@ControllerAdvice

编程入门 行业动态 更新时间:2024-10-28 21:22:49

@<a href=https://www.elefans.com/category/jswz/34/1671919.html style=ControllerAdvice"/>

@ControllerAdvice

  • 全局异常处理
  • 全局数据绑定
  • 全局数据预处理

全局异常处理
全局异常配置中一个重要注解

@ControllerAdviceorg.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

本文发布于:2024-03-09 13:26:12,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1725084.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:ControllerAdvice

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!