fix: 增加日记记录
This commit is contained in:
12
springboot/README.md
Normal file
12
springboot/README.md
Normal file
@@ -0,0 +1,12 @@
|
||||
这里是Springboot的学习笔记
|
||||
|
||||
* [定时任务](定时任务.md)
|
||||
* [返回数据全局统一](返回数据全局统一.md)
|
||||
* [热部署](热部署.md)
|
||||
* [文件上传](文件上传.md)
|
||||
* [chapter1](chapter1.md)
|
||||
* [chapter2](chapter2.md)
|
||||
* [chapter3](chapter3.md)
|
||||
* [chapter4-SpringMVC](chapter4-SpringMVC.md)
|
||||
* [chapter4-整合Mybatis](chapter5-整合MyBatis.md)
|
||||
* [lab1](lab1.md)
|
||||
10
springboot/_sidebar.md
Normal file
10
springboot/_sidebar.md
Normal file
@@ -0,0 +1,10 @@
|
||||
* [定时任务](定时任务.md)
|
||||
* [返回数据全局统一](返回数据全局统一.md)
|
||||
* [热部署](热部署.md)
|
||||
* [文件上传](文件上传.md)
|
||||
* [chapter1](chapter1.md)
|
||||
* [chapter2](chapter2.md)
|
||||
* [chapter3](chapter3.md)
|
||||
* [chapter4-SpringMVC](chapter4-SpringMVC.md)
|
||||
* [chapter4-整合Mybatis](chapter5-整合MyBatis.md)
|
||||
* [lab1](lab1.md)
|
||||
39
springboot/chapter1.md
Normal file
39
springboot/chapter1.md
Normal file
@@ -0,0 +1,39 @@
|
||||
## 目录说明
|
||||
```- src
|
||||
-main
|
||||
-java
|
||||
-package
|
||||
#主函数,启动类,运行它如果运行了 Tomcat、Jetty、Undertow 等容器
|
||||
-SpringbootApplication
|
||||
-resouces
|
||||
#存放静态资源 js/css/images 等
|
||||
- statics
|
||||
#存放 html 模板文件
|
||||
- templates
|
||||
#主要的配置文件,SpringBoot启动时候会自动加载application.yml/application.properties
|
||||
- application.yml
|
||||
#测试文件存放目录
|
||||
-test
|
||||
# pom.xml 文件是Maven构建的基础,里面包含了我们所依赖JAR和Plugin的信息
|
||||
- pom
|
||||
```
|
||||
|
||||
##注意
|
||||
- pom.xml中配置文件和程序的编码格式为utf-8
|
||||
|
||||
在<properties>标签中添加
|
||||
```
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
```
|
||||
|
||||
- 设置默认端口号和默认访问路径,在application.properties中配置
|
||||
```
|
||||
// 设置默认端口号
|
||||
server.port=8090
|
||||
// 设置根路径
|
||||
server.servlet.context-path=/xiao
|
||||
```
|
||||
|
||||
- 修改默认banner
|
||||
- 在resource目录下添加banner.txt、banner.jpg、banner.gif、banner.jpeg等文件即可
|
||||
77
springboot/chapter2.md
Normal file
77
springboot/chapter2.md
Normal file
@@ -0,0 +1,77 @@
|
||||
## 配置详解
|
||||
* 可以在任何Component中注入application.properties中的属性内容,格式为
|
||||
```
|
||||
@Value("${全名称}")
|
||||
```
|
||||
|
||||
* 如果想在编辑配置文件时有提示内容,可以在pom.xml中增加此依赖
|
||||
```
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
* 默认application.properties文件中增加属性内容后,注入到实体类,可以新建java类,通过下面的注解进行注入
|
||||
```
|
||||
// 声明该类为组件类,spring会自动注入到ApplicationContext中
|
||||
@Component
|
||||
// 声明当前类通过config文件注入属性,prefix为前缀为指定内容的属性会按照名称自动注入到类属性中
|
||||
@ConfigurationProperties(prefix = "snapswitch")
|
||||
```
|
||||
|
||||
* 自定义配置文件
|
||||
* 如果不想将所有配置都放在application.propeties中,可以自定义自己的配置文件,然后通过下面的注解,将类和属性文件关联
|
||||
```
|
||||
@Component
|
||||
@PropertySource("classpath:map.properties")
|
||||
@ConfigurationProperties(prefix = "map")
|
||||
```
|
||||
|
||||
* 可以在application.properties中配置当前环境名称,这样程序在读取配置时,会根据配置的环境名称自动读取对应的配置
|
||||
```
|
||||
# 当前使用环境,程序启动后会自动读取application-dev.properties的配置
|
||||
# 如果默认配置和dev配置存在相同的配置,则以dev为准
|
||||
# 如果dev存在而默认不环境存在,则以dev环境配置为准
|
||||
# 如果默认环境存在而dev环境不存在,则以默认环境配置为准
|
||||
spring.profiles.active=dev
|
||||
```
|
||||
|
||||
* 命令行打包程序,启动程序,指定参数启动
|
||||
* 打包命令,进入项目目录后,执行
|
||||
```
|
||||
mvn clean install
|
||||
mvn package
|
||||
```
|
||||
* 启动打包的jar
|
||||
|
||||
打包后的jar包会生成在target中,最终的jar文件就是可执行程序,在该jar文件所在目录执行
|
||||
```
|
||||
java -jar
|
||||
jar文件名 例如:chapter2-0.0.1-SNAPSHOT.jar
|
||||
[--参数 例如:--spring.profiles.active=test --my1.age=32]
|
||||
```
|
||||
|
||||
## 非常用参数
|
||||
|
||||
* 如果在配置文件中引用另外一个配置文件的值,也可以通过${参数名}的方式引用
|
||||
```
|
||||
app.name = appName
|
||||
app.newName = ${app.name}V1.0
|
||||
```
|
||||
此时app.newName的值即为appNameV1.0
|
||||
|
||||
* 如果需要在配置文件中使用随机数,可以通过此方式生成
|
||||
```
|
||||
# 随机字符串
|
||||
com.didispace.blog.value=${random.value}
|
||||
# 随机int
|
||||
com.didispace.blog.number=${random.int}
|
||||
# 随机long
|
||||
com.didispace.blog.bignumber=${random.long}
|
||||
# 10以内的随机数
|
||||
com.didispace.blog.test1=${random.int(10)}
|
||||
# 10-20的随机数
|
||||
com.didispace.blog.test2=${random.int[10,20]}
|
||||
```
|
||||
6
springboot/chapter3.md
Normal file
6
springboot/chapter3.md
Normal file
@@ -0,0 +1,6 @@
|
||||
## 日志配置
|
||||
* spring默认使用logback作为日志组件,logback默认输出INFO、WARN、ERROR
|
||||
,如果需要更多的日志级别输出,可以在application.properties中增加配置
|
||||
```
|
||||
debug=true
|
||||
```
|
||||
107
springboot/chapter4-SpringMVC.md
Normal file
107
springboot/chapter4-SpringMVC.md
Normal file
@@ -0,0 +1,107 @@
|
||||
## MVC设置
|
||||
* @Controller:修饰class,用来创建处理http请求的对象
|
||||
* @RestController:Spring4之后加入的注解,原来在@Controller中返回json需要@ResponseBody来配合,如果直接用@RestController替代@Controller就不需要再配置@ResponseBody,默认返回json格式。
|
||||
* @RequestMapping:配置url映射
|
||||
* value 请求路径 例如:@RequestMapping(value="/a/b"),则该方法对应的路径即为/a/b
|
||||
* **在请求中可以以Ant通配符的方式配置路径**,例如:@RequestMapping(value="/*/b") 表示a/b、c/b等各个请求均可以访问到该方法,而@RequestMapping(value="/\*\*/b")则表示1/2/b,3/4/b都可以访问到该方法,单个\*号表示任意字符通配符,两个星号代表任意路径通配符
|
||||
* @PathVariable("id") 配置rest请求中的可变路径参数
|
||||
* @ModelAttribute 配置参数对象,前端可通过传递对象中的属性值来填充该对象
|
||||
* @RequestParam 配置参数,对应名值对的形式
|
||||
* @RequestBody 配置请求参数,该数据一个请求只有一个,且请求类型不能为get类型
|
||||
|
||||
## Swagger2配置
|
||||
> 由于接口众多,并且细节复杂(需要考虑不同的HTTP请求类型、HTTP头部信息、HTTP请求内容等),高质量地创建这份文档本身就是件非常吃力的事,下游的抱怨声不绝于耳。
|
||||
随着时间推移,不断修改接口实现的时候都必须同步修改接口文档,而文档与代码又处于两个不同的媒介,除非有严格的管理机制,不然很容易导致不一致现象。
|
||||
为了解决上面这样的问题,本文将介绍RESTful API的重磅好伙伴Swagger2,它可以轻松的整合到Spring Boot中,并与Spring MVC程序配合组织出强大RESTful API文档。
|
||||
|
||||
> 简单来说,swagger就是用来自动生成Spring MVC文档的工具,接口开发完毕后,无需手动再修改接口文档,直接让客户端/前端人员查看swagger生成的文档即可。
|
||||
|
||||
- 首先在pom.xml中导入swagger2的依赖
|
||||
```
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>2.2.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger-ui</artifactId>
|
||||
<version>2.2.2</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
- 构建swagger的配置类
|
||||
|
||||
```
|
||||
/**
|
||||
* swagger的配置文件
|
||||
* */
|
||||
@Configuration
|
||||
@EnableSwagger2
|
||||
public class SwaggerConfig {
|
||||
@Value("${baseUrl}")
|
||||
private String baseUrl;
|
||||
|
||||
@Bean
|
||||
public Docket createRestRequestApi(){
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
// 配置ApiInfo,级当前应用的基本信息
|
||||
.apiInfo(getAppInfo())
|
||||
// 生成DocketBuilder
|
||||
.select()
|
||||
// 指定api类生成的包名,swagger会自动扫描指定包下的所有类,生成说明文档
|
||||
.apis(RequestHandlerSelectors.basePackage("com.xiaoxiao.springboot2.controller"))
|
||||
// 指定实现了RestController接口的类,生成说明文档
|
||||
.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
|
||||
// 路径过滤规则,多数情况下不需要过滤
|
||||
.paths(PathSelectors.any())
|
||||
.build();
|
||||
}
|
||||
|
||||
private ApiInfo getAppInfo(){
|
||||
return new ApiInfoBuilder()
|
||||
.title("api文档")
|
||||
.description("小小的api文档说明")
|
||||
.contact(new Contact("xiaoxiao", null, "xiaoyan159@163.com"))
|
||||
.version("V0.1")
|
||||
.termsOfServiceUrl(baseUrl)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
```
|
||||
> 注意:上面Docket的apis方法只有一个会生效,因此如果需要扫描不同包的controller的类及方法,可使用withClassAnnotation方式
|
||||
|
||||
此刻直接访问localhost:8080/swagger-ui.html,即可看到自动生成的说明文档,但是这些说明文档是自动生成的,可读性不高,可通过在controller上增加注解的方式提高文档可读性
|
||||
```
|
||||
@ApiImplicitParams(
|
||||
@ApiImplicitParam(name = "user", dataType = "User", allowEmptyValue = false, required = true)
|
||||
)
|
||||
@ApiOperation(value = "打印snapSwitch配置信息", notes = "注意:")
|
||||
```
|
||||
|
||||
* 访问静态资源(图片、音频等文件)
|
||||
> springboot中访问静态资源,是按照如下顺序寻找的
|
||||
> * classpath:/META-INF/resources/
|
||||
> * classpath:/resources/
|
||||
> * classpath:/static/
|
||||
> * classpath:/public/
|
||||
> * /
|
||||
>
|
||||
> 如果需要自定义静态资源位置,可以在application.properties中增加配置
|
||||
> * spring.resources.static-locations=classpath:/
|
||||
> * spring.mvc.static-path-pattern=/**
|
||||
|
||||
* 关于跨域
|
||||
|
||||
解决跨域问题,springboot中可以通过两种方式:
|
||||
1. 在请求上添加注解@CrossOrigin(value ="http://localhost:8081")
|
||||
2. 通过下面的代码
|
||||
```java
|
||||
@Configuration
|
||||
public class WebMvcConfig implements WebMvcConfigurer{
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**").allowedOrigins("http://localhost:8081").allowedMethods("*").allowedHeaders("*");
|
||||
}
|
||||
}
|
||||
```
|
||||
44
springboot/chapter5-整合MyBatis.md
Normal file
44
springboot/chapter5-整合MyBatis.md
Normal file
@@ -0,0 +1,44 @@
|
||||
## 整合MyBatis
|
||||
- 首先在pom.xml中配置mybatis的依赖,MySql连接库
|
||||
```
|
||||
<!--mybatis依赖-->
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>1.3.2</version>
|
||||
</dependency>
|
||||
|
||||
<!--mysql连接-->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
- 然后在application.properties中添加数据库连接配置
|
||||
```
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/springboot2Test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
|
||||
spring.datasource.password=root
|
||||
spring.datasource.username=xiaoyan159
|
||||
# 注意注意
|
||||
mybatis.mapper-locations=classpath:com/xiaoxiao/springboot2/dao/*.xml
|
||||
#mybatis.mapper-locations=classpath:mapper/*.xml #这种方式需要自己在resources目录下创建mapper目录然后存放xml
|
||||
mybatis.type-aliases-package=com.xiaoxiao.springboot2.pojo #这里配置mybatis中别名自动生成的包名
|
||||
# 驼峰命名规范 如:数据库字段是 order_id 那么 实体字段就要写成 orderId
|
||||
mybatis.configuration.map-underscore-to-camel-case=true
|
||||
```
|
||||
|
||||
> 注意! 如果配置的mybatis.mapper-locations同dao包一致,在打包时默认可能不会将xml文件打包进jar中,需要在pom.xml文件中特殊声明
|
||||
```
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/java</directory>
|
||||
<includes>
|
||||
<include>**/*.xml</include>
|
||||
</includes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
```
|
||||
17
springboot/lab1.md
Normal file
17
springboot/lab1.md
Normal file
@@ -0,0 +1,17 @@
|
||||
## spring-security
|
||||
1. 首先在pom文件中增加依赖
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
2. 可选项,在application.yml文件中配置默认的用户名密码
|
||||
```yaml
|
||||
spring:
|
||||
security:
|
||||
user:
|
||||
name: xiaoyan159
|
||||
password: xiaoyan159062
|
||||
roles: admin
|
||||
```
|
||||
46
springboot/定时任务.md
Normal file
46
springboot/定时任务.md
Normal file
@@ -0,0 +1,46 @@
|
||||
## 定时任务
|
||||
|
||||
### spring自带定时任务Scheduled
|
||||
* 首先在SpringBootApplication上添加启动定时任务的注解@EnableScheduling
|
||||
* 然后编写定时任务,定时任务的类需要是一个@Component,需要spring可以扫描到该组件
|
||||
* 首先使用 @Scheduled 注解开启一个定时任务。
|
||||
* fixedRate 表示任务执行之间的时间间隔,具体是指两次任务的开始时间间隔,即第二次任务开始时,第一次任务可能还没结束。
|
||||
* fixedDelay 表示任务执行之间的时间间隔,具体是指本次任务结束到下次任务开始之间的时间间隔。
|
||||
* initialDelay 表示首次任务启动的延迟时间。
|
||||
* 所有时间的单位都是毫秒。
|
||||
|
||||
* 上面这是一个基本用法,除了这几个基本属性之外,@Scheduled 注解也支持 cron 表达式,使用 cron 表达式,可以非常丰富的描述定时任务的时间。cron 表达式格式如下:
|
||||
> \[秒\] \[分\] \[小时\] \[日\] \[月\] \[周\] \[年\]
|
||||
|
||||
|序号|说明|是否必填|允许填写的值|允许的通配符|
|
||||
|:---:|:---:|:---:|:---:|:---:|
|
||||
|1| 秒| 是| 0-59| - * /|
|
||||
|2| 分| 是| 0-59| - * /|
|
||||
|3| 时| 是| 0-23| - * /|
|
||||
|4| 日| 是| 1-31| - * ? / L W|
|
||||
|5| 月| 是| 1-12| or JAN-DEC - * /|
|
||||
|6| 周| 是| 1-7| or SUN-SAT - * ? / L #|
|
||||
|7| 年| 否| 1970-2099| - * /|
|
||||
|
||||
```
|
||||
? 表示不指定值,即不关心某个字段的取值时使用。需要注意的是,月份中的日期和星期可能会起冲突,因此在配置时这两个得有一个是 ?
|
||||
|
||||
* 表示所有值,例如:在秒的字段上设置 *,表示每一秒都会触发
|
||||
|
||||
, 用来分开多个值,例如在周字段上设置 "MON,WED,FRI" 表示周一,周三和周五触发
|
||||
|
||||
- 表示区间,例如在秒上设置 "10-12",表示 10,11,12秒都会触发
|
||||
|
||||
/ 用于递增触发,如在秒上面设置"5/15" 表示从5秒开始,每增15秒触发(5,20,35,50)
|
||||
|
||||
# 序号(表示每月的第几个周几),例如在周字段上设置"6#3"表示在每月的第三个周六,(用 在母亲节和父亲节再合适不过了)
|
||||
|
||||
周字段的设置,若使用英文字母是不区分大小写的 ,即 MON 与mon相同
|
||||
|
||||
L 表示最后的意思。在日字段设置上,表示当月的最后一天(依据当前月份,如果是二月还会自动判断是否是润年), 在周字段上表示星期六,相当于"7"或"SAT"(注意周日算是第一天)。如果在"L"前加上数字,则表示该数据的最后一个。例如在周字段上设置"6L"这样的格式,则表示"本月最后一个星期五"
|
||||
|
||||
W 表示离指定日期的最近工作日(周一至周五),例如在日字段上设置"15W",表示离每月15号最近的那个工作日触发。如果15号正好是周六,则找最近的周五(14号)触发, 如果15号是周未,则找最近的下周一(16号)触发,如果15号正好在工作日(周一至周五),则就在该天触发。如果指定格式为 "1W",它则表示每月1号往后最近的工作日触发。如果1号正是周六,则将在3号下周一触发。(注,"W"前只能设置具体的数字,不允许区间"-")
|
||||
|
||||
L 和 W 可以一组合使用。如果在日字段上设置"LW",则表示在本月的最后一个工作日触发(一般指发工资 )
|
||||
```
|
||||
|
||||
66
springboot/整合druid数据源.md
Normal file
66
springboot/整合druid数据源.md
Normal file
@@ -0,0 +1,66 @@
|
||||
## 整合druid数据源
|
||||
* 此处使用yml格式配置
|
||||
```
|
||||
spring:
|
||||
profiles:
|
||||
active: dev
|
||||
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
druid:
|
||||
url: jdbc:mysql://localhost:3306/springboot2Test?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=UTC
|
||||
username: root
|
||||
password: xiaoyan159
|
||||
# 连接池初始化连接数
|
||||
initial-size: 5
|
||||
# 连接不够时新增连接数
|
||||
min-idle: 5
|
||||
# 连接池最大连接数
|
||||
max-active: 30
|
||||
# 最大等待时间
|
||||
max-wait: 30000
|
||||
# 配置检测可以关闭的空闲连接间隔时间
|
||||
time-between-eviction-runs-millis: 60000
|
||||
# 配置连接在池中的最小生存时间
|
||||
min-evictable-idle-time-millis: 300000
|
||||
validation-query: select '1' from dual
|
||||
test-while-idle: true
|
||||
test-on-borrow: false
|
||||
test-on-return: false
|
||||
# 打开PSCache,并且指定每个连接上PSCache的大小
|
||||
pool-prepared-statements: true
|
||||
max-open-prepared-statements: 30
|
||||
max-pool-prepared-statement-per-connection-size: 30
|
||||
# 配置监控统计拦截的filters, 去掉后监控界面sql无法统计, 'wall'用于防火墙
|
||||
filters: stat,wall
|
||||
# Spring监控AOP切入点,如x.y.z.service.*,配置多个英文逗号分隔
|
||||
aop-patterns: com.xiaoxiao.springboot2.servie.*
|
||||
|
||||
# WebStatFilter配置
|
||||
web-stat-filter:
|
||||
enabled: true
|
||||
# 添加过滤规则
|
||||
url-pattern: /*
|
||||
# 忽略过滤的格式
|
||||
exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'
|
||||
|
||||
# StatViewServlet配置
|
||||
stat-view-servlet:
|
||||
enabled: true
|
||||
# 访问路径为/druid时,跳转到StatViewServlet
|
||||
url-pattern: /druid/*
|
||||
# 是否能够重置数据
|
||||
reset-enable: false
|
||||
# 需要账号密码才能访问控制台
|
||||
login-username: druid
|
||||
login-password: druid123
|
||||
# IP白名单
|
||||
# allow: 127.0.0.1
|
||||
# IP黑名单(共同存在时,deny优先于allow)
|
||||
# deny: 192.168.1.218
|
||||
|
||||
# 配置StatFilter
|
||||
filter:
|
||||
stat:
|
||||
log-slow-sql: true
|
||||
```
|
||||
72
springboot/文件上传.md
Normal file
72
springboot/文件上传.md
Normal file
@@ -0,0 +1,72 @@
|
||||
## 文件上传
|
||||
* 首先介绍静态资源文件夹,springboot中默认的静态资源文件目录
|
||||
,从上到下共5个,当我们请求静态资源时,spring会按照配置寻找指定
|
||||
资源,我们可以在application配置文件中配置静态资源文件夹
|
||||
```yaml
|
||||
spring:
|
||||
resources:
|
||||
static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,classpath:/,file:./upload/
|
||||
|
||||
mvc:
|
||||
static-path-pattern: /** # 此配置使用Ant语法,说明自动匹配/路径及其子路径
|
||||
```
|
||||
|
||||
* 文件上传建议上传到resources静态资源目录下,我们可以通过此方法,获取到当前程序运行的文件目录
|
||||
```java
|
||||
public class PathUtils {
|
||||
public static String getResourceBasePath() {
|
||||
// 获取跟目录
|
||||
File path = null;
|
||||
try {
|
||||
path = new File(ResourceUtils.getURL("classpath:").getPath());
|
||||
} catch (FileNotFoundException e) {
|
||||
// nothing to do
|
||||
}
|
||||
if (path == null || !path.exists()) {
|
||||
path = new File("");
|
||||
}
|
||||
|
||||
String pathStr = path.getAbsolutePath();
|
||||
// 如果是在eclipse中运行,则和target同级目录,如果是jar部署到服务器,则默认和jar包同级
|
||||
pathStr = pathStr.replace("\\target\\classes", "");
|
||||
|
||||
return pathStr;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* 如果需要控制上传文件的大小,可以在application.yml中配置
|
||||
```yaml
|
||||
spring:
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 1024MB
|
||||
max-request-size: 1024MB
|
||||
```
|
||||
|
||||
* 然后在Controller中增加上传文件接口即可
|
||||
|
||||
```java
|
||||
@RestController
|
||||
@RequestMapping("/upload")
|
||||
public class FileUploadController {
|
||||
@RequestMapping("/single")
|
||||
public boolean uploadSingleFile(@RequestParam("file")/*此处注解应该也可以使用RequestBody*/ MultipartFile file/*上传文件均通过该参数获取即可*/){
|
||||
if (file == null || file.getSize()<=0){
|
||||
throw new ServiceException(ServiceException.ServiceExceptionEnum.FILE_IS_EMPTY);
|
||||
}
|
||||
try {
|
||||
File destFolder = new File(PathUtils.getResourceBasePath(),"/upload");
|
||||
if (!destFolder.exists()||!destFolder.isDirectory()){
|
||||
destFolder.mkdirs();
|
||||
}
|
||||
// MultipartFile提供transferTo的工具方法,可以将文件直接复制到指定位置
|
||||
file.transferTo(new File(destFolder.getAbsolutePath()+"/"+file.getOriginalFilename()));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
```
|
||||
10
springboot/热部署.md
Normal file
10
springboot/热部署.md
Normal file
@@ -0,0 +1,10 @@
|
||||
## 热部署
|
||||
* 首先在pom.xml中增加配置
|
||||
```
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<optional>true</optional> <!-- 可选 -->
|
||||
</dependency>
|
||||
```
|
||||
|
||||
203
springboot/返回数据全局统一.md
Normal file
203
springboot/返回数据全局统一.md
Normal file
@@ -0,0 +1,203 @@
|
||||
## 返回数据全局统一
|
||||
* 首先定义格式化数据实体类
|
||||
```
|
||||
public class CommonResult<T> implements Serializable {
|
||||
public static Integer CODE_SUCCESS = 0;
|
||||
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
private Integer code;
|
||||
/**
|
||||
* 错误提示
|
||||
*/
|
||||
private String message;
|
||||
/**
|
||||
* 返回数据
|
||||
*/
|
||||
private T data;
|
||||
|
||||
/**
|
||||
* 将传入的 result 对象,转换成另外一个泛型结果的对象
|
||||
*
|
||||
* 因为 A 方法返回的 CommonResult 对象,不满足调用其的 B 方法的返回,所以需要进行转换。
|
||||
*
|
||||
* @param result 传入的 result 对象
|
||||
* @param <T> 返回的泛型
|
||||
* @return 新的 CommonResult 对象
|
||||
*/
|
||||
public static <T> CommonResult<T> error(CommonResult<?> result) {
|
||||
return error(result.getCode(), result.getMessage());
|
||||
}
|
||||
|
||||
public static <T> CommonResult<T> error(Integer code, String message) {
|
||||
Assert.isTrue(!CODE_SUCCESS.equals(code), "code 必须是错误的!");
|
||||
CommonResult<T> result = new CommonResult<>();
|
||||
result.code = code;
|
||||
result.message = message;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T> CommonResult<T> success(T data) {
|
||||
CommonResult<T> result = new CommonResult<>();
|
||||
result.code = CODE_SUCCESS;
|
||||
result.data = data;
|
||||
result.message = "";
|
||||
return result;
|
||||
}
|
||||
|
||||
@JsonIgnore // 忽略,避免 jackson 序列化给前端
|
||||
public boolean isSuccess() { // 方便判断是否成功
|
||||
return CODE_SUCCESS.equals(code);
|
||||
}
|
||||
|
||||
@JsonIgnore // 忽略,避免 jackson 序列化给前端
|
||||
public boolean isError() { // 方便判断是否失败
|
||||
return !isSuccess();
|
||||
}
|
||||
|
||||
public static Integer getCodeSuccess() {
|
||||
return CODE_SUCCESS;
|
||||
}
|
||||
|
||||
public static void setCodeSuccess(Integer codeSuccess) {
|
||||
CODE_SUCCESS = codeSuccess;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(Integer code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
public class ServiceException extends RuntimeException{
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
private final Integer code;
|
||||
|
||||
public ServiceException(ServiceExceptionEnum serviceExceptionEnum) {
|
||||
// 使用父类的 message 字段
|
||||
super(serviceExceptionEnum.getMessage());
|
||||
// 设置错误码
|
||||
this.code = serviceExceptionEnum.getCode();
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
// ServiceExceptionEnum.java
|
||||
|
||||
public enum ServiceExceptionEnum {
|
||||
|
||||
// ========== 系统级别 ==========
|
||||
SUCCESS(0, "成功"),
|
||||
SYS_ERROR(2001001000, "服务端发生异常"),
|
||||
MISSING_REQUEST_PARAM_ERROR(2001001001, "参数缺失"),
|
||||
|
||||
// ========== 用户模块 ==========
|
||||
USER_NOT_FOUND(1001002000, "用户不存在"),
|
||||
|
||||
// ========== 订单模块 ==========
|
||||
|
||||
// ========== 商品模块 ==========
|
||||
;
|
||||
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
private int code;
|
||||
/**
|
||||
* 错误提示
|
||||
*/
|
||||
private String message;
|
||||
|
||||
ServiceExceptionEnum(int code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* 然后通过@RestControllerAdvice(basePackages = {"com.xiaoxiao.springboot2.controller"})拦截controller的返回response,统一处理返回值
|
||||
```
|
||||
// 此处增加basePackages配置,只拦截自有controller的返回值,不影响druid以及swagger的页面正常显示
|
||||
@RestControllerAdvice(basePackages = {"com.xiaoxiao.springboot2.controller"})
|
||||
public class CommonResultControllerAdvice implements ResponseBodyAdvice {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Override
|
||||
public boolean supports(MethodParameter methodParameter, Class aClass) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
|
||||
if (o instanceof CommonResult){
|
||||
return o;
|
||||
}
|
||||
return CommonResult.success(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理业务异常
|
||||
* */
|
||||
@ExceptionHandler(value = ServiceException.class)
|
||||
public CommonResult serviceExceptionHandler(HttpServletRequest req, ServiceException ex){
|
||||
return CommonResult.error(ex.getCode(),ex.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理其他异常
|
||||
* */
|
||||
@ExceptionHandler(value = Exception.class)
|
||||
public CommonResult exceptionHandler(HttpServletRequest req, Exception e) {
|
||||
// 记录异常日志
|
||||
logger.error("[exceptionHandler]", e);
|
||||
// 返回 ERROR CommonResult
|
||||
return CommonResult.error(ServiceException.ServiceExceptionEnum.SYS_ERROR.getCode(),
|
||||
ServiceException.ServiceExceptionEnum.SYS_ERROR.getMessage());
|
||||
}
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user