- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章使用springboot打包成zip部署,并实现优雅停机由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
众所周知springboot项目,使用springboot插件打包的话,会打包成一个包含依赖的可执行jar,非常方便。只要有java运行环境的电脑上,运行java -jar xxx.jar就可以直接运行项目.
但是这样的缺点也很明显,如果我要改个配置,要将jar包中的配置文件取出来,修改完再放回去。这样做在windows下还比较容易。如果在linux上面就很费劲了.
另外如果代码中需要读取一些文件(比如说一张图片),也被打进jar中,就没办法像在磁盘中时一句File file = new File(path)代码就可以读取了。(当然这个可以使用spring的ClassPathResource来解决).
还有很多公司项目上线后,都是增量发布,这样如果只有一个jar 的话,增量发布也是很麻烦的事情。虽然我是很讨厌这种增量发布的方式,因为会造成线上生产环境和开发环境有很多不一致的地方,这样在找问题的时候会走很多弯路。很不幸我现在在的项目也是这样的情况,而且最近接的任务就是用springboot搭建一个定时任务服务,为了维护方便,最后决定将项目打包成zip进行部署.
网上找到了很多springboot打包成zip的文章,不过基本都是将依赖从springboot的jar中拿出来放到lib目录中,再将项目的jar包中META-INF中指定lib到classpath中。这样做还是会有上面的问题.
最后我决定自己通过maven-assembly-plugin来实现这个功能.
首先maven-assembly-plugin是将项目打包的一个插件。可以通过指定配置文件来决定打包的具体要求.
我的想法是将class打包到classes中,配置文件打包到conf中,项目依赖打包到lib中,当然还有自己编写的启动脚本在bin目录中.
如图 。
maven的target/classes下就是项目编译好的代码和配置文件。原来的做法是在assembly.xml中配置筛选,将该目录下class文件打包进classes中,除class文件打包到conf中(bin目录文件打包进bin目录,项目依赖打包进lib目录)。结果发现conf目录下会有空文件夹(java包路径).
pom.xml 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<
plugin
>
<
artifactId
>maven-assembly-plugin</
artifactId
>
<
configuration
>
<
appendAssemblyId
>false</
appendAssemblyId
>
<
descriptors
>
<
descriptor
>assembly/assembly.xml</
descriptor
>
</
descriptors
>
</
configuration
>
<
executions
>
<
execution
>
<
id
>make-assembly</
id
>
<
phase
>package</
phase
>
<
goals
>
<
goal
>single</
goal
>
</
goals
>
</
execution
>
</
executions
>
</
plugin
>
|
assembly.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
38
39
40
41
42
43
44
|
<
assembly
xmlns
=
"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
=
"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd"
>
<
id
>package</
id
>
<
formats
>
<
format
>zip</
format
>
</
formats
>
<
includeBaseDirectory
>true</
includeBaseDirectory
>
<
dependencySets
>
<
dependencySet
>
<
useProjectArtifact
>true</
useProjectArtifact
>
<
outputDirectory
>lib</
outputDirectory
>
<
excludes
>
<
exclude
>
${groupId}:${artifactId}
</
exclude
>
</
excludes
>
</
dependencySet
>
</
dependencySets
>
<
fileSets
>
<
fileSet
>
<
directory
>bin</
directory
>
<
outputDirectory
>/bin</
outputDirectory
>
<
fileMode
>777</
fileMode
>
</
fileSet
>
<
fileSet
>
<
directory
>${project.build.directory}/conf</
directory
>
<
outputDirectory
>/conf</
outputDirectory
>
<
excludes
>
<
exclude
>**/*.class</
exclude
>
<
exclude
>META-INF/*</
exclude
>
</
excludes
>
</
fileSet
>
<
fileSet
>
<
directory
>${project.build.directory}/classes</
directory
>
<
outputDirectory
>/classes</
outputDirectory
>
<
includes
>
<
include
>**/*.class</
include
>
<
include
>META-INF/*</
include
>
</
includes
>
</
fileSet
>
</
fileSets
>
</
assembly
>
|
其实这样是不影响项目运行的,但是我看着很难受,尝试了很多方法去修改配置来达到不打包空文件夹的效果。但是都没成功.
然后我换了个方式,通过maven-resources-plugin插件将配置文件在编译的时候就复制一份到target/conf目录下,打包的时候配置文件从conf目录中取。这样就可以避免打包空白文件夹到conf目录中的情况.
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
<
build
>
<
plugins
>
<
plugin
>
<
artifactId
>maven-resources-plugin</
artifactId
>
<
executions
>
<
execution
>
<
id
>compile-resources</
id
>
<
goals
>
<
goal
>resources</
goal
>
</
goals
>
<
configuration
>
<
encoding
>utf-8</
encoding
>
<
useDefaultDelimiters
>true</
useDefaultDelimiters
>
<
resources
>
<
resource
>
<
directory
>src/main/resources/</
directory
>
<
filtering
>true</
filtering
>
<
includes
>
<!--只对yml文件进行替换-->
<
include
>*.yml</
include
>
</
includes
>
</
resource
>
<
resource
>
<
directory
>src/main/resources/</
directory
>
<
filtering
>false</
filtering
>
</
resource
>
</
resources
>
</
configuration
>
</
execution
>
<
execution
>
<
id
>-resources</
id
>
<
goals
>
<
goal
>resources</
goal
>
</
goals
>
<
configuration
>
<
encoding
>utf-8</
encoding
>
<
useDefaultDelimiters
>true</
useDefaultDelimiters
>
<
resources
>
<
resource
>
<
directory
>src/main/resources/</
directory
>
<
filtering
>true</
filtering
>
<
includes
>
<!--只对yml文件进行替换-->
<
include
>*.yml</
include
>
</
includes
>
</
resource
>
<
resource
>
<
directory
>src/main/resources/</
directory
>
<
filtering
>false</
filtering
>
</
resource
>
</
resources
>
<
outputDirectory
>${project.build.directory}/conf</
outputDirectory
>
</
configuration
>
</
execution
>
</
executions
>
</
plugin
>
<!-- springboot maven打包-->
<
plugin
>
<
groupId
>org.springframework.boot</
groupId
>
<
artifactId
>spring-boot-maven-plugin</
artifactId
>
</
plugin
>
<
plugin
>
<
artifactId
>maven-assembly-plugin</
artifactId
>
<
configuration
>
<
appendAssemblyId
>false</
appendAssemblyId
>
<
descriptors
>
<
descriptor
>assembly/assembly.xml</
descriptor
>
</
descriptors
>
</
configuration
>
<
executions
>
<
execution
>
<
id
>make-assembly</
id
>
<
phase
>package</
phase
>
<
goals
>
<
goal
>single</
goal
>
</
goals
>
</
execution
>
</
executions
>
</
plugin
>
</
plugins
>
</
build
>
|
assembly.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
38
39
40
41
|
<
assembly
xmlns
=
"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
=
"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd"
>
<
id
>package</
id
>
<
formats
>
<
format
>zip</
format
>
<
format
>tar.gz</
format
>
</
formats
>
<
includeBaseDirectory
>true</
includeBaseDirectory
>
<
dependencySets
>
<
dependencySet
>
<
useProjectArtifact
>true</
useProjectArtifact
>
<
outputDirectory
>lib</
outputDirectory
>
<
excludes
>
<
exclude
>
${groupId}:${artifactId}
</
exclude
>
</
excludes
>
</
dependencySet
>
</
dependencySets
>
<
fileSets
>
<
fileSet
>
<
directory
>bin</
directory
>
<
outputDirectory
>/bin</
outputDirectory
>
<
fileMode
>777</
fileMode
>
</
fileSet
>
<
fileSet
>
<
directory
>${project.build.directory}/conf</
directory
>
<
outputDirectory
>/conf</
outputDirectory
>
</
fileSet
>
<
fileSet
>
<
directory
>${project.build.directory}/classes</
directory
>
<
outputDirectory
>/classes</
outputDirectory
>
<
includes
>
<
include
>**/*.class</
include
>
<
include
>META-INF/*</
include
>
</
includes
>
</
fileSet
>
</
fileSets
>
</
assembly
>
|
pom文件中resources插件配置了2个execution,一个是正常往classes中写配置文件的execution,一个是往conf写配置文件的execution。这样做的好处是不影响maven本身的打包逻辑。如果再配置一个springboot的打包插件,也可以正常打包,执行.
原来打包成jar后,只要一句java -jar xxx.jar就可以启动项目。现在为多个文件夹的情况下,就要手动指定环境,通过java -classpath XXX xxx.xxx.MainClass来启动项目,所以写了启动脚本.
run.sh 。
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
|
#!/bin/bash
#Java程序所在的目录(classes的上一级目录)
APP_HOME=..
#需要启动的Java主程序(main方法类)
APP_MAIN_CLASS="io.github.loanon.springboot.MainApplication"
#拼凑完整的classpath参数,包括指定lib目录下所有的jar
CLASSPATH="$APP_HOME/conf:$APP_HOME/lib/*:$APP_HOME/classes"
s_pid=0
checkPid() {
java_ps=`jps -l | grep $APP_MAIN_CLASS`
if [ -n "$java_ps" ]; then
s_pid=`echo $java_ps | awk '{print $1}'`
else
s_pid=0
fi
}
start() {
checkPid
if [ $s_pid -ne 0 ]; then
echo "================================================================"
echo "warn: $APP_MAIN_CLASS already started! (pid=$s_pid)"
echo "================================================================"
else
echo -n "Starting $APP_MAIN_CLASS ..."
nohup java -classpath $CLASSPATH $APP_MAIN_CLASS >./st.out 2>&1 &
checkPid
if [ $s_pid -ne 0 ]; then
echo "(pid=$s_pid) [OK]"
else
echo "[Failed]"
fi
fi
}
echo "start project......"
start
run.cmd
@echo off
set APP_HOME=..
set CLASS_PATH=%APP_HOME%/lib/*;%APP_HOME%/classes;%APP_HOME%/conf;
set APP_MAIN_CLASS=io.github.loanon.springboot.MainApplication
java -classpath %CLASS_PATH% %APP_MAIN_CLASS%
|
这样就可以启动项目了.
linux下停止tomcat一般怎么做?当然是通过运行shutdown.sh。这样做有什么好处呢?可以优雅停机。何为优雅停机?简单点说就是让代码把做了一半工作的做完,还没做的(新的任务,请求)就不要做了,然后停机.
因为做的是定时任务处理数据的功能。试想下如果一个任务做了一半,我给停了,这个任务处理的数据被我标记了在处理中,下次重启后,就不再处理,那么这些数据就一直不会再被处理。所以需要像tomcat一样能优雅停机.
网上查询springboot优雅停机相关资料。主要是使用spring-boot-starter-actuator,不过很多人说这个在1.X的springboot中可以用,springboot 2.X不能用,需要自己写相关代码来支持,亲测springboot 2.0.4.RELEASE可以用。pom文件中引入相关依赖.
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
project
xmlns
=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<
modelVersion
>4.0.0</
modelVersion
>
<
parent
>
<
groupId
>org.springframework.boot</
groupId
>
<
artifactId
>spring-boot-starter-parent</
artifactId
>
<
version
>2.0.4.RELEASE</
version
>
<
relativePath
/>
<!-- lookup parent from repository -->
</
parent
>
<
groupId
>io.github.loanon</
groupId
>
<
artifactId
>spring-boot-zip</
artifactId
>
<
version
>1.0.0-SNAPSHOT</
version
>
<
properties
>
<
java.version
>1.8</
java.version
>
<
encoding
>UTF-8</
encoding
>
<
maven.compiler.encoding
>UTF-8</
maven.compiler.encoding
>
<
project.build.sourceEncoding
>UTF-8</
project.build.sourceEncoding
>
<
project.reporting.outputEncoding
>UTF-8</
project.reporting.outputEncoding
>
<
maven.compiler.source
>${java.version}</
maven.compiler.source
>
<
maven.compiler.target
>${java.version}</
maven.compiler.target
>
</
properties
>
<
dependencies
>
<
dependency
>
<
groupId
>org.springframework.boot</
groupId
>
<
artifactId
>spring-boot-starter-web</
artifactId
>
</
dependency
>
<
dependency
>
<
groupId
>org.springframework.boot</
groupId
>
<
artifactId
>spring-boot-starter-logging</
artifactId
>
</
dependency
>
<!-- springboot监控 -->
<
dependency
>
<
groupId
>org.springframework.boot</
groupId
>
<
artifactId
>spring-boot-starter-actuator</
artifactId
>
</
dependency
>
<!--springboot自定义配置-->
<
dependency
>
<
groupId
>org.springframework.boot</
groupId
>
<
artifactId
>spring-boot-autoconfigure-processor</
artifactId
>
</
dependency
>
<!--定时任务-->
<
dependency
>
<
groupId
>org.springframework.boot</
groupId
>
<
artifactId
>spring-boot-starter-quartz</
artifactId
>
</
dependency
>
<!--发送http请求 -->
<
dependency
>
<
groupId
>org.apache.httpcomponents</
groupId
>
<
artifactId
>httpclient</
artifactId
>
</
dependency
>
<
dependency
>
<
groupId
>org.apache.httpcomponents</
groupId
>
<
artifactId
>httpmime</
artifactId
>
</
dependency
>
</
dependencies
>
<
build
>
<
plugins
>
<
plugin
>
<
artifactId
>maven-resources-plugin</
artifactId
>
<
executions
>
<
execution
>
<
id
>compile-resources</
id
>
<
goals
>
<
goal
>resources</
goal
>
</
goals
>
<
configuration
>
<
encoding
>utf-8</
encoding
>
<
useDefaultDelimiters
>true</
useDefaultDelimiters
>
<
resources
>
<
resource
>
<
directory
>src/main/resources/</
directory
>
<
filtering
>true</
filtering
>
<
includes
>
<!--只对yml文件进行替换-->
<
include
>*.yml</
include
>
</
includes
>
</
resource
>
<
resource
>
<
directory
>src/main/resources/</
directory
>
<
filtering
>false</
filtering
>
</
resource
>
</
resources
>
</
configuration
>
</
execution
>
<
execution
>
<
id
>-resources</
id
>
<
goals
>
<
goal
>resources</
goal
>
</
goals
>
<
configuration
>
<
encoding
>utf-8</
encoding
>
<
useDefaultDelimiters
>true</
useDefaultDelimiters
>
<
resources
>
<
resource
>
<
directory
>src/main/resources/</
directory
>
<
filtering
>true</
filtering
>
<
includes
>
<!--只对yml文件进行替换-->
<
include
>*.yml</
include
>
</
includes
>
</
resource
>
<
resource
>
<
directory
>src/main/resources/</
directory
>
<
filtering
>false</
filtering
>
</
resource
>
</
resources
>
<
outputDirectory
>${project.build.directory}/conf</
outputDirectory
>
</
configuration
>
</
execution
>
</
executions
>
</
plugin
>
<!-- springboot maven打包-->
<
plugin
>
<
groupId
>org.springframework.boot</
groupId
>
<
artifactId
>spring-boot-maven-plugin</
artifactId
>
</
plugin
>
<
plugin
>
<
artifactId
>maven-assembly-plugin</
artifactId
>
<
configuration
>
<
appendAssemblyId
>false</
appendAssemblyId
>
<
descriptors
>
<
descriptor
>assembly/assembly.xml</
descriptor
>
</
descriptors
>
</
configuration
>
<
executions
>
<
execution
>
<
id
>make-assembly</
id
>
<
phase
>package</
phase
>
<
goals
>
<
goal
>single</
goal
>
</
goals
>
</
execution
>
</
executions
>
</
plugin
>
</
plugins
>
</
build
>
</
project
>
|
在application.yml中配置一下 。
application.yml 。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
management: #开启监控管理,优雅停机
server:
ssl:
enabled:
false
endpoints:
web:
exposure:
include:
"*"
endpoint:
health:
show-details: always
shutdown:
enabled:
true
#启用shutdown端点
|
启动项目,可以通过POST方式访问/actuator/shutdown让项目停机.
实际线上可能没办法方便的发送POST请求,所以写个类处理下 。
Shutdown.java 。
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
|
package
io.github.loanon.springboot;
import
org.apache.http.client.HttpClient;
import
org.apache.http.client.methods.HttpPost;
import
org.apache.http.impl.client.HttpClients;
import
java.io.IOException;
/**
* 应用关闭入口
* @author dingzg
*/
public
class
Shutdown {
public
static
void
main(String[] args) {
String url =
null
;
if
(args.length >
0
) {
url = args[
0
];
}
else
{
return
;
}
HttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost =
new
HttpPost(url);
try
{
httpClient.execute(httpPost);
}
catch
(IOException e) {
e.printStackTrace();
}
}
}
|
只要将启动脚本中的启动类改成Shutdown类,并指定请求的地址即可.
stop.sh 。
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
|
#!/bin/bash
#Java程序所在的目录(classes的上一级目录)
APP_HOME=..
#需要启动的Java主程序(main方法类)
APP_MAIN_CLASS="io.github.loanon.springboot.MainApplication"
SHUTDOWN_CLASS="io.github.loanon.springboot.Shutdown"
#拼凑完整的classpath参数,包括指定lib目录下所有的jar
CLASSPATH="$APP_HOME/conf:$APP_HOME/lib/*:$APP_HOME/classes"
ARGS="http://127.0.0.1:8080/actuator/shutdown"
s_pid=0
checkPid() {
java_ps=`jps -l | grep $APP_MAIN_CLASS`
if [ -n "$java_ps" ]; then
s_pid=`echo $java_ps | awk '{print $1}'`
else
s_pid=0
fi
}
stop() {
checkPid
if [ $s_pid -ne 0 ]; then
echo -n "Stopping $APP_MAIN_CLASS ...(pid=$s_pid) "
nohup java -classpath $CLASSPATH $SHUTDOWN_CLASS $ARGS >./shutdown.out 2>&1 &
if [ $? -eq 0 ]; then
echo "[OK]"
else
echo "[Failed]"
fi
sleep 3
checkPid
if [ $s_pid -ne 0 ]; then
stop
else
echo "$APP_MAIN_CLASS Stopped"
fi
else
echo "================================================================"
echo "warn: $APP_MAIN_CLASS is not running"
echo "================================================================"
fi
}
echo "stop project......"
stop
stop.cmd
@echo off
set APP_HOME=..
set CLASS_PATH=%APP_HOME%/lib/*;%APP_HOME%/classes;%APP_HOME%/conf;
set SHUTDOWN_CLASS=io.github.loanon.springboot.Shutdown
set ARGS=http://127.0.0.1:8080/actuator/shutdown
java -classpath %CLASS_PATH% %SHUTDOWN_CLASS% %ARGS%
|
这样就可以通过脚本来启停项目.
关于停机这块还是有缺点,主要是安全性。如果不加校验都可以访问接口,别人也就可以随便让我们的项目停机,实际操作过程中我是通过将web地址绑定到127.0.0.1这个地址上,不允许远程访问。当然也可添加spring-security做严格的权限控制,主要项目中没有用到web功能,只是spring-quartz的定时任务功能,所以就将地址绑定到本地才能访问。而且项目本身也是在内网运行,基本可以保证安全.
以上为个人经验,希望能给大家一个参考,也希望大家多多支持我.
原文链接:https://www.cnblogs.com/jimmyfan/p/11340899.html 。
最后此篇关于使用springboot打包成zip部署,并实现优雅停机的文章就讲到这里了,如果你想了解更多关于使用springboot打包成zip部署,并实现优雅停机的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
SpringBoot-Admin 服务监控 简单介绍 Spring Boot Actuator 是 Spring Boot 自带的一个功能模块, 提供了一组已经开箱即用的生产环境下常用
我想查找通过关键字匹配字段 nameEnglish 或 nameChinese 的模型列表。我花了一个多小时谷歌搜索但我做不到。请帮忙。 Springboot Mongo 入门示例 https://s
(请注意:在调查 this issue 时,我更好地发现了我在此处介绍的问题根源) 我对 Hibernate 和 SpringBoot 非常陌生。我的项目涉及一个搜索引擎,其中索引(javafx 客户
我最近有一个 Web 应用程序从 springboot 升级到 springboot 2。当我将其部署到 Tomcat 8 时,它似乎启动了,但没有完全启动。 在 localhost.2019-09-
我是 Spring boot 的新手...我在运行 Controller 时遇到问题, Description: Field todoService in com.springboot.todoCon
我有一个SpringBoot应用程序,它使用以下配置与PostgreSQL通信,通过AWS Beanstrik部署:。在我将AWS Aurora证书更新为rds-ca-ecc384-g1之前,一切都很
雪花算法的唯一性,在单个节点中是可以保证的,对应kubernetes中的应用,如果是横向扩展后,进行多副本的情况下,可能出现重复的ID,这需要我们按着pod_name进行一个workId的生成,我还是
实在是不知道标题写什么了 可以在评论区给个建议哈哈哈哈 先用这个作为标题吧 尝试使用 国内给出的 AI 大模型做出一个 可以和 AI 对话的 网站出来 使用 智普AI 只能 在控制
一、介绍 在实际的软件系统开发过程中,由于业务的需求,在代码层面实现数据的脱敏还是远远不够的,往往还需要在数据库层面针对某些关键性的敏感信息,例如:身份证号、银行卡号、手机号、工资等信息进行加密存储
Selenium Selenium是一个用于Web应用程序自动化测试的开源工具套件。它主要用于以下目的: 浏览器自动化:Selenium能够模拟真实用户在不同浏览器(如Chrome、Fire
一、简介 在实际的项目开发过程中,经常需要用到邮件通知功能。例如,通过邮箱注册,邮箱找回密码,邮箱推送报表等等,实际的应用场景非常的多。 早期的时候,为了能实现邮件的自动发送功能,通常会使用 Ja
SpringBoot:基于redis自定义注解实现后端接口防重复提交校验 一、添加依赖 org.springframework.boot spring
SpringBoot:使用Jackson完成全局序列化配置 一、测试准备 com.fasterxml.jackson.core jackson-cor
springboot:整合rocketmq 一、简易消息操作 生产者整合mq 导入依赖 org.springframework.boot
springboot:常用注解 一、spring常用注解 包扫描+组件标注注解 @Component:泛指各种组件 @Controller、@Service、@Repository都可以称为@Comp
我们经常需要在两个系统之间进行一些数据的交互,这时候我们就需要开发数据交互接口。 一般来说,遇到比较多的接口有HTTP接口、WebService接口、FTP文件传输。今天我要来学习一下在SpringB
背景 近期项目上线,甲方要求通过安全检测才能进行验收,故针对扫描结果对系统进行了一系列的安全加固,本文对一些常见的安全问题及防护策略进行介绍,提供对应的解决方案 跨站脚本攻击 XSS常发生于论坛评论等
1.排除 Spring-boot-starter 默认的日志配置 将原本的 spring-boot-starter 改为 org.springframework.boot
springboot:解决跨域问题 一、跨域简介 URL的组成: // 协议 + 域名(子域名 + 主域名) + 端口号 + 资源地址 http://www.baidu.com:8080/ 只要协
一、自定义Starter 的思路: 创建一个Maven工程,创建三个模块 一个模块为demo-app,一个模块为demo-module,一个模块为demo-module-springboot-star
我是一名优秀的程序员,十分优秀!