使用Gradle第一次構建Web應用

Gradle Web 插件

Gradle 提供了打包 war 包的插件,能夠將 Web 應用部署到本地 Servlet 容器中。css

使用 War 和 Jetty 插件

Gradle 對構建和運行 Web 應用提供了對應擴展的支持。
下面咱們介紹 War 和 Jetty 插件。
War 插件擴展自 Java 插件,爲 Web 應用部署和組裝 War 包添加了約定和支持。
Jetty 是一個流行的輕量級開源 Web 容器,Gradle 提供了 Jetty 插件,方便 Jetty 的使用。Jetty 擴展自 War 插件,爲部署一個 Web 應用和運行 Web 應用提供了對應的任務。java

War插件

War 插件擴展自 Java 插件,因此咱們在引入 War 插件後無需再顯式引入 Java插件(引入也不會影響,應用插件是一個冪等【任意屢次執行所產生的影響均與一次執行的影響相同】操做,某一個指定的插件只會運行一次)
使用插件只需:git

apply plugin:'war'

對於項目自己,除了 Java 插件的約定外,還會應用 Web 應用文件,並打包項目爲 WAR 文件而不是 JAR 文件。Web 應用默認約定的源代碼目錄是src/main/webapp
添加相關 Web 文件以後咱們的文件目錄以下所示:github

└─src
    └─main
        ├─java
        │  └─com
        │      └─manning
        │          └─gia
        │              └─todo
        │                  ├─model
        │                  │      ToDoItem.java
        │                  │
        │                  ├─repository
        │                  │      InMemoryToDoRepository.java
        │                  │      ToDoRepository.java
        │                  │
        │                  └─web
        │                          ToDoServlet.java
        │
        └─webapp
            ├─css
            │      base.css
            │      bg.png
            │
            ├─jsp
            │      index.jsp
            │      todo-list.jsp
            │
            └─WEB-INF
                    web.xml

當咱們構建的時候會發現報錯:web

www.coderknock.com$ gradle build
:compileJava
D:\Windows\Desktop\LearnGradle\用Gradle作Web開發\src\main\java\com\manning\gia\todo\web\ToDoServlet.java:7: 錯誤: 程序包javax.servlet不存在
import javax.servlet.RequestDispatcher;
                    ^
D:\Windows\Desktop\LearnGradle\用Gradle作Web開發\src\main\java\com\manning\gia\todo\web\ToDoServlet.java:8: 錯誤: 程序包javax.servlet不存在
import javax.servlet.ServletException;
                    ^
D:\Windows\Desktop\LearnGradle\用Gradle作Web開發\src\main\java\com\manning\gia\todo\web\ToDoServlet.java:9: 錯誤: 程序包javax.servlet.http不存在
import javax.servlet.http.HttpServlet;
                         ^
D:\Windows\Desktop\LearnGradle\用Gradle作Web開發\src\main\java\com\manning\gia\todo\web\ToDoServlet.java:10: 錯誤: 程序 包javax.servlet.http不存在
import javax.servlet.http.HttpServletRequest;
                         ^
D:\Windows\Desktop\LearnGradle\用Gradle作Web開發\src\main\java\com\manning\gia\todo\web\ToDoServlet.java:11: 錯誤: 程序 包javax.servlet.http不存在
import javax.servlet.http.HttpServletResponse;
                         ^
D:\Windows\Desktop\LearnGradle\用Gradle作Web開發\src\main\java\com\manning\gia\todo\web\ToDoServlet.java:16: 錯誤: 找不 到符號
public class ToDoServlet extends HttpServlet {
                                 ^
  符號: 類 HttpServlet
D:\Windows\Desktop\LearnGradle\用Gradle作Web開發\src\main\java\com\manning\gia\todo\web\ToDoServlet.java:22: 錯誤: 找不 到符號
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                           ^
  符號:   類 HttpServletRequest
  位置: 類 ToDoServlet
D:\Windows\Desktop\LearnGradle\用Gradle作Web開發\src\main\java\com\manning\gia\todo\web\ToDoServlet.java:22: 錯誤: 找不 到符號
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                                                       ^
  符號:   類 HttpServletResponse
  位置: 類 ToDoServlet
D:\Windows\Desktop\LearnGradle\用Gradle作Web開發\src\main\java\com\manning\gia\todo\web\ToDoServlet.java:22: 錯誤: 找不 到符號
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                                                                                            ^
  符號:   類 ServletException
  位置: 類 ToDoServlet
D:\Windows\Desktop\LearnGradle\用Gradle作Web開發\src\main\java\com\manning\gia\todo\web\ToDoServlet.java:29: 錯誤: 找不 到符號
    private String processRequest(String servletPath, HttpServletRequest request) {
                                                      ^
  符號:   類 HttpServletRequest
  位置: 類 ToDoServlet
D:\Windows\Desktop\LearnGradle\用Gradle作Web開發\src\main\java\com\manning\gia\todo\web\ToDoServlet.java:21: 錯誤: 方法 不會覆蓋或迪殖嘈偷姆椒?
      @Override
    ^
D:\Windows\Desktop\LearnGradle\用Gradle作Web開發\src\main\java\com\manning\gia\todo\web\ToDoServlet.java:25: 錯誤: 找不 到符號
        RequestDispatcher dispatcher = request.getRequestDispatcher(view);
        ^
  符號:   類 RequestDispatcher
  位置: 類 ToDoServlet
12 個錯誤
:compileJava FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':compileJava'.
> Compilation failed; see the compiler error output for details.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 1.21 secs

實現 Web 應用所須要的類並未包括在標準 JDK 中,例如 javax.servlet.HttpServlet。因此在運行構建前咱們須要添加外部依賴。咱們爲 War 插件引入兩個依賴,Servlet 依賴使用到的是 providedCompile,它表示該依賴在編譯時須要,但實際運行時由運行時的環境提供。在本項目中就是 Jetty 提供,這樣改依賴的相關文件就不會打包到 WAR 文件中了(避免 WAR 包過大以及可能出現的 JAR 包重複從而致使找不到相關類)。向 JSTL 庫等在編譯時不須要,運行時須要的庫,咱們須要標記爲 runtime ,這樣他們會被包含到 WAR 文件中以供運行時調用。咱們在 build.gradle 中添加下面依賴配置:api

dependencies{
     providedCompile 'javax.servlet:javax.servlet-api:3.1.0' //書中是該值,'javax.servlet:servlet-api:2.5' 可是該庫比較舊,咱們使用最新的 Servlet 依賴  
     runtime 'javax.servlet:jstl:1.1.2'
 }

這時咱們運行構建命令,發現仍是有報錯:bash

www.coderknock.com$ gradle build
> Configuring > 0/1 projects > root project > Compiling D:\Windows\Desktop\LearnGradle\用Gradle作Web開發\build.gradle in:compileJava FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Could not resolve all dependencies for configuration ':compileClasspath'.
> Cannot resolve external dependency javax.servlet:servlet-api:3.0.1 because no repositories are defined.
  Required by:
      project :

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 1.332 secs

這是由於咱們沒有什麼資源庫,在 build.gradle 中繼續添加:app

repositories {
    mavenCentral()
}

繼續編譯,編譯成功webapp

www.coderknock.com$ gradle build
:compileJava
:processResources NO-SOURCE
:classes
:war//由 War 插件提供的任務來打 WAR 包
:assemble
:compileTestJava NO-SOURCE
:processTestResources NO-SOURCE
:testClasses UP-TO-DATE
:test NO-SOURCE
:check UP-TO-DATE
:build

BUILD SUCCESSFUL

Total time: 7.904 secs

War 插件確保了打包的 WAR 文件遵循由 Java EE 規範定義的標準結構。其中主要作的任務以下:jvm

  1. 將 Web 應用源代碼目錄 src/main/webapp 的內容拷貝到 WAR 文件的根目錄

  2. 將編譯後的 class 文件放入到 WEB-INF/classes 下

  3. 經過依賴定義的運行時類庫(如上面的)javax.servlet:jstl:1.1.2 拷貝到 WEB-INF/lib 下

打包後的目錄以下:

│
├─.gradle
│  ├─3.4
│  │  ├─file-changes
│  │  │      last-build.bin
│  │  │
│  │  ├─fileContent
│  │  │      annotation-processors.bin
│  │  │      fileContent.lock
│  │  │
│  │  └─taskHistory
│  │          fileHashes.bin
│  │          fileSnapshots.bin
│  │          jvmClassSignatures.bin
│  │          taskHistory.bin
│  │          taskHistory.lock
│  │
│  └─buildOutputCleanup
│          built.bin
│          cache.properties
│          cache.properties.lock
│
├─build
│  ├─classes
│  │  └─main
│  │      └─com
│  │          └─manning
│  │              └─gia
│  │                  └─todo
│  │                      ├─model
│  │                      │      ToDoItem.class
│  │                      │
│  │                      ├─repository
│  │                      │      InMemoryToDoRepository.class
│  │                      │      ToDoRepository.class
│  │                      │
│  │                      └─web
│  │                              ToDoServlet$ToDoListStats.class
│  │                              ToDoServlet.class
│  │
│  ├─libs
│  │      用Gradle作Web開發.war
│  │
│  └─tmp
│      ├─compileJava
│      └─war
│              MANIFEST.MF
│
│
└─src
    └─main
        ├─java
        │  └─com
        │      └─manning
        │          └─gia
        │              └─todo
        │                  ├─model
        │                  │      ToDoItem.java
        │                  │
        │                  ├─repository
        │                  │      InMemoryToDoRepository.java
        │                  │      ToDoRepository.java
        │                  │
        │                  └─web
        │                          ToDoServlet.java
        │
        └─webapp
            ├─css
            │      base.css
            │      bg.png
            │
            ├─jsp
            │      index.jsp
            │      todo-list.jsp
            │
            └─WEB-INF
                    web.xml

其中打包好的 WAR 文件的目錄結構以下:

├─css
│      base.css
│      bg.png
│
├─jsp
│      index.jsp
│      todo-list.jsp
│
├─META-INF
│      MANIFEST.MF
│
└─WEB-INF
    │  web.xml
    │
    ├─classes
    │  └─com
    │      └─manning
    │          └─gia
    │              └─todo
    │                  ├─model
    │                  │      ToDoItem.class
    │                  │
    │                  ├─repository
    │                  │      InMemoryToDoRepository.class
    │                  │      ToDoRepository.class
    │                  │
    │                  └─web
    │                          ToDoServlet$ToDoListStats.class
    │                          ToDoServlet.class
    │
    └─lib
            jstl-1.2.jar

能夠看到其結構正如咱們分析的同樣。
相關代碼

相關文章
相關標籤/搜索