上篇文章介绍了在 Spring Boot中如何使用拦截器、过滤器、监听器以及事件监听。本篇文章将简单、大概的介绍spring boot的其他特性。
Web 开发
1. json 接口开发
1). 在Spring环境中开发项目,需要提供 json 接口时需要做哪些配置呢?
- 添加 jackjson 等相关 jar 包
- 配置 Spring Controller 扫描
- 对接的方法添加 @ResponseBody
2). Spring Boot 如何做呢,只需要类添加 @RestController
即可,默认类中的方法都会以 json 的格式返回
@RestController
public class TestController {
@RequestMapping("test")
public String test(String phone) {
return "json格式响应";
}
}
如果需要使用页面开发只要使用@Controller
注解即可
2. Spring Boot(二):拦截器、过滤器、监听器、事件监听
3. 自定义 Property配置文件
在 Web 开发的过程中,我经常需要自定义一些配置文件,如何使用呢?
在src/main/resources目录下配置application.properties 中
com.reyco.name=不哭死神
com.reyco.title=Spring boot Web开发
自定义配置类
@Component
public class ReycoProperties {
@Value("${com.reyco.name}")
private String name;
@Value("${com.reyco.title}")
private String title;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
4. log配置
## log输出地址
logging.path=/logs/log/
## 日志文件名
logging.file=erp.log
## 不同资源输出级别
logging.level.root=info
logging.level.com.aqkc.erp.core=debug
logging.level.com.favorites=DEBUG
logging.level.org.springframework.web=DEBUG
5. 数据库配置
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
添加相关依赖...
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
6. 文件上传
1). springboot默认文件上传大小为1MB,超过1MB会报错:
Caused by: java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field file exceeds its maximum permitted size of 1048576 bytes.
2). 修改spring boot默认文件上传大小
第一种方式:在application.properties中配置spring boot文件上传大小
spring.servlet.multipart.enabled = true
## 单个文件的最大上限
spring.servlet.multipart.max-file-size=10MB
## 单个请求的总大小上限
spring.servlet.multipart.max-request-size=100MB
第二种方式:添加bean的方式修改spring boot默认文件上传大小
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
//单个文件最大
factory.setMaxFileSize("10240KB"); //KB,MB
/// 设置总上传数据总大小
factory.setMaxRequestSize("102400KB");
return factory.createMultipartConfig();
}
}
3). 文件上传
@RestController
public class FileController {
@RequestMapping("/upload")
public String upload(MultipartFile file ) throws IllegalStateException, IOException {
file.transferTo(new File("D:/upload/"+file.getOriginalFilename()));
return "ok";
}
}
7. 静态资源
1). SpringBoot 从 classpath/static 的目录
注意目录名称必须是 static
2). SpringBoot 从 ServletContext 根目录下
在 src/main/webapp 目录名称必须要 webapp
8. 跨域支持
1). 第一种解决方案
实现WebMvcConfigurer接口,实现addCorsMappings方式
@SpringBootConfiguration
public class CorsConfig implements WebMvcConfigurer{
/**
* 跨域
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowCredentials(true)
.allowedHeaders("*")
.allowedOrigins("*")
.allowedMethods("GET", "PUT", "DELETE", "POST", "OPTIONS")
.maxAge(3600);
}
}
2). 第二种解决方案
注册bean的方式解决跨域问题,
@SpringBootApplication
public class ReycoApplication {
public static void main(String[] args) {
SpringApplication.run(ReycoApplication.class, args);
}
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.setMaxAge(3600);
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
9. 异常处理
SpringBoot 中对于异常处理提供了五种处理方式
1). 自定义错误页面
SpringBoot 默认的处理异常的机制:SpringBoot 默认的已经提供了一套处理异常的机制。
一旦程序中出现了异常 SpringBoot 会像/error 的 url 发送请求。在 springBoot 中提供了一个
叫 BasicExceptionController 来处理/error 请求,然后跳转到默认显示异常的页面来展示异常
信息。
如 果 我 们 需 要 将 所 有 的 异 常 同 一 跳 转 到 自 定 义 的 错 误 页 面 , 首先需要在src/main/resources/ 目录下创建 resources或者static或者public的folder。然后在目录下创建error的folder,folder名称必须叫error,最后在error下创建4xx.html和5xx.html页面。
4xx.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
你访问的资源不存在,请联系管理员。。。。
</body>
</html>
5xx.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
出错了,请联系管理员。。。。
</body>
</html>
当访问服务器不存在的资源时会跳转到4xx.html下,当我们的服务器发生异常的时候会跳转到5xx.html页面。
访问不存在资源:
访问异常:
2). @ExceptionHandle 注解处理异常
在error目录下创建error1.html和error2.html
页面内容如下:
error1.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
NullPointerException 出错了,请联系管理员。。。。
</body>
</html>
error2.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
ArithmeticException 出错了,请联系管理员。。。。
</body>
</html>
在Controller中发生了异常,会根据异常类型跳转到指定的错误页面,如果当前异常类型没有定义对应的异常处理,会默认走我们的自定义错误页面
@RestController
public class ExceptionController {
@RequestMapping("error1")
public String error1() {
String a = null ;
a.length();
return "test1";
}
@RequestMapping("error2")
public String error2() {
int a = 1/0;
return "test2";
}
@ExceptionHandler(NullPointerException.class)
public ModelAndView nullPointerException(Exception e) {
ModelAndView model = new ModelAndView();
model.addObject("error",e.toString());
model.setViewName("/error/error1.html");
return model;
}
@ExceptionHandler(ArithmeticException.class)
public ModelAndView ArithmeticException(Exception e) {
ModelAndView model = new ModelAndView();
model.addObject("error",e.toString());
model.setViewName("/error/error2.html");
return model;
}
}
访问错误 error1
访问错误 error2
3). @ControllerAdvice+@ExceptionHandler 注解处理异常
需要创建一个能够处理异常的全局异常类。在该类上需要添加@ControllerAdvice 注解
/**
* 全局异常处理
* @author reyco
*
*/
@ControllerAdvice
public class GlobalDefultExceptionHandler {
protected Logger logger = LoggerFactory.getLogger(getClass());
/**
* 声明要捕获的异常
* @param reuqest
* @param response
* @param ex
* @return
*/
@ExceptionHandler(NullPointerException.class)
public ModelAndView defultExcepitonHandler(HttpServletRequest reuqest,HttpServletResponse response,Exception ex) {
ex.printStackTrace();
ModelAndView mv = new ModelAndView();
mv.addObject("error",ex.toString());
mv.setViewName("/error/error1.html");
return mv;
}
/**
* 声明要捕获的异常
* @param e
* @return
*/
@ExceptionHandler(ArithmeticException.class)
public ModelAndView ArithmeticException(Exception e) {
ModelAndView model = new ModelAndView();
model.addObject("error",e.toString());
model.setViewName("/error/error2.html");
return model;
}
}
在(@ExceptionHandle 注解处理异常 )的错误页面保留,当发生异常就会跳转到指定的错误页面。
4). 配置 SimpleMappingExceptionResolver 处理异常
/**
* 通过 SimpleMappingExceptionResolver 做全局异常处理
* @author reyco
*/
@Configuration
public class GlobalDefultExceptionHandler {
protected Logger logger = LoggerFactory.getLogger(getClass());
/**
* 该方法必须要有返回值。返回值类型必须是: SimpleMappingExceptionResolver
* @return
*/
@Bean
public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
/**
* 参数一:异常的类型,注意必须是异常类型的全名 *
* 参数二:视图名称
*/
Properties mappings = new Properties();
mappings.put("java.lang.NullPointerException", "/error/error1.html");
mappings.put("java.lang.ArithmeticException", "/error/error2.html");
resolver.setExceptionMappings(mappings);
return resolver;
}
}
在(@ExceptionHandle 注解处理异常 )的错误页面保留,当发生异常就会跳转到指定的错误页面。
5). 自定义 HandlerExceptionResolver 类处理异常
/**
* 通过实现 HandlerExceptionResolver 接口做全局异常处理
* @author reyco
*/
@Configuration
public class GlobalDefultExceptionHandler implements HandlerExceptionResolver{
protected Logger logger = LoggerFactory.getLogger(getClass());
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) {
ModelAndView mv = new ModelAndView();
mv.addObject("error",ex.toString());
//判断不同异常类型,做不同视图跳转
if(ex instanceof NullPointerException) {
mv.setViewName("/error/error1.html");
}else if(ex instanceof ArithmeticException) {
mv.setViewName("/error/error2.html");
}
return mv;
}
}
10. DevTools 工具
1). SpringLoader 与 DevTools 的区别:
SpringLoader:SpringLoader 在部署项目时使用的是热部署的方式。
DevTools:DevTools 在部署项目时使用的是重新部署的方式
2). 添加 DevTools依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>