Skip to content

Commit 6a9fba5

Browse files
committed
[add] First commit(历时一周)
0 parents  commit 6a9fba5

30 files changed

+1697
-0
lines changed

.gitignore

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/target/
2+
!.mvn/wrapper/maven-wrapper.jar
3+
4+
### STS ###
5+
.apt_generated
6+
.classpath
7+
.factorypath
8+
.project
9+
.settings
10+
.springBeans
11+
.sts4-cache
12+
13+
### IntelliJ IDEA ###
14+
.idea
15+
*.iws
16+
*.iml
17+
*.ipr
18+
19+
### NetBeans ###
20+
/nbproject/private/
21+
/nbbuild/
22+
/dist/
23+
/nbdist/
24+
/.nb-gradle/
25+
/build/
26+
27+
### VS Code ###
28+
.vscode/

README.md

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
## **SpringBoot-rest-demo**
2+
3+
> SpringBoot+maven多模块项目常用功能集锦,主要用于rest前后端分离项目,内容取自网络和自身经验,文中如有疏漏还请指正!
4+
5+
本项目SpringBoot版本为`2.1.3.RELEASE`, 代码中会嵌入部分链接作为参考
6+
7+
### 包含示例
8+
9+
1. SpringBoot+maven多模块项目配置(入口启动类`demo.web.WebApplication`
10+
2. 拦截器的使用`HandlerInterceptorAdapter`
11+
3. 统一异常处理`ControllerAdvice,ExceptionHandler`
12+
4. controller层参数校验(json参数、键值对参数、单个参数)`Validated, Valid`
13+
5. AOP记录日志`Aspect`
14+
6. 跨域访问
15+
7. 文件上传(拦截器控制大小限制)`MultipartFile`
16+
8. 邮件发送(结合JetBrick模板引擎)
17+
9. 异步任务(多线程)`EnableAsync, Async`
18+
10. 计划任务(定时任务)`Scheduled`
19+
11. 第三方接口调用`RestTemplate`
20+
12. 常用配置(见application.properties)
21+
22+
### 更多内容,持续更新
23+
24+
---
25+
26+
### 一些注意点:
27+
#### maven模块配置
28+
29+
父pom.xml文件中
30+
31+
```xml
32+
<groupId>demo</groupId>
33+
<artifactId>parent</artifactId>
34+
<version>0.0.1-SNAPSHOT</version>
35+
<name>parent</name>
36+
<!--必须指定为pom-->
37+
<packaging>pom</packaging>
38+
<!--指定子模块-->
39+
<modules>
40+
<module>web</module>
41+
<module>service</module>
42+
</modules>
43+
```
44+
45+
子模块pom.xml中
46+
47+
```xml
48+
<!--指定parent-->
49+
<parent>
50+
<groupId>demo</groupId>
51+
<artifactId>parent</artifactId>
52+
<version>0.0.1-SNAPSHOT</version>
53+
<!--上面的三个可以直接copy父pom.xml中的内容-->
54+
<relativePath>../pom.xml</relativePath>
55+
</parent>
56+
```
57+
58+
详见本项目代码
59+
60+
61+
#### 参数校验
62+
63+
若入参是对象,则给该对象的类加上`@Validated`, 注意`@Valid`不要漏了,否则不会生效
64+
65+
```java
66+
/**
67+
* 参数校验2,入参为json数据
68+
* 异常类型:{@link org.springframework.web.bind.MethodArgumentNotValidException}
69+
*/
70+
@PostMapping("/param1")
71+
public User param1(@Valid @RequestBody User user) {
72+
return user;
73+
}
74+
```
75+
76+
```java
77+
@Validated
78+
@Data
79+
public class User {
80+
private String id;//用户ID
81+
82+
@NotNull(message = "昵称不能为空")
83+
@Size(min = 2, max = 64, message = "昵称长度必须在2-64个字符")
84+
private String username;/
85+
86+
@Email(message = "邮箱必须合法")
87+
@NotNull(message = "邮箱不能为空")
88+
private String email;
89+
}
90+
```
91+
92+
如果`User`类上没加`@Validated`,在Controller类上加`@Validated`,效果是一样的,**建议两个地方都加上**,因为针对单个参数的校验,必须在Controller上加 `@Validated`
93+
94+
```java
95+
@RestController
96+
@Validated//校参注解
97+
public class RestfulController {
98+
//单个参数校验
99+
@RequestMapping("/param2")
100+
public Integer param2(@Range(min = 1, max = 100, message = "age必须在1和100之间") @RequestParam Integer age) {
101+
return age;
102+
}
103+
}
104+
```
105+
具体情况还是亲自运行看看吧
106+
#### 文件上传
107+
108+
文件上传大小限制为什么用拦截器实现呢?其实SpringBoot自带参数设置可以限制文件大小,如下:
109+
110+
```properties
111+
# 上传文件单个最大值
112+
spring.servlet.multipart.max-file-size=1MB
113+
# 上传文件总最大值
114+
spring.servlet.multipart.max-request-size=10MB
115+
```
116+
117+
但是会有一个问题,就是当上传的文件大小超过限制时,会抛出`MaxUploadSizeExceededException`异常,此异常无法被`ControllerAdvice`捕获,故使用拦截器来判断,若你有什么更好建议,欢迎提出!
118+
119+
#### More
120+
121+
更多内容,持续更新,感谢**`Star`**
122+

ajax.html

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<html>
2+
<head>
3+
<meta charset="UTF-8">
4+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5+
<meta name="keywords" content="Register,Login" />
6+
<meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0" />
7+
<meta name="format-detection" content="telephone=no,email=no,date=no,address=no"/>
8+
<title>ajax test</title>
9+
<script src="http://code.jquery.com/jquery-latest.js"></script>
10+
<style>
11+
input{
12+
width: 90vw;
13+
font-size: 20px;
14+
}
15+
#result{
16+
background-color: #51a42e;
17+
padding: 10px;
18+
}
19+
button{
20+
font-size: 20px;
21+
}
22+
</style>
23+
</head>
24+
<body>
25+
<h1>最好打开控制台测试</h1>
26+
<div></div>
27+
<h3 id="result"></h3>
28+
<input id="input" value="http://localhost:8080/ajax" placeholder="请求的URL"></input><br>
29+
<button id="btn">获取数据</button>
30+
</body>
31+
<script type="text/javascript">
32+
var data=JSON.stringify({"username":"Childwanwan","password":"123"});
33+
$("#btn").click(function(){
34+
console.log("click")
35+
$("#result").text("")
36+
$.ajax({
37+
url: $("#input").val(),
38+
method: "post",
39+
data: data,
40+
contentType: "application/json",
41+
xhrFields: {"withCredentials": true},//携带cookie
42+
success: res=>{
43+
console.log(res)
44+
$("#result").text(res)
45+
}
46+
})
47+
})
48+
</script>
49+
</html>

pom.xml

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>org.springframework.boot</groupId>
7+
<artifactId>spring-boot-starter-parent</artifactId>
8+
<version>2.1.3.RELEASE</version>
9+
<relativePath/> <!-- lookup parent from repository -->
10+
</parent>
11+
12+
<groupId>demo</groupId>
13+
<artifactId>parent</artifactId>
14+
<version>0.0.1-SNAPSHOT</version>
15+
<name>parent</name>
16+
<!--指定pom-->
17+
<packaging>pom</packaging>
18+
<description>Demo project for Spring Boot</description>
19+
20+
<!--子模块-->
21+
<modules>
22+
<module>web</module>
23+
<module>service</module>
24+
</modules>
25+
26+
<properties>
27+
<java.version>1.8</java.version>
28+
</properties>
29+
30+
<dependencies>
31+
<!--所有子模块可继承该父依赖-->
32+
<dependency>
33+
<groupId>org.projectlombok</groupId>
34+
<artifactId>lombok</artifactId>
35+
<optional>true</optional>
36+
</dependency>
37+
</dependencies>
38+
</project>

service/pom.xml

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>demo</groupId>
7+
<artifactId>parent</artifactId>
8+
<version>0.0.1-SNAPSHOT</version>
9+
<relativePath>../pom.xml</relativePath>
10+
</parent>
11+
<groupId>demo</groupId>
12+
<artifactId>service</artifactId>
13+
<version>0.0.1-SNAPSHOT</version>
14+
<name>service</name>
15+
<description>Demo project for Spring Boot</description>
16+
17+
<properties>
18+
<java.version>1.8</java.version>
19+
</properties>
20+
21+
<dependencies>
22+
<!--RestTemplate依赖于starter-web-->
23+
<dependency>
24+
<groupId>org.springframework.boot</groupId>
25+
<artifactId>spring-boot-starter-web</artifactId>
26+
</dependency>
27+
28+
</dependencies>
29+
30+
31+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package demo.service.config;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.http.client.ClientHttpRequestFactory;
6+
import org.springframework.http.client.SimpleClientHttpRequestFactory;
7+
import org.springframework.web.client.RestTemplate;
8+
9+
/**
10+
* parent
11+
* demo.service.config
12+
* RestTemplate配置类
13+
*
14+
* @author BlueDriver
15+
* @email cpwu@foxmail.com
16+
* @date 2019/03/29 20:54 Friday
17+
*/
18+
@Configuration
19+
public class RestTemplateConfig {
20+
@Bean
21+
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
22+
return new RestTemplate(factory);
23+
}
24+
25+
@Bean
26+
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
27+
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
28+
factory.setConnectTimeout(15_000);
29+
factory.setReadTimeout(5_000);
30+
return factory;
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package demo.service.service;
2+
3+
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import org.springframework.beans.factory.annotation.Autowired;
6+
import org.springframework.http.HttpEntity;
7+
import org.springframework.http.HttpHeaders;
8+
import org.springframework.http.MediaType;
9+
import org.springframework.http.ResponseEntity;
10+
import org.springframework.stereotype.Service;
11+
import org.springframework.web.client.RestTemplate;
12+
13+
/**
14+
* parent
15+
* demo.service.service
16+
* RestTemplate调用第三方接口(示例中调的是本地web模块中的接口)
17+
* https://blog.csdn.net/weixin_40461281/article/details/83540604
18+
* https://www.jianshu.com/p/8cc05da7a6a2
19+
*
20+
* @author BlueDriver
21+
* @email cpwu@foxmail.com
22+
* @date 2019/03/29 21:23 Friday
23+
*/
24+
@Service
25+
public class RestTemplateService {
26+
@Autowired
27+
private RestTemplate restTemplate;
28+
29+
/**
30+
* 获取url返回的字符串
31+
*/
32+
public String getStringFromUrl(String url) {
33+
return restTemplate.getForObject(url, String.class);
34+
}
35+
36+
/**
37+
* post请求url获得结果
38+
*
39+
* @param url 接口地址
40+
* @param requestParam 请求参数封装的类
41+
* @param responseClass 返回参数类型
42+
*/
43+
public <T, K> K postObjectFromUrl(String url, T requestParam, Class<K> responseClass) throws JsonProcessingException {
44+
ObjectMapper mapper = new ObjectMapper();
45+
String json = mapper.writeValueAsString(requestParam);
46+
return postObjectFromUrl(url, json, responseClass);
47+
}
48+
49+
/**
50+
* post请求url获得结果
51+
*
52+
* @param url 接口地址
53+
* @param requestJsonString json字符串格式参数
54+
* @param responseClass 返回类型
55+
*/
56+
public <K> K postObjectFromUrl(String url, String requestJsonString, Class<K> responseClass) {
57+
HttpHeaders headers = new HttpHeaders();
58+
headers.setContentType(MediaType.APPLICATION_JSON);//设置contentType为json
59+
HttpEntity<String> entity = new HttpEntity<>(requestJsonString, headers);
60+
return restTemplate.postForObject(url, entity, responseClass);
61+
}
62+
63+
/**
64+
* 获取返回状态码
65+
*/
66+
public int postStatusCode(String url) {
67+
ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, null, String.class);
68+
return responseEntity.getStatusCode().value();
69+
}
70+
71+
72+
}

0 commit comments

Comments
 (0)