参考这篇文章里面的几种异常形式:
全局异常处理是个比较重要的功能,一般在项目里都会用到。
大概把一次请求分成三个阶段,来分别进行全局的异常处理。
一:在进入Controller之前,譬如请求一个不存在的地址,404错误。
二:在执行@RequestMapping时,进入逻辑处理阶段前。譬如传的参数类型错误。
三:以上都正常时,在controller里执行逻辑代码时出的异常。譬如NullPointerException。
http://blog.csdn.net/tianyaleixiaowu/article/details/70145251
直接将编写的全局异常处理类放入项目中,配置@Controller将类载入spring中即可使用,不需要任何配置。
以下是我写的异常处理类:
package com.archibladwitwicke.springboot2.chapter03.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@Controller
public class GlobalErrorController extends AbstractErrorController {
private static final String ERROR_PATH = "/error";
private Log log = LogFactory.getLog(GlobalErrorController.class);
@Autowired
ObjectMapper objectMapper;
public GlobalErrorController() {
super(new DefaultErrorAttributes());
}
@RequestMapping(ERROR_PATH)
public ModelAndView getErrorPath(HttpServletRequest request, HttpServletResponse response) {
Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(
request, false));
Throwable cause = getCause(request);
int status = (Integer) model.get("status");
//错误信息
String message = (String) model.get("message");
//友好提示
String errorMessage = getErrorMessage(cause);
String requestPath = (String) model.get("path");
//后台打印日志信息方方便查错
log.info(status + ":" + message, cause);
log.info("requestPath---" + ":" + requestPath);
//后台打印日志信息方方便查错
log.info(message, cause);
response.setStatus(status);
if (!isJsonRequest(request, model)) {
ModelAndView view = new ModelAndView("/error.btl");
view.addAllObjects(model);
view.addObject("status", status);
view.addObject("errorMessage", errorMessage);
view.addObject("cause", cause);
return view;
} else {
Map<String, Object> error = new HashMap<>();
error.put("success", false);
error.put("errorMessage", getErrorMessage(cause));
error.put("message", message);
writeJson(response, error);
return null;
}
}
private boolean isJsonRequest(HttpServletRequest request, Map<String, Object> model) {
// 修复bug,在此类中,使用request无法获取requestPath
String requestPath = (String) model.get("path");
if (requestPath.endsWith(".json")) {
return true;
} else {
return (request.getHeader("accept").contains("application/json") || (request.getHeader("X-Requested-With") != null
&& request.getHeader("X-Requested-With").contains("XMLHttpRequest")));
}
}
private void writeJson(HttpServletResponse response, Map<?, ?> error) {
response.setContentType("application/json;charset=utf-8");
try {
response.getWriter().write(objectMapper.writeValueAsString(error));
} catch (IOException e) {
e.printStackTrace();
}
}
private String getErrorMessage(Throwable ex) {
/*不给前端显示详细错误*/
return "服务器错误,请联系管理员";
}
private Throwable getCause(HttpServletRequest request) {
Throwable error = (Throwable) request.getAttribute("javax.servlet.error.exception");
if (error != null) {
while (error instanceof ServletException && error.getCause() != null) {
error = ((ServletException) error).getCause();
}
}
return error;
}
@Override
public String getErrorPath() {
return ERROR_PATH;
}
}
可以根据项目具体修改这个方法,将判断ajax请求的种类进行完善,其余的部分可以不用修改:
private boolean isJsonRequest(HttpServletRequest request, Map<String, Object> model) {
// 修复bug,在此类中,使用request无法获取requestPath
String requestPath = (String) model.get("path");
if (requestPath.endsWith(".json")) {
return true;
} else {
return (request.getHeader("accept").contains("application/json") || (request.getHeader("X-Requested-With") != null
&& request.getHeader("X-Requested-With").contains("XMLHttpRequest")));
}
}
此异常类可以对上述三种异常情况进行拦截处理,显示自定义的异常处理页面或异常处理数据。