使用Maven創建Web應用程序項目

在本教程中,我們將演示如何使用 Maven 創建一個 Java Web 項目(Spring MVC)。

用到的技術/工具:

  1. Maven 3.3.3
  2. Eclipse 4.3
  3. JDK 8
  4. Spring 4.1.1.RELEASED
  5. Tomcat 7
  6. Logback 1.0.13

1. 從Maven模板創建Web項目

您可以通過使用Maven的maven-archetype-webapp模板來創建一個快速啓動Java Web應用程序的項目。在終端(* UNIX或Mac)或命令提示符(Windows)中,導航至您想要創建項目的文件夾。

鍵入以下命令:

$ mvn archetype:generate -DgroupId=com.yiibai -DartifactId=CounterWebApp -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false

具體示例 :

C:\worksp>mvn archetype:generate -DgroupId=com.yiibai -DartifactId=CounterWebAp
p -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] >>> maven-archetype-plugin:2.4:generate (default-cli) > generate-sources
@ standalone-pom >>>
[INFO]
[INFO] <<< maven-archetype-plugin:2.4:generate (default-cli) < generate-sources
@ standalone-pom <<<
[INFO]
[INFO] --- maven-archetype-plugin:2.4:generate (default-cli) @ standalone-pom --
-
[INFO] Generating project in Batch mode
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/archetypes/ma
ven-archetype-webapp/1.0/maven-archetype-webapp-1.0.jar
Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/archetypes/mav
en-archetype-webapp/1.0/maven-archetype-webapp-1.0.jar (4 KB at 0.1 KB/sec)
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/archetypes/ma
ven-archetype-webapp/1.0/maven-archetype-webapp-1.0.pom
Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/archetypes/mav
en-archetype-webapp/1.0/maven-archetype-webapp-1.0.pom (533 B at 0.1 KB/sec)
[INFO] -------------------------------------------------------------------------


[INFO] Using following parameters for creating project from Old (1.x) Archetype:
maven-archetype-webapp:1.0
[INFO] -------------------------------------------------------------------------


[INFO] Parameter: basedir, Value: C:\worksp
[INFO] Parameter: package, Value: com.yiibai
[INFO] Parameter: groupId, Value: com.yiibai
[INFO] Parameter: artifactId, Value: CounterWebApp
[INFO] Parameter: packageName, Value: com.yiibai
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: C:\worksp\CounterWebApp
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 10:30 min
[INFO] Finished at: 2015-10-28T20:31:03+08:00
[INFO] Final Memory: 16M/174M
[INFO] ------------------------------------------------------------------------

新的Web項目命名爲 「CounterWebApp」,以及一些標準的 web 目錄結構也會自動創建。

2. 項目目錄佈局

查看生成的項目結構佈局:

.|____CounterWebApp
||____pom.xml
||____src
|||____main
||||____resources
||||____webapp
|||||____index.jsp
|||||____WEB-INF
||||||____web.xml

Maven 產生了一些文件夾,一個部署描述符 web.xml,pom.xml 和 index.jsp。

注意,
請查看 官方Maven標準目錄佈局指南來了解更多。

pom.xml


4.0.0
com.yiibai
CounterWebApp
war
1.0-SNAPSHOT
CounterWebApp Maven Webapp
http://maven.apache.org


junit
junit
3.8.1
test



CounterWebApp

web.xml – Servlet 2.3 已經比較舊, 建議升級到2.5

<web-app><display-name>Archetype Created Web Application</display-name></web-app>

index.jsp – 一個簡單的 hello world html 頁面文件

Hello World!

3. Eclipse IDE 支持

要導入這個項目到Eclipse中,需要生成一些 Eclipse 項目的配置文件:

3.1、在終端,進入到 「CounterWebApp」 文件夾中,鍵入以下命令:

C:\worksp>cd CounterWebApp
C:\worksp\CounterWebApp>mvn eclipse:eclipse -Dwtpversion=2.0
[INFO] Scanning for projects...
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven -war-plugin/2.2/maven-war-plugin-2.2.pom
Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven- war-plugin/2.2/maven-war-plugin-2.2.pom (7 KB at 2.5 KB/sec)
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven -war-plugin/2.2/maven-war-plugin-2.2.jar
Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven- war-plugin/2.2/maven-war-plugin-2.2.jar (77 KB at 26.2 KB/sec)
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building CounterWebApp Maven Webapp 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] >>> maven-eclipse-plugin:2.10:eclipse (default-cli) > generate-resources
@ CounterWebApp >>>
[INFO]
[INFO] <<< maven-eclipse-plugin:2.10:eclipse (default-cli) < generate-resources
@ CounterWebApp <<<
[INFO]
[INFO] --- maven-eclipse-plugin:2.10:eclipse (default-cli) @ CounterWebApp ---
[INFO] Adding support for WTP version 2.0.
[INFO] Using Eclipse Workspace: null
[INFO] Adding default classpath container: org.eclipse.jdt.launching.JRE_CONTAINER
[INFO] Not writing settings - defaults suffice
[INFO] Wrote Eclipse project for "CounterWebApp" to C:\worksp\CounterWebApp.
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7.982 s
[INFO] Finished at: 2015-10-28T20:24:57+08:00
[INFO] Final Memory: 15M/146M
[INFO] ------------------------------------------------------------------------

注意,此選項 -Dwtpversion=2.0 告訴 Maven 將項目轉換到 Eclipse 的 Web 項目(WAR),而不是默認的Java項目(JAR)。爲方便起見,以後我們會告訴你如何配置 pom.xml 中的這個 WTP 選項。

3.2 導入到 Eclipse IDE – File -> Import… -> General -> Existing Projects into workspace.

圖像說明: 在 Eclipse 中,如果看到項目頂部有地球圖標,意味着這是一個 Web 項目。

4. 更新POM

在Maven中,Web項目的設置都通過這個單一的pom.xml文件配置。

  1. 添加項目依賴 - Spring, logback 和 JUnit
  2. 添加插件來配置項目

閱讀註釋清楚明瞭。

pom.xml


4.0.0
com.yiibai
CounterWebApp
war
1.0-SNAPSHOT
CounterWebApp Maven Webapp
http://maven.apache.org
<jdk.version>1.7</jdk.version>
<spring.version>4.1.1.RELEASE</spring.version>
<jstl.version>1.2</jstl.version>
<junit.version>4.11</junit.version>
<logback.version>1.0.13</logback.version>
<jcl-over-slf4j.version>1.7.5</jcl-over-slf4j.version>

<dependencies>
    <!-- Unit Test -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit.version}</version>
    </dependency>

    <!-- Spring Core -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
        <exclusions>
            <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>${jcl-over-slf4j.version}</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>${logback.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!-- jstl -->
    <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>${jstl.version}</version>
    </dependency>
</dependencies>

<build>
    <finalName>CounterWebApp</finalName>

    <plugins>
        <!-- Eclipse project -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-eclipse-plugin</artifactId>
        <version>2.9</version>
        <configuration>
                <!-- Always download and attach dependencies source code -->
            <downloadSources>true</downloadSources>
            <downloadJavadocs>false</downloadJavadocs>
            <!-- Avoid type mvn eclipse:eclipse -Dwtpversion=2.0 -->
            <wtpversion>2.0</wtpversion>
        </configuration>
      </plugin>

      <!-- Set JDK Compiler Level -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
            <source>${jdk.version}</source>
            <target>${jdk.version}</target>
        </configuration>
      </plugin>

      <!-- For Maven Tomcat Plugin -->
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
        <configuration>
            <path>/CounterWebApp</path>
        </configuration>
      </plugin>
    </plugins>
</build>

注意,爲方便起見,聲明 maven-eclipse-plugin,並配置wtpversion 來避免輸入參數 -Dwtpversion=2.0。現在,每次使用 mvn eclipse:eclipse,Maven將這個項目導入轉換爲 Eclipse Web 項目。

#之前
mvn eclipse:eclipse --> Eclipse Java project (JAR)
mvn eclipse:eclipse -Dwtpversion=2.0 --> Eclipse Java web project (WAR)

#之後
mvn eclipse:eclipse --> Eclipse Java web project (WAR)

5. 更新源代碼

在這一步中,在上一步配置完pom.xml後,重新執行 mvn eclipse:eclipse 這個命令,我們將創建Spring MVC的一些文件和logback日誌框架的文件夾,最終的項目結構如下所示:

.
|____pom.xml
|____src
| |____main
| | |____java
| | | |____com
| | | | |____yiibai
| | | | | |____controller
| | | | | | |____BaseController.java
| | |____resources
| | | |____logback.xml
| | |____webapp
| | | |____WEB-INF
| | | | |____mvc-dispatcher-servlet.xml
| | | | |____pages
| | | | | |____index.jsp
| | | | |____web.xml

注意,如果它不存在,需要手動創建文件夾。

5.1 創建 Spring MVC 的控制器類。

/src/main/java/com/yiibai/controller/BaseController.java

package com.yiibai.controller;

import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class BaseController {

private static int counter = 0;
private static final String VIEW\_INDEX = "index";
private final static org.slf4j.Logger logger = LoggerFactory.getLogger(BaseController.class);

@RequestMapping(value = "/", method = RequestMethod.GET)
public String welcome(ModelMap model) {

    model.addAttribute("message", "Welcome");
    model.addAttribute("counter", ++counter);
    logger.debug("\[welcome\] counter : {}", counter);

    // Spring uses InternalResourceViewResolver and return back index.jsp
    return VIEW\_INDEX;

}

@RequestMapping(value = "/{name}", method = RequestMethod.GET)
public String welcomeName(@PathVariable String name, ModelMap model) {

    model.addAttribute("message", "Welcome " + name);
    model.addAttribute("counter", ++counter);
    logger.debug("\[welcomeName\] counter : {}", counter);
    return VIEW\_INDEX;

}

}

5.2 創建Spring配置文件。

/src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml

<context:component-scan base-package="com.yiibai.controller" />
<bean
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix">
        <value>/WEB-INF/pages/</value>
    </property>
    <property name="suffix">
        <value>.jsp</value>
    </property>
</bean>

5.3 更新讓現有的 web.xml 支持 Servlet 2.5(默認的Servlet2.3 太舊了), 並且還通過 Spring 監聽器 ContextLoaderListener 集成了Spring框架。

/src/main/webapp/WEB-INF/web.xml

<display-name>Counter Web Application</display-name>

<servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>

                        org.springframework.web.servlet.DispatcherServlet
                
1

<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>

<listener>
    <listener-class>

                   org.springframework.web.context.ContextLoaderListener
                

5.4 移動文件 index.jsp 到 WEB-INF/pages 目錄下, 爲了保護直接訪問。並更新內容:

/src/main/webapp/WEB-INF/pages/index.jsp

5.5 在資源文件夾(resources)中創建 logback.xml 文件

/src/main/resources/logback.xml

6. Eclipse + Tomcat

在第5步中創建所有文件以後,這裏有一些方法可以用來部署和測試Web項目,我們這裏推薦使用6.2中的方法。

6.1 要編譯,測試和項目打包成一個WAR文件,輸入:

mvn package

一個新的 WAR 文件將在 project/target/CounterWebApp.war產生,只需複製並部署到Tomcat 發佈的目錄。

6.2 如果想通過 Eclipse 服務器這個項目插件(Tomcat 或其它容器)調試,這裏再輸入:

mvn eclipse:eclipse

如果一切順利,該項目的依賴將被裝配附加到 Web部署項目。圖片: 右鍵點擊 project -> Properties -> Deployment Assembly

6.3 Maven 的 Tomcat 插件聲明(加入到 pom.xml):

pom.xml

鍵入以下命令(有時網絡不通暢需要執行2-3次):

mvn tomcat:run
tp://logback.qos.ch/codes.html#layoutInsteadOfEncoder for details
20:37:32,089 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Se
g level of logger [com.yiibai.controller] to DEBUG
20:37:32,089 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Se
g additivity of logger [com.yiibai.controller] to false
20:37:32,090 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction -
ching appender named [STDOUT] to Logger[com.yiibai.controller]
20:37:32,090 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction
tting level of ROOT logger to ERROR
20:37:32,090 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction -
ching appender named [STDOUT] to Logger[ROOT]
20:37:32,090 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationActi
 End of configuration.
20:37:32,091 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@3bead5  Registering current configuration as safe fallback point

十月 28, 2015 20:37:32 下午 org.apache.catalina.core.ApplicationContext log
信息: Initializing Spring root WebApplicationContext
十月 28, 2015 20:37:33 下午 org.apache.catalina.core.ApplicationContext log
信息: Initializing Spring FrameworkServlet 'mvc-dispatcher'
十月 28, 2015 20:37:33 下午 org.apache.coyote.http11.Http11Protocol init
信息: Initializing Coyote HTTP/1.1 on http-8080
十月 28, 2015 20:37:33 下午 org.apache.coyote.http11.Http11Protocol start
信息: Starting Coyote HTTP/1.1 on http-8080

這將啓動Tomcat,部署項目默認在端口8080。

出錯:Maven項目下update maven後Eclipse報錯:java.lang.ClassNotFoundException: ContextLoaderL

解決方案:

1.右鍵點擊項目--選擇Properties

選擇Deployment Assembly,在右邊點擊Add按鈕,在彈出的窗口中選擇Java Build Path Entries

2.點擊Next,選擇Maven Dependencies

3.點擊Finish,然後可以看到已經把Maven Dependencies添加到Web應用結構中了

操作完後,重新部署工程,不再報錯了。然後我們再到.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\目錄下,發現工程WEB-INF目錄下自動生成了lib目錄,並且所有的依賴jar包也都已經部署進來。問題因此解決。