gradle创建一个java web app
最近在udemy上学习gradle,本文主要介绍gradle 新建一个java web工程,本文用的gradle版本为
7.1.1
,如果本文对您有帮助,请不要吝啬您的点赞,谢谢~
新建java web工程
创建一个文件夹叫做firstWebApp
, 然后cd进入, 运行gradle init
创建完成后继续在app/src/main/目录下面新建文件夹:webapp, 并添加index.html 以及 response.jsp 空文件,工程目录结构如下:
@192 firstWebApp02 % tree
.
├── app
│ ├── build.gradle
│ └── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── xj
│ │ │ └── gradle
│ │ │ └── App.java
│ │ ├── resources
│ │ └── webapp
│ │ ├── index.html
│ │ └── response.jsp
│ └── test
│ ├── java
│ │ └── com
│ │ └── xj
│ │ └── gradle
│ │ └── AppTest.java
│ └── resources
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
编辑build.gradle 代码
- 删除 plugins里面的
id 'application'
, 加上id 'war'
因为它不再是一个java application了 - 删除
application
里面的的内容,不需要指定main class了
application {
// Define the main class for the application.
mainClass = 'com.xj.gradle.App'
}
- 添加依赖:
implementation 'javax.servlet:javax.servlet-api:3.1.0'
表示会用到servlet内容
编辑 业务代码
index.html
,这里有一个a标签,以及一个form表单
<!DOCTYPE html>
<html>
<head>
<title>Home</title>
</head>
<body>
<a href="coupon">Get Coupon</a>
<form method="post" action="coupon">
Coupon Code:<input type="text" name="coupon">
<input type="submit" value="Get Discount">
</form>
</body>
</html>
App.java
,里面继承了HttpServlet,里面两个方法,一个响应get请求,一个响应post请求,post请求后分发到response.jsp
页面
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package com.xj.gradle;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/coupon")
public class App extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.getWriter().print("SUPERSALE");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String coupon = request.getParameter("coupon");
request.setAttribute("discount","Discount for coupon "+coupon+" is 50%" );
request.getRequestDispatcher("response.jsp").forward(request,response);
}
}
response.jsp
页面,展示discount的内容
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<!DOCTYPE html>
<html>
<head>
<title>Discount Page</title>
</head>
<body>
<h2>${discount}</h2>
</body>
</html>
尝试运行gradle命令
./gradlew tasks --all
可以发现有任务:
app:war - Generates a war archive with all the compiled classes, the web-app content and the libraries.
, 可以用来打包
也有任务:
app:compileJava - Compiles main Java source.
因为plugins里面 war是在java的基础上构建的./gradlew war
后再次运行tree
,可以发现:在app下多了build文件夹,里面有编译好的class文件,以及libs包下面有发布的app.war文件
├── app
│ ├── build
│ │ ├── classes
│ │ │ └── java
│ │ │ └── main
│ │ │ └── com
│ │ │ └── xj
│ │ │ └── gradle
│ │ │ └── App.class
│ │ ├── generated
│ │ │ └── sources
│ │ │ ├── annotationProcessor
│ │ │ │ └── java
│ │ │ │ └── main
│ │ │ └── headers
│ │ │ └── java
│ │ │ └── main
│ │ ├── libs
│ │ │ └── app.war
│ │ └── tmp
│ │ ├── compileJava
│ │ │ └── previous-compilation-data.bin
│ │ └── war
│ │ └── MANIFEST.MF
│ ├── build.gradle
│ └── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── xj
│ │ │ └── gradle
│ │ │ └── App.java
│ │ └── resources
│ ├── test
│ │ ├── java
│ │ │ └── com
│ │ │ └── xj
│ │ │ └── gradle
│ │ │ └── AppTest.java
│ │ └── resources
│ └── webapp
│ ├── index.html
│ └── response.jsp
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
本地运行项目
- 编辑build.gradle 文件夹,添加插件
id 'org.gretty' version '3.0.5'
(你需要去gretty官网查找最新的版本,否则可能会出错)
plugins {
id 'war'
id 'org.gretty' version '3.0.5'
}
- 然后运行
./gradle tasks --all
,发现多了很多任务:
Gretty tasks
------------
app:appAfterIntegrationTest - Stops server after integration test.
app:appBeforeIntegrationTest - Starts server before integration test.
app:appRestart - Sends 'restart' command to a running server.
app:appRun - Starts web-app inplace, in interactive mode.
app:appRunDebug - Starts web-app inplace, in debug and interactive mode.
app:appRunWar - Starts web-app on WAR-file, in interactive mode.
app:appRunWarDebug - Starts web-app on WAR-file, in debug and interactive mode.
app:appStart - Starts web-app inplace (stopped by 'appStop').
app:appStartDebug - Starts web-app inplace, in debug mode (stopped by 'appStop').
app:appStartWar - Starts web-app on WAR-file (stopped by 'appStop').
app:appStartWarDebug - Starts web-app on WAR-file, in debug mode (stopped by 'appStop').
app:appStop - Sends 'stop' command to a running server.
app:archiveAllProducts - Archives all configured gretty products.
app:archiveProduct - Archives gretty product.
app:buildAllProducts - Builds all configured gretty products.
app:buildProduct - Builds gretty product.
app:createInplaceWebAppFolder - Creates directory ${buildDir}/inplaceWebapp
app:farmAfterIntegrationTest - Stops default farm after integration test.
app:farmBeforeIntegrationTest - Starts default farm before integration test.
app:farmIntegrationTest - Runs integration tests on default farm web-apps.
app:farmRestart - Sends 'restart' command to a running default farm.
app:farmRun - Starts default farm inplace, in interactive mode.
app:farmRunDebug - Starts default farm inplace, in debug and in interactive mode.
app:farmRunWar - Starts default farm on WAR-files, in interactive mode.
app:farmRunWarDebug - Starts default farm on WAR-files, in debug and in interactive mode.
app:farmStart - Starts default farm inplace (stopped by 'farmStop').
app:farmStartDebug - Starts default farm inplace, in debug mode (stopped by 'farmStop').
app:farmStartWar - Starts default farm on WAR-files (stopped by 'farmStop').
app:farmStartWarDebug - Starts default farm on WAR-files, in debug (stopped by 'farmStop').
app:farmStop - Sends 'stop' command to a running default farm.
app:jettyRestart - Sends 'restart' command to a running server.
app:jettyRun - Starts web-app inplace, in interactive mode.
app:jettyRunDebug - Starts web-app inplace, in debug and interactive mode.
app:jettyRunWar - Starts web-app on WAR-file, in interactive mode.
app:jettyRunWarDebug - Starts web-app on WAR-file, in debug and interactive mode.
app:jettyStart - Starts web-app inplace (stopped by 'jettyStop').
app:jettyStartDebug - Starts web-app inplace, in debug mode (stopped by 'jettyStop').
app:jettyStartWar - Starts web-app on WAR-file (stopped by 'jettyStop').
app:jettyStartWarDebug - Starts web-app on WAR-file, in debug mode (stopped by 'jettyStop').
app:jettyStop - Sends 'stop' command to a running server.
app:prepareArchiveWebApp - Prepares war web-app
app:prepareInplaceWebApp - Prepares inplace web-app
app:prepareInplaceWebAppClasses - Compiles classes of this web-app and all overlays (if any)
app:prepareInplaceWebAppFolder - Copies webAppDir of this web-app and all overlays (if any) to ${buildDir}/inplaceWebapp
app:showClassPath - Shows classpath information
app:tomcatRestart - Sends 'restart' command to a running server.
app:tomcatRun - Starts web-app inplace, in interactive mode.
app:tomcatRunDebug - Starts web-app inplace, in debug and interactive mode.
app:tomcatRunWar - Starts web-app on WAR-file, in interactive mode.
app:tomcatRunWarDebug - Starts web-app on WAR-file, in debug and interactive mode.
app:tomcatStart - Starts web-app inplace (stopped by 'tomcatStop').
app:tomcatStartDebug - Starts web-app inplace, in debug mode (stopped by 'tomcatStop').
app:tomcatStartWar - Starts web-app on WAR-file (stopped by 'tomcatStop').
app:tomcatStartWarDebug - Starts web-app on WAR-file, in debug mode (stopped by 'tomcatStop').
app:tomcatStop - Sends 'stop' command to a running server.
- 运行:
./gradlew app:appRun
可以看见项目启动成功
- 进入网址:
http://localhost:8088/app/
查看页面:
- 如果别的端口被占用,你也可以指定端口
gretty.httpPort = 8090
,然后再运行
gradle运行出错
- 当我服务build成功后,运行
gradle app:appRun
去启动服务,然后报错了。。
Exception in thread "main" org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
General error during semantic analysis: Unsupported class file major version 60
java.lang.IllegalArgumentException: Unsupported class file major version 60
at groovyjarjarasm.asm.ClassReader.<init>(ClassReader.java:196)
at groovyjarjarasm.asm.ClassReader.<init>(ClassReader.java:177)
at groovyjarjarasm.asm.ClassReader.<init>(ClassReader.java:163)
at groovyjarjarasm.asm.ClassReader.<init>(ClassReader.java:284)
at org.codehaus.groovy.ast.decompiled.AsmDecompiler.parseClass(AsmDecompiler.java:81)
at org.codehaus.groovy.control.ClassNodeResolver.findDecompiled(ClassNodeResolver.java:251)
at org.codehaus.groovy.control.ClassNodeResolver.tryAsLoaderClassOrScript(ClassNodeResolver.java:189)
at org.codehaus.groovy.control.ClassNodeResolver.findClassNode(ClassNodeResolver.java:169)
at org.codehaus.groovy.control.ClassNodeResolver.resolveName(ClassNodeResolver.java:125)
at org.codehaus.groovy.ast.decompiled.AsmReferenceResolver.resolveClassNullable(AsmReferenceResolver.java:57)
at org.codehaus.groovy.ast.decompiled.AsmReferenceResolver.resolveClass(AsmReferenceResolver.java:44)
at org.codehaus.groovy.ast.decompiled.ClassSignatureParser.configureClass(ClassSignatureParser.java:42)
at org.codehaus.groovy.ast.decompiled.DecompiledClassNode.lazyInitSupers(DecompiledClassNode.java:183)
at org.codehaus.groovy.ast.decompiled.DecompiledClassNode.getUnresolvedSuperClass(DecompiledClassNode.java:128)
at org.codehaus.groovy.ast.ClassNode.getUnresolvedSuperClass(ClassNode.java:1024)
at org.codehaus.groovy.ast.ClassNode.getSuperClass(ClassNode.java:1018)
at org.codehaus.groovy.ast.ClassNode.getMethods(ClassNode.java:913)
at org.apache.groovy.ast.tools.ClassNodeUtils.hasPossibleStaticMethod(ClassNodeUtils.java:235)
at org.codehaus.groovy.ast.ClassNode.hasPossibleStaticMethod(ClassNode.java:1347)
at org.codehaus.groovy.control.StaticImportVisitor.findStaticMethod(StaticImportVisitor.java:566)
at org.codehaus.groovy.control.StaticImportVisitor.findStaticMethodImportFromModule(StaticImportVisitor.java:508)
at org.codehaus.groovy.control.StaticImportVisitor.transformMethodCallExpression(StaticImportVisitor.java:254)
at org.codehaus.groovy.control.StaticImportVisitor.transform(StaticImportVisitor.java:113)
at org.codehaus.groovy.ast.ClassCodeExpressionTransformer.visitExpressionStatement(ClassCodeExpressionTransformer.java:142)
at org.codehaus.groovy.ast.stmt.ExpressionStatement.visit(ExpressionStatement.java:40)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClassCodeContainer(ClassCodeVisitorSupport.java:110)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitConstructorOrMethod(ClassCodeVisitorSupport.java:121)
at org.codehaus.groovy.ast.ClassCodeExpressionTransformer.visitConstructorOrMethod(ClassCodeExpressionTransformer.java:53)
at org.codehaus.groovy.control.StaticImportVisitor.visitConstructorOrMethod(StaticImportVisitor.java:89)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitMethod(ClassCodeVisitorSupport.java:132)
at org.codehaus.groovy.ast.ClassNode.visitContents(ClassNode.java:1103)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClass(ClassCodeVisitorSupport.java:54)
at org.codehaus.groovy.control.StaticImportVisitor.visitClass(StaticImportVisitor.java:83)
at org.codehaus.groovy.control.CompilationUnit$14.call(CompilationUnit.java:708)
at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1084)
at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:640)
at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:618)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:595)
at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:401)
at groovy.lang.GroovyClassLoader.access$300(GroovyClassLoader.java:89)
at groovy.lang.GroovyClassLoader$5.provide(GroovyClassLoader.java:341)
at groovy.lang.GroovyClassLoader$5.provide(GroovyClassLoader.java:338)
at org.codehaus.groovy.runtime.memoize.ConcurrentCommonCache.getAndPut(ConcurrentCommonCache.java:147)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:336)
at groovy.lang.GroovyShell.parseClass(GroovyShell.java:546)
at groovy.lang.GroovyShell.parse(GroovyShell.java:558)
在网上搜了下,说需要更新gradle的版本,每次重新配置,我想着我这基本都是通过命令行跑的,肯定跟这个没关系,然后试了下项目下自带的命令工具:./gradlew app:appRun
,竟然成功了,惊喜,有知道为什么的大佬请给我留言指教一下,谢谢!