@ControllerAdvice 这个注解呢不能说时springBoot的,它是springMVC的一个注解,只不过功能用途是一模一样的。
@ControllerAdvice 的三种用途:
- 处理全局异常
- 预设全局数据
- 请求参数预处理
一、处理全局异常:
下面是代码实例:文件上传,文件过大的异常
/**
* 单文件上传
*
* @param file
* @param request
* @return
*/
@PostMapping("/oneUpload")
@ResponseBody
public String oneUploadFile(MultipartFile file, HttpServletRequest request) {
String path = "F://图片/img/";
String data = sft.format(new Date());
String fileName = file.getOriginalFilename();
String lastStr = fileName.substring(fileName.lastIndexOf("."));
if (".txt".equals(lastStr)) {
return "文件格式不正确";
}
;
File file1 = new File(path + data);
if (!file1.exists()) {
file1.mkdirs();
}
String newName = UUID.randomUUID().toString().replace("-", "") + fileName;
try {
file.transferTo(new File(file1, newName));
String url = path + data + "/" + newName;
return url;
} catch (IOException e) {
e.printStackTrace();
}
//文件存储路径
return "error";
}
前端页面:
<form action="/upload/oneUpload" method="post" enctype="multipart/form-data">
<input type="file" id="upload" name="file">
<input type="submit" value="提交">
</form>
并且我把配置文件application.properties 文件大小改为了1kb
#=========================文件上传大小控制 ===================
spring.servlet.multipart.max-file-size=1kb
启动项目上传文件后出现的异常,可读性很不友好的来定制异常信息。
这下你就可以自定义一个来处理异常的类并且用@ControllerAdvice
/**
* 异常处理
*
* @author
*/
@ControllerAdvice
public class MyException {
//在这个注解里面 可以指定异常还可以指定父级异常所有异常都捕获。
@ExceptionHandler(MaxUploadSizeExceededException.class)
public void myException(HttpServletResponse response) throws IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write("上传文件过大");
writer.flush();
writer.close();
}
}
测试结果如下:
你还可以返回一个ModelAndView 返回一个异常页面。
@ExceptionHandler(MaxUploadSizeExceededException.class)
public ModelAndView myException() throws IOException {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("myError");
modelAndView.addObject("error", "文件上传失败");
return modelAndView;
}
下面的异常页面我使用thymeleaf 模板引擎来做的。
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1 th:text="${error}"> </h1>
</body>
</html>
结果如下:
二、预设全局数据
通过这个注解@ControllerAdvice 设置的数据 在任何一个Controller中都可以获取的到。
直接上代码了
/**
* 预设全局数据
*
* @author
*/
@ControllerAdvice
public class GlobalData {
/**
* 这个里的 info 可以随意设置 就相当于一个变量的名字 取数据的时候
* 可以根据这变量来获取 设置的值
*
* @return
*/
@ModelAttribute(value = "info")
public Map<String, Object> info() {
HashMap<String, Object> map = new HashMap<>();
map.put("name", "邢小白");
return map;
}
}
在项目任意Controller 中取出info 步骤:
/**
* 取出预设全局数据
*
* @author
*/
@Controller
public class GlobalDataController {
@RequestMapping("/info")
@ResponseBody
public Object getGlobalData(Model model) {
Map<String, Object> map = model.asMap();
for (String key : map.keySet()) {
System.out.println(key + ":" + map.get(key));
}
return map.get("info");
}
}
结果如下:也是一个map 对象
info:{name=邢小白}
三、请求参数预处理
如果两个类有一个属性名称相同,那springMvc 时怎样映射封装呢
代码如下:
实体类:用的lombak插件 解决了写get \set 和toString() 方法
@Data
public class Book {
private String name;
private double price;
}
@Data
public class Author {
private String name;
private Integer age;
}
Controller
@Controller
public class BookController{
@PostMapping("/book")
@ResponseBody
public String book(Book book, Author author ){
System.out.println(book);
System.out.println(author);
return "22";
}
}
Postman工具调用接口:
结果如下:springMvc 也分不清那个是哪个, 会把两个相同属性的字段,映射封装到一个字段中。
Book(name=西游记,吴承恩, price=100.0)
Author(name=西游记,吴承恩, age=19)
解决方案:@ControllerAdvice
@ControllerAdvice
public class GlobalData {
@InitBinder("a")
public void initA(WebDataBinder dataBinder) {
//设置默认的前缀
dataBinder.setFieldDefaultPrefix("a.");
}
@InitBinder("b")
public void initAB(WebDataBinder dataBinder) {
//设置默认的前缀
dataBinder.setFieldDefaultPrefix("b.");
}
}
Controller
@PostMapping("/book")
@ResponseBody
public String book(@ModelAttribute("b") Book book, @ModelAttribute("a") Author author ){
System.out.println(book);
System.out.println(author);
return "22";
}
Postman调用请求也会相应的改变:
感言致辞:
也还是那句话写这些东西呢 也算是一个总结记录以后遇到相对应的问题,也好解决,也希望学习一门技术有可能不能实践,两个星期就还回去了,觉得自己总结描述太差,想锻炼以下自己的书写能力。