@RestController
1、观察handler方法,可以看到每一个方法上面都有一个@ResponseBody, 这时我们可以将@ResponseBody提升到类上
2、@RestController = @Controller + @ResponseBody
异常映射兼容异步请求
异常表现
Ajax请求在服务器端处理过程中抛出异常,经过/atcrowdfunding-admin-2-component/src/main/java/com/atguigu/crowd/funding/exeption/CrowdFundingExceptionResolever.java异常处理器:
@ControllerAdvice
public class CrowdFundingExceptionResolever {
@ExceptionHandler(value=Exception.class)
public ModelAndView catchException(Exception exception) {
ModelAndView mav = new ModelAndView();
mav.addObject("exception", exception);
mav.setViewName("system-error");
return mav;
}
}
目前这个异常处理机制,只能返回页面,而不能针对Ajax请求返回JSON格式的响应数据。所以Ajax请求处理过程中,如果抛出异常,返回异常信息页面,Ajax程序无法正常解析,导致页面不能正常显示和工作,也不能给出友好的错误提示。
解决思路
异步请求特点
分辨异步请求的工具方法
/atcrowdfunding-admin-3-common/src/main/java/com/atguigu/crowd/funding/util/CrowdFundingUtils.java
/**
* 用于判断一个请求是否是异步请求
* @param request
* @return
*/
public static boolean checkAsyncRequest(HttpServletRequest request) {
// 1.获取相应请求消息头
String accept = request.getHeader("Accept");
String xRequested = request.getHeader("X-Requested-With");
// 2.判断请求消息头数据中是否包含目标特征
if(
(stringEffective(accept) && accept.contains("application/json"))
||
(stringEffective(xRequested) && xRequested.contains("XMLHttpRequest")) ) {
return true;
}
return false;
}
升级后的异常处理器
引入gjson依赖
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
代码
所在工程:atcrowdfunding-admin-3-common
全类名:com.atguigu.crowd.funding.util.CrowdFundingConstant
public static final Map<String, String> EXCEPTION_MESSAGE_MAP = new HashMap<>();
static {
EXCEPTION_MESSAGE_MAP.put("java.lang.ArithmeticException", "系统在进行数学运算时发生错误");
EXCEPTION_MESSAGE_MAP.put("java.lang.RuntimeException", "系统在运行时发生错误");
EXCEPTION_MESSAGE_MAP.put("com.atguigu.crowd.funding.exception.LoginException", "登录过程中运行错误");
}
所在工程:atcrowdfunding-admin-2-component
全类名:com.atguigu.crowd.funding.exeption.CrowdFundingExceptionResolever
@ControllerAdvice
public class CrowdFundingExceptionResolever {
@ExceptionHandler(value=Exception.class)
public ModelAndView catchException(
Exception exception,
HttpServletRequest request,
HttpServletResponse response) throws IOException {
// 1.对当前请求进行检查
boolean checkAsyncRequestResult = CrowdFundingUtils.checkAsyncRequest(request);
// 2.如果是异步请求
if(checkAsyncRequestResult) {
// 根据异常类型在常量中的映射,使用比较友好的文字显示错误提示消息
String exceptionClassName = exception.getClass().getName();
String message = CrowdFundingConstant.EXCEPTION_MESSAGE_MAP.get(exceptionClassName);
if(message == null) {
message = "系统未知错误";
}
// 3.创建ResultEntity对象
ResultEntity<String> resultEntity = ResultEntity.failed(ResultEntity.NO_DATA, message);
// 4.将resultEntity转换为JSON格式
Gson gson = new Gson();
String json = gson.toJson(resultEntity);
// 5.将json作为响应数据返回给浏览器
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(json);
return null;
}
ModelAndView mav = new ModelAndView();
mav.addObject("exception", exception);
mav.setViewName("system-error");
return mav;
}
}