在controller里面,我们可以这样实现返回格式的统一
@ResponseBody
@RequestMapping(value = "saveReferenceInfo", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public JSONObject saveReferenceInfo(@RequestBody List<AfcApplicantVo> voList, String sessionKey){
try{
applicantService.saveReferenceInfo(voList);
}catch (HandleException e){
e.printStackTrace();
return Success(ResultType.error, e.getMessage(), null);
}catch (Exception e){
e.printStackTrace();
return Success(ResultType.error, "系统错误", null);
}
return Success(ResultType.success, "操作成功", null);
}
但是这样实现容易出现以下问题
那么有没有办法来做统一的数据返回呢?
@ControllerAdvice(basePackages = "org.zj.test.test")
public class TestResponseBodyAdvice<T> implements ResponseBodyAdvice<T> {
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
return true;
}
@Override
public T beforeBodyWrite(T t, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
Result<T> tResult = new Result<>();
tResult.setCode(200);
tResult.setMessage("操作成功");
tResult.setData(t);
return (T) tResult;
}
}
这里我们定义一个ControllerAdvice来对Controller的返回结果进行处理
请求过来的时候,会路由到方法上进行执行。这里会先执行定义的supports方法,对返回值进行判断。如果返回值为true并且在往Response中写入json之前才会执行beforeBodyWrite方法。这里没有特殊要求,我就直接让supports方法返回true了
我们看一下我们的测试代码
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping("/t")
public Student ttt() throws TestException {
Result<Student> studentResult = new Result<>();
studentResult.setCode(1);
studentResult.setMessage("成功");
Student student = new Student();
student.setName("李四");
student.setPassword("ffff");
return student;
}
}
调用接口就能看见他已经起作用了
{“code”:200,“message”:“操作成功”,“data”:{“name”:“李四”,“password”:“ffff”}}
先定义我们的异常类
public class TestException extends Exception {
public TestException(String message) {
super(message);
}
}
然后定义我们的异常拦截
@ControllerAdvice
public class ResultHandler {
@ResponseBody
@ExceptionHandler(TestException.class)
public <T>Result<T> handle(HttpServletRequest request,TestException exception){
Result<T> objectResult = new Result<>();
objectResult.setMessage(exception.getMessage());
objectResult.setCode(400000);
return objectResult;
}
}
注意,这里我们加了异常处理的返回和通用的结果返回,必须要配置下通用结果返回的Supports方法的返回值,不然就会出现这种情况
{“code”:200,“message”:“操作成功”,“data”:{“code”:400000,“message”:“我故意的”,“data”:null}}
遇到异常后,这里先处理了异常结果的返回,然后又经过了响应处理。
我们可以在响应处理的Supports方法里面进行处理,判断结果是否处理过,处理过就不处理了
只需要改一下这里
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
return methodParameter.getParameterType()!=Result.class;
}
这里直接判断返回值是否是我定义的那个类,是的话就不处理了
然后就是测试代码
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping("/t")
public Student ttt() throws TestException {
Result<Student> studentResult = new Result<>();
studentResult.setCode(1);
studentResult.setMessage("成功");
throw new TestException("我故意的");
}
}
这里我直接手动在Controller方法中抛出了一个异常
{“code”:400000,“message”:“我故意的”,“data”:null}
这样就基本上满足我们的需求了