springMvc異常處理定製化
阿新 • • 發佈:2019-03-21
1、擴充套件SimpleMappingExceptionResolver來實現springMvc的定製
import org.apache.commons.codec.binary.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; @Service public class DivExceptionResolver extends SimpleMappingExceptionResolver { private static final Logger LOGGER = LoggerFactory.getLogger(DivExceptionResolver.class); private static final String LOG_INTERVAL = "DIV:EXCEPTION:LOG:INTERVAL"; private static final int INTERVAL = 10; @Resource private ExceptionMessageUtils exceptionMessageUtils; @Resource private JedisTemplate jedisTemplate; @Override public ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { ErrorResp resp = new ErrorResp(); resp.setSuccess(false); String code = exceptionMessageUtils.findCode(ex); String msg = exceptionMessageUtils.findLocaleMessage(code, ex); resp.setErrorCode(code); resp.setMsg(msg); logError(code, msg, ex); write(response, resp); exceptionCounter.addSystemException(ex.getMessage()); return null; } protected void write(HttpServletResponse response, ErrorResp result) { PrintWriter out = null; try { Map<String, Object> map = new HashMap<String, Object>(); map.put("success", result.isSuccess()); map.put("msg", result.getMsg()); map.put("errorCode", result.getErrorCode()); String resStr = Base64.encodeBase64String(JsonUtil.toString(map).getBytes("utf-8")); response.setHeader("Access-Control-Allow-Origin", "*");//允許跨域 response.setHeader("Content-Type","application/json;charset=UTF-8");//指定json response.setHeader("Access-Control-Allow-Methods", "*");//支援多方法 out = response.getWriter(); IOUtils.write(resStr, out); } catch (Exception ex) { LOGGER.error("error on exception wrapper output.", ex); } finally { IOUtils.closeQuietly(out); } } /** * 記錄日誌 modified by ysma */ protected void logError(String code, String msg, Exception ex){ if(ex instanceof ReqRejectException) { //指定型別異常 長時間列印一次日誌 String loged = jedisTemplate.get(LOG_INTERVAL); if(loged == null){ LOGGER.error("code[{}], message: {} sys has rejected this request", code, msg); jedisTemplate.setex(LOG_INTERVAL, "loged", INTERVAL); } } else { LOGGER.error("code[{}], message: {}", code, msg, ex); } } }
2、解析異常,植入code和msg
@Component public class ExceptionMessageUtils implements ServletContextAware { private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionMessageUtils.class); private ServletContext servletContext; @Override public void setServletContext(ServletContext servletContext) { this.servletContext = servletContext; } /** * 獲取異常碼 * @return 本地的異常碼 */ public String findCode(Throwable throwable) { String code; if (throwable instanceof BaseException) { code = ((BaseException) throwable).getCode(); } else { if (throwable instanceof DataAccessException || throwable instanceof SQLException) { code = SysExConstants.SQL_EXCEPTION; } else if (throwable instanceof IOException) { code = SysExConstants.IO_EXCEPTION; } else if (throwable instanceof TspErrorCodeException) { code = SysExConstants.TSP_EXECUTE_FALSE; } else { code = SysExConstants.UNKNOWN_EXCEPTION; } } return code; } /** * 獲取異常對應可讀錯誤文字,中文資源 * @return 錯誤資訊 */ public String findChineseMessage(Throwable throwable) { String code = findCode(throwable); return findLocaleMessage(code, throwable, Locale.SIMPLIFIED_CHINESE); } /** * 獲取異常對應可讀錯誤文字,自動判斷資源 * @param code 異常碼 * @param throwable 異常 * @return 錯誤資訊 */ public String findLocaleMessage(String code, Throwable throwable) { RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); Locale locale = RequestContextUtils.getLocale(request); return findLocaleMessage(code, throwable, locale); } /** * 獲取異常對應可讀錯誤文字 * @param code 異常碼 * @param throwable 異常 * @param locale 原生代碼 * @return 錯誤資訊 */ public String findLocaleMessage(String code, Throwable throwable, Locale locale) { Object[] args = null; if (throwable instanceof BaseException) { if (throwable.getMessage() != null) { return throwable.getMessage(); } args = ((BaseException) throwable).getMessageArgs(); } WebApplicationContext webApplicationContext = WebApplicationContextUtils .getWebApplicationContext(servletContext); return webApplicationContext.getMessage(code, args, throwable.getMessage(), locale); } }
3、異常碼基本定義
public class BaseException extends RuntimeException { private static final long serialVersionUID = -2755280599112409861L; private String code; private Object[] messageArgs; public BaseException(String code) { this.code = code; } public BaseException(String code, Throwable cause) { super(cause); this.code = code; } public BaseException(String code, Object[] messageArgs) { this.code = code; this.messageArgs = messageArgs; } public BaseException(String code, String message, Object[] messageArgs) { super(message); this.code = code; this.messageArgs = messageArgs; } public BaseException(String code, String message, Throwable cause, Object[] messageArgs) { super(message, cause); this.code = code; this.messageArgs = messageArgs; } public BaseException(String code, Throwable cause, Object[] messageArgs) { super(cause); this.code = code; this.messageArgs = messageArgs; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public Object[] getMessageArgs() { return messageArgs; } public void setMessageArgs(Object[] messageArgs) { this.messageArgs = messageArgs; } }
4、錯誤碼國際化繫結
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="i18n.messages" />
</bean>
國際話文字設定resource根i18n目錄下
5、異常常量控制
public class SysExConstants {
public static final String TSP_TRANSFORM_OK = "1797100";
public static final String TSP_TRANSFORM_FAIL = "1797101";
/**
* 未捕獲異常
*/
public static final String UNKNOWN_EXCEPTION = "7100001";
/**
* IO異常
*/
public static final String IO_EXCEPTION = "7100002";
/**
* SQL異常
*/
public static final String SQL_EXCEPTION = "7100003";
/**
* solr執行異常
*/
public static final String SOLR_EXCEPTION = "7100004";
/**
* REST 執行出錯
*/
public static final String REST_CLIENT_ERROR = "7100008";
/**
* pebble exception
*/
public static final String PEBBLE_CLIENT_ERROR = "7200001";
/**
* json入參解析異常
*/
public static final String JSON_PARSE_EXCEPTION = "7100009";
}
6、如上springMVC異常