继承org.springframework.web.servlet.handler.SimpleMappingExceptionResolver
public class SimpleMappingExceptionResolver extends AbstractHandlerExceptionResolver {
...
@Override
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) {
// Expose ModelAndView for chosen error view.
String viewName = determineViewName(ex, request);
if (viewName != null) {
// Apply HTTP status code for error views, if specified.
// Only apply it if we're processing a top-level request.
Integer statusCode = determineStatusCode(request, viewName);
if (statusCode != null) {
applyStatusCodeIfPossible(request, response, statusCode);
}
return getModelAndView(viewName, ex, request);
}
else {
return null;
}
}
}
只需要重写doResolveException方法
MyExceptionResolver
package com.ghgcn.support.web;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import org.jflame.toolkit.common.bean.CallResult;
import org.jflame.toolkit.common.bean.CallResult.ResultEnum;
import org.jflame.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
/**
* 统一异常处理类
*
* @author zyc
*/
@SuppressWarnings("rawtypes")
public class MyExceptionResolver extends SimpleMappingExceptionResolver {
private final CallResult err_json = new CallResult(ResultEnum.SERVER_ERROR);
private final Logger log = LoggerFactory.getLogger(MyExceptionResolver.class);
public MyExceptionResolver() {
}
@Override
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) {
String viewName = determineViewName(ex, request);
log.error(ex.getMessage(), ex);// 日志记录异常
if (viewName != null) {
Integer statusCode = determineStatusCode(request, viewName);
if (statusCode != null) {
applyStatusCodeIfPossible(request, response, statusCode);
}
// 请求方法未使用BindingResult保存验证结果时,将抛出BindException异常,由此处统一处理
if (ex instanceof BindException) {
BindException validEx = (BindException) ex;
if (validEx.hasFieldErrors()) {
if (jsonResult(request, handler)) {
CallResult errResult = new CallResult();
BaseController.convertError(validEx.getBindingResult(), errResult);
outJson(response, errResult);
return null;
} else {
((WebRequest) request).setAttribute("fieldErrors", validEx.getFieldErrors(),
WebRequest.SCOPE_REQUEST);
}
}
} else {
if (jsonResult(request, handler)) {
if (ex.getCause() instanceof ConstraintViolationException) {
ConstraintViolationException cve = (ConstraintViolationException) ex.getCause();
String errMsg = "";
for (ConstraintViolation cv : cve.getConstraintViolations()) {
errMsg = errMsg + cv.getMessage() + ";";
}
outJson(response, CallResult.paramError(errMsg));
} else {
outJson(response, err_json);
}
return null;
}
}
return getModelAndView(viewName, ex, request);
}
return null;
}
void outJson(HttpServletResponse response, CallResult json) {
try {
WebUtils.outJson(response, json);
} catch (IOException e) {
log.error("", e);
}
}
public static boolean jsonResult(HttpServletRequest request, Object handler) {
if (handler != null && handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
if (handlerMethod.getMethodAnnotation(ResponseBody.class) != null
|| handlerMethod.getBeanType().getAnnotation(RestController.class) != null) {
return true;
}
}
if (WebUtils.isJsonRequest(request)) {
return true;
}
return false;
}
}
WebUtils
/**
* http mine,json类型
*/
public static final String MIME_TYPE_JSON = "application/json";
/**
* http mine,json类型指定utf-8编码
*/
public final static String MIME_TYPE_JSON_UTF8 = MIME_TYPE_JSON + ";charset=UTF-8";
public static <T extends Serializable> void outJson(HttpServletResponse response, T entity) throws IOException {
outJson(response, entity, null);
}
/**
* 对象转为json后输出到到response.
*
* @param response HttpServletResponse
* @param entity 待序列化对象
* @param charset 字符集,为null时采用utf-8
* @throws IOException
*/
public static <T extends Serializable> void outJson(HttpServletResponse response, T entity, Charset charset)
throws IOException {
setDisableCacheHeader(response);
if (charset == null) {
response.setContentType(MIME_TYPE_JSON_UTF8);
} else {
response.setContentType(MIME_TYPE_JSON + ";charset=" + charset.name());
}
PrintWriter out = response.getWriter();
out.print(JsonHelper.toJson(entity));
out.close();
}
/**
* 设置禁止客户端缓存的Header.
*
* @param response HttpServletResponse
*/
public static void setDisableCacheHeader(HttpServletResponse response) {
response.setDateHeader("Expires", 1L);
response.addHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache, no-store, max-age=0");
}
xml中配置
<mvc:default-servlet-handler />
<!-- 统一异常处理 -->
<bean id="exceptionResolver" class="com.ghgcn.support.web.MyExceptionResolver">
<property name="defaultErrorView" value="/common/error" />
<property name="exceptionMappings">
<props>
<prop key="java.lang.Exception">/common/error</prop>
</props>
</property>
</bean>