Maven - Как создать проект веб-приложения Java
В этом руководстве мы покажем вам, как использовать Maven для управления веб-проектом Java. В конце мы создадим веб-приложение Spring MVC, отображающее текущую дату на странице JSP.
Используемые технологии:
-
Maven 3.5.3
-
JDK 8
-
Весна 5.1.0. ВЫПУСК
-
Юнит 5
-
Logback 1.2.3
-
Jetty 9.4.x или Tomcat 8.5
1. Создайте веб-проект из шаблона Maven
Создайте веб-проект из шаблона Mavenmaven-archetype-webapp
mvn archetype:generate -DgroupId={project-packaging} -DartifactId={project-name} -DarchetypeArtifactId={maven-template} -DinteractiveMode=false
Например,
D:\>mvn archetype:generate -DgroupId=com.example.web -DartifactId=java-web-project -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false [INFO] Scanning for projects... [INFO] [INFO] ------------------< org.apache.maven:standalone-pom >------------------- [INFO] Building Maven Stub Project (No POM) 1 [INFO] --------------------------------[ pom ]--------------------------------- [INFO] [INFO] >>> maven-archetype-plugin:3.0.1:generate (default-cli) > generate-sources @ standalone-pom >>> [INFO] [INFO] <<< maven-archetype-plugin:3.0.1:generate (default-cli) < generate-sources @ standalone-pom <<< [INFO] [INFO] [INFO] --- maven-archetype-plugin:3.0.1:generate (default-cli) @ standalone-pom --- [INFO] Generating project in Batch mode [INFO] ---------------------------------------------------------------------------- [INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-webapp:1.0 [INFO] ---------------------------------------------------------------------------- [INFO] Parameter: basedir, Value: D:\ [INFO] Parameter: package, Value: com.example.web [INFO] Parameter: groupId, Value: com.example.web [INFO] Parameter: artifactId, Value: java-web-project [INFO] Parameter: packageName, Value: com.example.web [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] project created from Old (1.x) Archetype in dir: D:\java-web-project [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 6.509 s [INFO] Finished at: 2018-10-04T15:25:16+08:00 [INFO] ------------------------------------------------------------------------
Note
На самом деле, это необязательно для создания веб-проекта из веб-шаблона Maven. Вы всегда можете создать эти папки вручную с помощью классической командыmkdir
.
2. Шаблон Maven
2.1 The following project directory structure will be created.
P.S Above figure is captured from IntelliJ IDEA, just ignore those IDE folders like .idea
and `java-web-project.iml`
2.2 Review the generated pom.xml
.
pom.xml
4.0.0 com.example.web java-web-project war 1.0-SNAPSHOT java-web-project Maven Webapp http://maven.apache.org junit junit 3.8.1 test java-web-project
P.S The generated files are not much value, we will update all of them later. Сначала удалитеweb.xml
, нам это не нужно.
3. Обновить POM
3.1 Update the pom.xml
file, add dependencies for Spring MVC for web framework, JUnit for unit test, Jetty server to test the web project, and also some Maven configuration.
pom.xml
4.0.0 com.example.web java-web-project war 1.0-SNAPSHOT java-web-project Maven Webapp http://maven.apache.org UTF-8 1.8 1.8 5.1.0.RELEASE org.springframework spring-webmvc ${spring.version} org.springframework spring-test ${spring.version} ch.qos.logback logback-classic 1.2.3 org.junit.jupiter junit-jupiter-engine 5.3.1 test org.hamcrest hamcrest-library 1.3 test javax.servlet javax.servlet-api 3.1.0 provided javax.servlet jstl 1.2 provided java-web-project org.eclipse.jetty jetty-maven-plugin 9.4.12.v20180830 org.apache.maven.plugins maven-surefire-plugin 2.22.0 org.apache.maven.plugins maven-war-plugin 3.2.2
3.2 Display the project dependencies.
D:\> mvn dependency:tree ... [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ java-web-project --- [INFO] com.example.web:java-web-project:war:1.0-SNAPSHOT [INFO] +- org.springframework:spring-webmvc:jar:5.1.0.RELEASE:compile [INFO] | +- org.springframework:spring-aop:jar:5.1.0.RELEASE:compile [INFO] | +- org.springframework:spring-beans:jar:5.1.0.RELEASE:compile [INFO] | +- org.springframework:spring-context:jar:5.1.0.RELEASE:compile [INFO] | +- org.springframework:spring-core:jar:5.1.0.RELEASE:compile [INFO] | | \- org.springframework:spring-jcl:jar:5.1.0.RELEASE:compile [INFO] | +- org.springframework:spring-expression:jar:5.1.0.RELEASE:compile [INFO] | \- org.springframework:spring-web:jar:5.1.0.RELEASE:compile [INFO] +- org.springframework:spring-test:jar:5.1.0.RELEASE:compile [INFO] +- ch.qos.logback:logback-classic:jar:1.2.3:compile [INFO] | +- ch.qos.logback:logback-core:jar:1.2.3:compile [INFO] | \- org.slf4j:slf4j-api:jar:1.7.25:compile [INFO] +- org.junit.jupiter:junit-jupiter-engine:jar:5.3.1:test [INFO] | +- org.apiguardian:apiguardian-api:jar:1.0.0:test [INFO] | +- org.junit.platform:junit-platform-engine:jar:1.3.1:test [INFO] | | +- org.junit.platform:junit-platform-commons:jar:1.3.1:test [INFO] | | \- org.opentest4j:opentest4j:jar:1.1.1:test [INFO] | \- org.junit.jupiter:junit-jupiter-api:jar:5.3.1:test [INFO] +- org.hamcrest:hamcrest-library:jar:1.3:test [INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:test [INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided [INFO] \- javax.servlet:jstl:jar:1.2:provided [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.931 s [INFO] Finished at: 2018-10-08T15:55:08+08:00 [INFO] ------------------------------------------------------------------------
4. Spring MVC + JSP + LogBack
4.1 Create a few files to bootstrap Spring MVC web project.
SpringConfig.java
package com.example.web.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @EnableWebMvc @Configuration @ComponentScan({"com.example.web"}) public class SpringConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**") .addResourceLocations("/resources/"); } @Bean public InternalResourceViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setViewClass(JstlView.class); viewResolver.setPrefix("/WEB-INF/views/"); viewResolver.setSuffix(".jsp"); return viewResolver; } }
WebInitializer.java
package com.example.web; import com.example.web.config.SpringConfig; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class>[] getRootConfigClasses() { return null; } @Override protected Class>[] getServletConfigClasses() { return new Class[]{SpringConfig.class}; } @Override protected String[] getServletMappings() { return new String[]{"/"}; } }
WelcomeController.java
package com.example.web.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import java.util.Date; @Controller public class WelcomeController { private final Logger logger = LoggerFactory.getLogger(WelcomeController.class); @GetMapping("/") public String index(Model model) { logger.debug("Welcome to example.com..."); model.addAttribute("msg", getMessage()); model.addAttribute("today", new Date()); return "index"; } private String getMessage() { return "Hello World"; } }
4.2 Move the index.jsp
file into the WEB-INF
folder, and update it
index.jsp
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>${msg}
Today is
4.3 Logs to console.
logbacl.xml
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
5. Модульный тест
Простой пример Spring MVC 5 + JUnit 5.
TestWelcome.java
package com.example.web; import com.example.web.config.SpringConfig; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @SpringJUnitWebConfig(SpringConfig.class) public class TestWelcome { private MockMvc mockMvc; @Autowired private WebApplicationContext webAppContext; @BeforeEach public void setup() { mockMvc = MockMvcBuilders.webAppContextSetup(webAppContext).build(); } @Test public void testWelcome() throws Exception { this.mockMvc.perform( get("/")) .andDo(print()) .andExpect(status().isOk()) .andExpect(view().name("index")) .andExpect(forwardedUrl("/WEB-INF/views/index.jsp")) .andExpect(model().attribute("msg", "Hello World")); } }
6. Структура каталогов
Просмотрите окончательные файлы и структуру каталогов.
Прочтите этоMaven Standard Directory Layout.
7. Demo
7.1 Test the web project with Jetty web server - mvn jetty:run
D:\> mvn jetty:run [INFO] webAppSourceDirectory not set. Trying src\main\webapp [INFO] Reload Mechanic: automatic [INFO] nonBlocking:false [INFO] Classes = D:\java-web-project\target\classes [INFO] Configuring Jetty for project: java-web-project Maven Webapp [INFO] Logging initialized @4821ms to org.eclipse.jetty.util.log.Slf4jLog [INFO] Context path = / [INFO] Tmp directory = D:\java-web-project\target\tmp [INFO] Web defaults = org/eclipse/jetty/webapp/webdefault.xml [INFO] Web overrides = none [INFO] web.xml file = null [INFO] Webapp directory = D:\java-web-project\src\main\webapp [INFO] jetty-9.4.12.v20180830; built: 2018-08-30T13:59:14.071Z; git: 27208684755d94a92186989f695db2d7b21ebc51; jvm 10.0.1+10 ... [INFO] 1 Spring WebApplicationInitializers detected on classpath 2018-10-08 15:11:50 [main] DEBUG com.example.web.WebInitializer - No ContextLoaderListener registered, as createRootApplicationContext() did not return an application context [INFO] DefaultSessionIdManager workerName=node0 [INFO] No SessionScavenger set, using defaults [INFO] node0 Scavenging every 660000ms [INFO] Initializing Spring DispatcherServlet 'dispatcher' [INFO] Started o.e.j.m.p.JettyWebAppContext@68a78f3c{/,file:///D:/java-web-project/src/main/webapp/,AVAILABLE}{file:///D:/java-web-project/src/main/webapp/} [INFO] Started ServerConnector@3355168{HTTP/1.1,[http/1.1]}{0.0.0.0:8080} [INFO] Started @6271ms [INFO] Started Jetty Server 2018-10-08 15:12:01 [qtp1373051324-19] DEBUG c.m.web.controller.WelcomeController - Welcome to example.com...
7.2 Access it via http://localhost:8080/
P.S CTRL + C to stop the Jetty web server.
8. развертывание
8.1 mvn package
to generate a WAR file for deployment.
D:\> mvn package ... [INFO] Packaging webapp [INFO] Assembling webapp [java-web-project] in [D:\java-web-project\target\java-web-project] [INFO] Processing war project [INFO] Copying webapp resources [D:\java-web-project\src\main\webapp] [INFO] Webapp assembled in [89 msecs] [INFO] Building war: D:\java-web-project\target\java-web-project.war [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3.844 s [INFO] Finished at: 2018-10-08T15:31:12+08:00 [INFO] ------------------------------------------------------------------------
Каталог по умолчанию для сгенерированной WAR -target/finalName
. Готово.
Скачать исходный код
$ git clone https://github.com/example/maven-examples.git
$ cd java-web-project
$ mvn jetty:run
Рекомендации
-
http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html [Maven
-
Введение в стандартную структуру каталогов]
-