Jetty、React、SpringBoot

Article Directory
  1. 1. 在SpringBoot中,使用Jettyy轻量级可配置服务器,而不是自带的Tomcat
  2. 2. 配置Jetty
  3. 3. 整合React
    1. 3.1. build
    2. 3.2. build放到Spriongboot注意
    3. 3.3. 更改打包路径
  4. 4. 整合之后
  5. 5. Jetty,使用Ant Design Pro,集成到SpringBoot
    1. 5.1. Ant Design Pro 文档总览
    2. 5.2. 官方原话:
    3. 5.3. 1、npm安装@ant-design/pro-cli
    4. 5.4. 2、然后创建SpringBoot工程
      1. 5.4.1. 此处使用jetty启动后端项目。
        1. 5.4.1.1. a、pom.xml增加如下配置
        2. 5.4.1.2. b、配置maven启动
        3. 5.4.1.3. c、需要在src->main下创建一个webapp文件夹。
    5. 5.5. 3、前端Ant DesignPro整合进来
      1. 5.5.1. a、首先把myapp文件夹放到java工程中,与src文件夹平级
      2. 5.5.2. b、build打包之前,react工程的package.json里面加入一句话。
      3. 5.5.3. c、build打包之前,修改打包路径
      4. 5.5.4. d、修改路由方式
      5. 5.5.5. e、build打包
      6. 5.5.6. f、使用jetty运行SpringBoot
    6. 5.6. 4、然后需要写后端api
  6. 6. 默认Tomcat,使用Ant Design Pro,集成到SpringBoot
    1. 6.1. Ant Design Pro 文档总览
    2. 6.2. 官方原话:
    3. 6.3. 1、npm安装@ant-design/pro-cli
    4. 6.4. 2、然后创建SpringBoot工程
      1. 6.4.1. a、application.yaml配置
      2. 6.4.2. b、写一个普通的controller
      3. 6.4.3. c、写一个配置类,否则static下面的js、css等资源找不到
    5. 6.5. 3、前端Ant DesignPro整合进来
      1. 6.5.1. a、首先把myapp文件夹放到java工程中,与src文件夹平级
      2. 6.5.2. b、build打包之前,react工程的package.json里面加入一句话。
      3. 6.5.3. c、build打包之前,修改打包路径
      4. 6.5.4. d、修改路由方式
      5. 6.5.5. e、build打包
      6. 6.5.6. f、直接运行SpringBootApplication
    6. 6.6. 4、然后需要写后端api

Jetty、React、SpringBoot

在SpringBoot中,使用Jettyy轻量级可配置服务器,而不是自带的Tomcat

配置Jetty

jetty轻量级服务器介绍,运行命令及pom配置

Maven中配置jetty插件

Jetty Maven插件可用于快速开发和测试。您可以将它添加到根据Maven POM配置的任何webapp项目中。该插件可以定期扫描项目中的更改,并自动重新部署webapp(启动中的)。通过消除构建和部署步骤,允许您直接测试它们,这使得开发周期更加高效。

jetty更推荐于开发环境而非生成环境。

pom配置。

可以去Maven服务器网址找对应的依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!-- https://mvnrepository.com/artifact/org.eclipse.jetty/jetty-maven-plugin -->
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.52.v20230823</version>
</plugin>


<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>10.0.16</version>
<configuration>
<supportedPackagings>jar</supportedPackagings>
<webApp>
<contextPath>/test</contextPath>
</webApp>
<!-- webx表示停止程序的命令 -->
<stopKey>webx</stopKey>
<!-- 执行关闭功能的端口,一般不对外 -->
<stopPort>9999</stopPort>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<!-- 设置端口号:8081 -->
<port>8081</port>
<!-- 响应的最大空闲时间 -->
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
<!-- 记录日志 -->
<requestLog implementation="org.eclipse.jetty.server.NCSARequestLog">
<!-- 日志的存放位置 -->
<filename>target/access.log</filename>
<!-- 日志的存放的时间 -->
<retainDays>90</retainDays>
<!-- 增加的方式 -->
<append>false</append>
<!-- 有无扩展信息 -->
<extended>false</extended>
<!-- 时区 -->
<logTimeZone>GMT+8:00</logTimeZone>
</requestLog>
</configuration>
</plugin>

注意,/test之后是访问/test才能到项目中的webapp目录。

需要在src->main下创建一个webapp文件夹。

可配置启动端口,默认8080

1
mvn jetty:run -Djetty.http.port=9999
1
2
3
<!-- 启动后如果出现:packaging type [jar] is unsupported -->
<!-- add下面的到configuration标签中去 -->
<supportedPackagings>jar</supportedPackagings>
1
2
3
# 安装maven环境,其实不需要,IDEA自带
export MAVEN_HOME=/Users/dinosaur/jcwang/software/apache-maven-3.8.8
export PATH=$MAVEN_HOME/bin:$PATH:.

整合React

build

npm run build之后,会生成一个build文件夹。

1
npm i serve -g

全局安装serve,用serve就可以将build的静态文件开一个服务器运行起来。

然后到build文件夹下面(有index.html)运行下面命令就行

1
serve [文件夹名字]

build放到Spriongboot注意

然后使用命令创建一个react应用,放到IDEA自己创建的文件夹中

1
create-react-app jetty-react-test

然后build之后的静态文件,放到webapp中去。

注意,打包之前需要在react工程的package.json里面加入一句话,

否则的话,所有的资源的路径都是绝对路径,会加载失败。

1
2
3
{
"homepage": "." //新增此项,打包后的静态文件引入路径改为相对路径'./'
}

更改打包路径

打包的时候默认是 ./ 访问, 部署的时候会有问题

creat-react-app 修改打包路径

1、新建 .env 文件,并添加以下配置

1
BUILD_PATH = "../src/main/webapp/"

另外两种在上面的链接,就不贴了,因为感觉第一个有用。

整合之后

在同一个工程中写前端代码,写完之后build,然后后端jetty运行,访问相应的端口和contextPath下的路径,就能访问到react的build之后的静态资源了。

TODO:

然后后面还需要探索一下,npm run start之后运行一下前端,因为react代码改了之后前端能直接看到,而不是一直build之后运行后端这样。

然后公司的前端运行时候,需要先运行后端的端口,注册一下,才能前端出来,这个需要考虑一下看看嘛。

下周可以尝试:重新整合一个,上一个当作例子。整合进来新的前端react的成熟的网页例子,然后使用antd组件,进行一些开发,和尝试。

然后可以尝试在vs code运行前后端口。

Jetty,使用Ant Design Pro,集成到SpringBoot

Ant Design Pro Github

Ant Design Pro 文档总览

官方原话:

Spring Boot 是使用最多的 java 框架,只需要简单的几步就可以与 Ant Design Pro 进行整合。

首先运行 build

1
$ npm run build

然后将编译之后的文件复制到 spring boot 项目的 /src/main/resources/static 目录下。

重新启动项目,访问 http://localhost:8080/ 就可以看到效果。

为了方便做整合,最好使用 hash 路由。如果你想使用 browserHistory ,可以创建一个 controller ,并添加如下代码:

1
2
3
4
5
6
7
8
9
10
@RequestMapping("/api/**")
public ApiResult api(HttpServletRequest request, HttpServletResponse response){
return apiProxy.proxy(request, response);
}


@RequestMapping(value="/**", method=HTTPMethod.GET)
public String index(){
return "index"
}

注意 pro 并没有提供 java 的 api 接口实现,如果只是为了预览 demo,可以使用反向代理到 https://preview.pro.ant.design

UmiJS官网

1、npm安装@ant-design/pro-cli

(应该是创建脚手架的啥)并且创建工程前端Ant Design PRo

1
2
3
4
5
6
7
8
9
10
11
12
sudo npm i @ant-design/pro-cli -g

# 创建Ant Design Pro模版,选择了umi@4
pro create myapp

# 进去,安装依赖
cd myapp
npm install

# 然后就是npm运行编译啥的
npm run start
npm run build

2、然后创建SpringBoot工程

JDK17,SpringBoot3.1.3。

勾选Spring Web即可

thymeleaf引擎,SpringBoot整合Ant Design Pro进行部署

理论上可以使用内置的Tomcat,然后使用thymeleaf引擎啥的,配置静态资源路径。然后写一个controller,映射到主页/,然后返回本地的静态资源。npm run build之后将编译之后的文件复制到 spring boot 项目的 /src/main/resources/static 目录下。

此处使用jetty启动后端项目。

a、pom.xml增加如下配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!-- https://mvnrepository.com/artifact/org.eclipse.jetty/jetty-maven-plugin --><plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>10.0.16</version>
<configuration>
<!-- 注意要加这个,不然报错不支持jar -->
<supportedPackagings>jar</supportedPackagings>
<webApp>
<contextPath>/</contextPath>
</webApp>
<!-- webx表示停止程序的命令 -->
<stopKey>webx</stopKey>
<!-- 执行关闭功能的端口,一般不对外 -->
<stopPort>9999</stopPort>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<!-- 设置端口号:1997-->
<port>1997</port>
<!-- 响应的最大空闲时间 -->
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
<!-- 记录日志 -->
<requestLog implementation="org.eclipse.jetty.server.NCSARequestLog">
<!-- 日志的存放位置 -->
<filename>target/access.log</filename>
<!-- 日志的存放的时间 -->
<retainDays>90</retainDays>
<!-- 增加的方式 -->
<append>false</append>
<!-- 有无扩展信息 -->
<extended>false</extended>
<!-- 时区 -->
<logTimeZone>GMT+8:00</logTimeZone>
</requestLog>
</configuration>
</plugin>
b、配置maven启动
1
2
3
4
jetty:run -Djetty.http.port=1997

# 加上-X可以查看详细的debug信息
jetty:run -X -Djetty.http.port=1997

terminal要加上mvn?

1
mvn jetty:run -Djetty.http.port=1997
c、需要在src->main下创建一个webapp文件夹。

因为contextPath 的默认值的 /,${project.artifactId} 引用了 节点的值,即项目的名称。
项目的静态资源文件目录默认是 src/main/webapp,如果静态资源目录有多个,或者不在默认的 src/main/webapp 目录下,可做如下配置:

1
2
3
4
5
6
7
8
9
10
11
<configuration>
[...]
<webApp>
<contextPath>/${project.artifactId}</contextPath>
<resourceBases>
<resourceBase>${project.basedir}/src/main/webapp</resourceBase>
<resourceBase>${project.basedir}/commons</resourceBase>
</resourceBases>
</webApp>
[...]
</configuration>

3、前端Ant DesignPro整合进来

a、首先把myapp文件夹放到java工程中,与src文件夹平级

起名web就行了,我起名字antdesignpro-web

b、build打包之前,react工程的package.json里面加入一句话。

否则的话,所有的资源的路径都是绝对路径,会加载失败。

1
2
3
4
{
"homepage": "."
//新增此项,打包后的静态文件引入路径改为相对路径'./',注意json文件,家在打括号里面的
}

c、build打包之前,修改打包路径

新建 .env 文件,并添加以下配置,与package.json平级。

1
BUILD_PATH = "../src/main/webapp/"

注意之前直接用react脚手架项目是这样的,现在是ant design pro不一样。

umijs配置

Ant Design Pro构建

config/config.ts文件中,写输出路径,默认是./dist

1
outputPath: "../src/main/webapp/" // 定义外部输出路径

d、修改路由方式

Ant Design Pro部署

Ant Design Pro 使用的 Umi 可以使用两种路由方式:browserHistoryhashHistory

可以在 config/config.ts 中进行配置选择用哪个方式:

1
2
3
export default {
history: { type: 'hash' }, // 默认是 browser
};

hashHistory 使用如 https://cdn.com/#/users/123 这样的 URL,取井号后面的字符作为路径。browserHistory 则直接使用 https://cdn.com/users/123 这样的 URL。使用 hashHistory 时浏览器访问到的始终都是根目录下 index.html。使用 browserHistory 则需要服务器做好处理 URL 的准备,处理应用启动最初的 / 这样的请求应该没问题,但当用户来回跳转并在 /users/123 刷新时,服务器就会收到来自 /users/123 的请求,这时你需要配置服务器能处理这个 URL 返回正确的 index.html,否则就会出现 404 找不到该页面的情况。如果没有对服务器端的控制权限,建议在配置中开启 exportStatic,这样编译后的 dist 目录会对每一个路由都生成一个 index.html,从而每个路由都能支持 deeplink 直接访问。强烈推荐使用默认的 browserHistory

e、build打包

1
npm run build

umijs配置

问题,fatal - [esbuildHelperChecker] Found conflicts in esbuild helpers: Ed (199.aacdf6bf.async.js, umi.0aefec68.js), Pd (199.aacdf6bf.async.js, umi.0aefec68.js), please set esbuildMinifyIIFE: true in your config file.

解决,在config/config.ts文件中,增加esbuildMinifyIIFE: true,

1
esbuildMinifyIIFE: true,

f、使用jetty运行SpringBoot

1
mvn jetty:run -Djetty.http.port=1997

访问,localhost:1997

4、然后需要写后端api

官方原话:
注意 pro 并没有提供 java 的 api 接口实现,如果只是为了预览 demo,可以使用反向代理到 https://preview.pro.ant.design

注意,由于jetty启动后,发现controller写的接口无法访问了,我现在还是选择使用tomcat了。感觉因为不是SpringBootApplication访问的,好像没扫描到controller包?那咋扫描呢?

默认Tomcat,使用Ant Design Pro,集成到SpringBoot

Ant Design Pro Github

Ant Design Pro 文档总览

官方原话:

Spring Boot 是使用最多的 java 框架,只需要简单的几步就可以与 Ant Design Pro 进行整合。

首先运行 build

1
$ npm run build

然后将编译之后的文件复制到 spring boot 项目的 /src/main/resources/static 目录下。

重新启动项目,访问 http://localhost:8080/ 就可以看到效果。

为了方便做整合,最好使用 hash 路由。如果你想使用 browserHistory ,可以创建一个 controller ,并添加如下代码:

1
2
3
4
5
6
7
8
9
10
@RequestMapping("/api/**")
public ApiResult api(HttpServletRequest request, HttpServletResponse response){
return apiProxy.proxy(request, response);
}


@RequestMapping(value="/**", method=HTTPMethod.GET)
public String index(){
return "index"
}

注意 pro 并没有提供 java 的 api 接口实现,如果只是为了预览 demo,可以使用反向代理到 https://preview.pro.ant.design

UmiJS官网

1、npm安装@ant-design/pro-cli

(应该是创建脚手架的啥)并且创建工程前端Ant Design PRo

1
2
3
4
5
6
7
8
9
10
11
12
sudo npm i @ant-design/pro-cli -g

# 创建Ant Design Pro模版,选择了umi@4
pro create myapp

# 进去,安装依赖
cd myapp
npm install

# 然后就是npm运行编译啥的
npm run start
npm run build

2、然后创建SpringBoot工程

thymeleaf引擎,SpringBoot整合Ant Design Pro进行部署

JDK17,SpringBoot3.1.3。

勾选Spring Web,thymeleaf引擎。

1
2
3
4
5
6
7
8
9
10
11
12
13
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

可以使用内置的Tomcat,然后使用thymeleaf引擎啥的,配置静态资源路径。然后写一个controller,映射到主页/,到返回本地的静态资源。npm run build之后将编译之后的文件复制到 spring boot 项目的 /src/main/resources/static 目录下。

a、application.yaml配置

1
2
3
4
5
server:
port: 1997
spring:
thymeleaf:
prefix: classpath:static/

b、写一个普通的controller

注意一定要在SpringBootApplication的后面级,才能被扫描到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/**
* @author dinosaur
* @description 拦截Ant Design Pro访问路径
*/
@Controller
public class TomcatAntDesignProController {
@GetMapping("/welcome")
@ResponseBody
public String welcome() {
return "Welcome to Ant Design Pro Spring Boot Test!";
}

/**
* 配置url通配符,拦截多个地址
* @return
*/
@RequestMapping(value = {
"/",
"/user",
"/user/**",
"/console",
"/console/**"
})
public String fowardIndex() {
return "index";
}

@GetMapping("/api/currentUser")
@ResponseBody
public String getCurrentUser() {
String currentUser =
"""
{"name":"羊八井","avatar":"https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png","userid":"00000001","email":"yangbajing@gmail.com","signature":"海纳百川,有容乃大","title":"一个好爸爸","group":"华龙海数-某某某事业群-某某平台部-某某技术部-Developer","tags":[{"key":"0","label":"很有想法的"},{"key":"1","label":"专注后端"},{"key":"2","label":"强~"},{"key":"3","label":"彪悍"},{"key":"4","label":"重庆崽儿"},{"key":"5","label":"海纳百川"}],"notifyCount":12,"country":"China","geographic":{"province":{"label":"重庆市","key":"330000"},"city":{"label":"渝北区","key":"402260"}},"address":"渝北区金开大道西段106号10栋移动新媒体产业大厦11楼","phone":"023-88888888"}
""";
return currentUser;
}

@RequestMapping("/api/login/account")
@ResponseBody
public String api(HttpServletRequest request, HttpServletResponse response){
return """
{
"success": true,
"data": {},
"errorCode": "1001",
"errorMessage": "error message",
"showType": 2,
"traceId": "someid",
"host": "10.1.1.1"
}
""";
}
}

c、写一个配置类,否则static下面的js、css等资源找不到

1
2
3
4
5
6
7
8
@Configuration
@EnableWebMvc
public class UseStaticResourceConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
}
}

3、前端Ant DesignPro整合进来

a、首先把myapp文件夹放到java工程中,与src文件夹平级

起名web就行了,我起名字antdesignpro-web

b、build打包之前,react工程的package.json里面加入一句话。

否则的话,所有的资源的路径都是绝对路径,会加载失败。

1
2
3
4
{
"homepage": ".",
//新增此项,打包后的静态文件引入路径改为相对路径'./',注意json文件,家在打括号里面的
}

c、build打包之前,修改打包路径

新建 .env 文件,并添加以下配置,与package.json平级。

1
BUILD_PATH = "../src/main/resources/static/"

注意之前直接用react脚手架项目是这样的,现在是ant design pro不一样。

umijs配置

Ant Design Pro构建

config/config.ts文件中,写输出路径,默认是./dist

1
outputPath: "../src/main/resources/static/" // 定义外部输出路径

d、修改路由方式

Ant Design Pro部署

Ant Design Pro 使用的 Umi 可以使用两种路由方式:browserHistoryhashHistory

可以在 config/config.ts 中进行配置选择用哪个方式:

1
2
3
export default {
history: { type: 'hash' }, // 默认是 browser
};

hashHistory 使用如 https://cdn.com/#/users/123 这样的 URL,取井号后面的字符作为路径。browserHistory 则直接使用 https://cdn.com/users/123 这样的 URL。使用 hashHistory 时浏览器访问到的始终都是根目录下 index.html。使用 browserHistory 则需要服务器做好处理 URL 的准备,处理应用启动最初的 / 这样的请求应该没问题,但当用户来回跳转并在 /users/123 刷新时,服务器就会收到来自 /users/123 的请求,这时你需要配置服务器能处理这个 URL 返回正确的 index.html,否则就会出现 404 找不到该页面的情况。如果没有对服务器端的控制权限,建议在配置中开启 exportStatic,这样编译后的 dist 目录会对每一个路由都生成一个 index.html,从而每个路由都能支持 deeplink 直接访问。强烈推荐使用默认的 browserHistory

e、build打包

umijs配置

问题,fatal - [esbuildHelperChecker] Found conflicts in esbuild helpers: Ed (199.aacdf6bf.async.js, umi.0aefec68.js), Pd (199.aacdf6bf.async.js, umi.0aefec68.js), please set esbuildMinifyIIFE: true in your config file.

解决,在config/config.ts文件中,增加esbuildMinifyIIFE: true,

1
esbuildMinifyIIFE: true,

然后才能打包:

1
npm run build

f、直接运行SpringBootApplication

可以设置访问端口1997

访问,localhost:1997

4、然后需要写后端api

官方原话:
注意 pro 并没有提供 java 的 api 接口实现,如果只是为了预览 demo,可以使用反向代理到 https://preview.pro.ant.design

Author: Jcwang

Permalink: http://example.com/2023/09/09/Jetty%E3%80%81React%E3%80%81SpringBoot/