package message.exception.core; import message.base.Constants; import message.base.exception.ApplicationRuntimeException; import message.config.SystemConfig; import message.config.i18n.ResourceBundleHolder; import message.utils.JsonUtils; import message.utils.PropertyPlaceholderHelper; import message.utils.RequestUtils; import net.sf.json.JSONObject; import org.apache.commons.lang.StringUtils; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.lang.reflect.InvocationTargetException; import java.util.Enumeration; import java.util.Locale; /** * 异常统一处理类. * * @author sunhao(sunhao.java@gmail.com) * @version V1.0, 14-9-11 下午9:04 */ public class ApplicationExceptionResolver extends SimpleMappingExceptionResolver { private static final String ERROR_MESSAGE_KEY = "exceptionMsg"; private static final String AJAX_TYPE_JSON = "json"; private static final String AJAX_TYPE_HTML = "html"; private static final String AJAX_TYPE_JS = "js"; private static final String AJAX_ERROR_HTML = "An error occured when dealing with the ajax request,nested exception is : :errorMessage"; private static final String AJAX_ERROR_JS = "javascript:alert(\":errorMessage \")"; /** * 加载了所有的资源文件信息. */ private ResourceBundleHolder resourceBundleHolder = new ResourceBundleHolder(); public void init() throws Exception { String folderPath = "error"; Resource resource = SystemConfig.getConfigFile(folderPath); ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource[] resources = new Resource[0]; try { resources = resolver.getResources("file:" + resource.getFile().getAbsolutePath() + "/*.properties"); } catch (IOException e) { logger.error("resolver resource:'{" + resource + "}' is error!", e); e.printStackTrace(); } for (Resource r : resources) { String filePath = r.getFile().getAbsolutePath(); if (message.utils.StringUtils.indexOf(filePath, "_") == -1) { this.resourceBundleHolder.loadMessageResource(filePath, 1); } } } @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { if (RequestUtils.isAjaxRequest(request)) { Enumeration ajaxParams = request.getParameterNames(); String ajaxParam = null; while (ajaxParams != null && ajaxParams.hasMoreElements()) { Object obj = ajaxParams.nextElement(); if (obj != null && obj instanceof String && StringUtils.equalsIgnoreCase("ajaxtype", (String) obj)) { ajaxParam = (String) obj; break; } } String ajaxType = ajaxParam == null ? AJAX_TYPE_JSON : request.getParameter(ajaxParam); ajaxType = ajaxType == null ? AJAX_TYPE_JSON : ajaxType; if (ajaxType != null) { return resolveAjaxException(ajaxType, response, ex, request); } } return super.resolveException(request, response, handler, ex); } @Override protected ModelAndView getModelAndView(String viewName, Exception ex, HttpServletRequest request) { ModelAndView mv = super.getModelAndView(viewName, ex, request); String errorMessage = this.getExceptionMessage(ex, request); mv.addObject(ERROR_MESSAGE_KEY, errorMessage); return mv; } private ModelAndView resolveAjaxException(String ajaxType, HttpServletResponse response, Exception ex, HttpServletRequest request) { String exceptionMessage = getExceptionMessage(ex, request); if (StringUtils.equalsIgnoreCase(AJAX_TYPE_JSON, ajaxType)) { JSONObject params = new JSONObject(); params.put(Constants.REQ_STATUS, Constants.REQ_FAILURE); params.put("msg", exceptionMessage); printHTML(response, JsonUtils.toString(params)); } else if (StringUtils.equalsIgnoreCase(AJAX_TYPE_HTML, ajaxType)) { printHTML(response, AJAX_ERROR_HTML); } else if (StringUtils.equals(AJAX_TYPE_JS, ajaxType)) { printHTML(response, AJAX_ERROR_JS); } return null; } private String getExceptionMessage(Exception ex, HttpServletRequest request) { String exceptionMessage; if (ex instanceof ApplicationRuntimeException) { //系统自定义的异常 exceptionMessage = getApplicationExceptionMessage(ex, request); } else { //未知异常 exceptionMessage = getUnknownExceptionMessage(ex); } return exceptionMessage; } /** * 获取异常的异常信息 * * @param ex 异常 * @return */ private String getUnknownExceptionMessage(Exception ex) { String errorMsg = ex.getMessage(); if (StringUtils.isEmpty(errorMsg) && (ex instanceof InvocationTargetException)) { Throwable t = ((InvocationTargetException) ex).getTargetException(); if (t != null) { errorMsg = t.getMessage(); } } return StringUtils.trimToEmpty(errorMsg); } /** * 获取系统定义异常的信息 * * @param ex * @param request * @return */ private String getApplicationExceptionMessage(Exception ex, HttpServletRequest request) { if (!(ex instanceof ApplicationRuntimeException)) { return "未知异常"; } ApplicationRuntimeException are = (ApplicationRuntimeException) ex; int errorCode = are.getErrorCode(); Locale locale = request.getLocale(); String messageByCode = this.resourceBundleHolder.getResourceBundle(locale).getString(errorCode + ""); String message = formatErrorMessage(are.getMessage(), are.getArgs()); Throwable throwable = are.getException(); if (throwable != null) { throwable.printStackTrace(); } return messageByCode + "[" + message + "]"; } private String formatErrorMessage(String message, String[] args) { if (args == null || args.length == 0) { return message; } return PropertyPlaceholderHelper.replacePlaceholder(message, message, args); } private void printHTML(HttpServletResponse response, String html) { PrintWriter printWriter; try { response.setContentType("application/x-json"); response.setCharacterEncoding("utf-8"); printWriter = response.getWriter(); printWriter.print(html); printWriter.close(); } catch (IOException e) { logger.error(e.getMessage(), e); e.printStackTrace(); } } }