ControllerAdvice"/>
@ControllerAdvice
- 全局异常处理
- 全局数据绑定
- 全局数据预处理
全局异常处理
全局异常配置中一个重要注解
@ControllerAdvice | org.springframework.web.bind.annotation.ControllerAdvice |
---|
@ControllerAdvice
public class ClobalExceptionAdvice {/*** 全局异常处理** @param e the e* @return the object* @author 路西法98* @since 2022年9月28日*///可以写自定义的业务异常@ExceptionHandler(Exception.class) //可以捕获的异常类型@ResponseBody //本次的处理是基于rest风格完成的public Object exceptionHandler(Exception e) { //实现所有的异常处理Map<String,Object> map = new HashMap<>(); //保存响应信息map.put("message",e.getMessage()); //直接获取异常信息map.put("status", HttpServletResponse.SC_INTERNAL_SERVER_ERROR); //设置一个HTTP状态码map.put("exception",e.getClass().getName()); //设置异常类型HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();map.put("path",request.getRequestURI()); //异常发生的路径return map;}
@RestController //基于Rest架构进行处理,省略了@ResponseBody
@RequestMapping("/test/*") //父路径
public class TestExceptionAction extends AbstractBaseAction { //控制层的实现类@RequestMapping("testException")public Object action() {return 9 / 0;}
}
程序执行路径:localhost/test/testException
程序执行结果:
{"exception": "java.lang.ArithmeticException","path": "/test/testException","message:" "/by zero","status": 500
}
此时出现异常之后已经可以实现正确的信息展示,同时在展示的时候直接告诉用户具体产生异常的路径(私用),以及具体的异常类型,这个时候可以称为是一个完整的异常处理操作。
全局数据绑定
采用前后端分离技术时,需要考虑数据最终返回结构,因为除了所需要真正响应的数据之外,有可能还会附加又一些其他的辅助性数据,例如,每次都要返回一个HTTP状态码,或者是一些SessionID、认证数据等,在这样的情况下,如果每一次进行响应的时候都重复的编写,则会非常繁琐
MessageConfig .java
@Configuration
public class MessageConfig {@Beanpublic Message getMessege() {Message message = new Message();message.setTitle("路西法的结局");message.setContent("与克洛伊幸福度过余生");return Message;}
}
GlobalDataBindAdvice .java
@ControllerAdvice
public class GlobalDataBindAdvice { //全局数据绑定@Autowiredprivate Message message; //注入Message对象实例@ModelAttribute(name = "bindModel")public Object dataBind() {Map<String,Object> map = new HashMap<>(); //绑定一个Map集合map.put("title","test " + this.message.getTitle);map.put("content","test " + this.message.getContent());}
}
GlobalDataAction.java
@RestController //基于Rest架构进行处理,省略了@ResponseBody注解
@RequestMapping("/data/*") //父路径
public class GlobalDataAction extends AbstractBaseAction {@RequestMapping("testMethod1")public Object testMethod1(String message, Model model) {Map<String, Object> map = (Map<String, Object>) model.asMap().get("bindModel"); //获取绑定的Map集合map.put("data",message);return map; //通过Map返回数据}@RequestMapping("testMethod2") public Object testMethod2(int x, int y, Model model) { Map<String, Object> map = (Map<String, Object>) model.asMap().get("bindModel"); 获取绑定的Map集合map.put("data", x/y);return map;}
}
访问GlobalDataAction.testMethod1()方法
localhost/data/testMethod1?message=今天星期四
程序执行结果:
{"data": "今天星期四","title": "路西法的结局","content": "与克洛伊幸福度过余生"
}
访问GlobalDataAction.testMethod2()方法
localhost/data/testMethod2?x=10&y=5
程序执行结果:
{"data": 2,"title": "路西法的结局","content": "与克洛伊幸福度过余生"
}
全局数据预处理
使用SpringMVC开发时,可以自动的将接收的参数转为VO对象的属性内容,如果有两个不同的类,类中有两个相同的属性,并且,这两个类的对象还需要接收
eg
Company.java
@Data
public class Company {private Long cid;private String name;
}
Dept.java
@Data
public class Dept {private Long deptno;private String name;
}
DeptAction.java
@RestController
@RequestMapping("/dept/*")
public class DeptAction {@RequestMapping("add"public Object add(Company company, Dept dept) {Map<String, Object> map = new HashMap<>();map.put("dept", dept);map.put("company", company);return map;}
}
通过浏览器访问当前的执行路径:
localhost/dept/add?cid=10&name=路西法&deptno=999&name=地狱管理部
程序执行结果:
{"company": {"cid": 10,"name": "路西法,地狱管理部"},"dept": {"deptno": 999,"name": "路西法,地狱管理部"}
}
最终执行结果的name跟预期的有差别
如果想要解决请求参数准确设置的问题,必须采用一种全局预处理的方式进行代码的配置,这种方式相当于设置一些前缀
GlobalDataPreparementAdvice .java
@ControllerAdvice
public class GlobalDataPreparementAdvice { //全局数据预处理@InitBinder("company") public void company(WebDataBinder binder) {binder.setFieldDefaultPrefix("company."); //参数前缀}@InitBinder("dept") public void dept(WebDataBinder binder) {binder.setFieldDefaultPrefix("dept."); //参数前缀}
}
DeptAction.java
@RestController
@RequestMapping("/dept/*")
public class DeptAction {@RequestMapping("add")public Object add(@ModelAttribute("company") Company company,@ModelAttribute("dept") Dept dept) {Map<String, Object> map = new HashMap<>();map.put("dept", dept);map.put("company", company);return map;}
}
准备完成之后进行请求路径的设置,路径对于同名的参数要加入前缀
localhost/dept/add?cid=10&company.name=路西法&deptno=999&dept.name=地狱管理部
程序执行结果:
{"company": {"cid": 10,"name": "路西法"},"dept": {"deptno": 999,"name": "地狱管理部"}
}
更多推荐
@ControllerAdvice
发布评论