Java tutorial
/* * Copyright 2007-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.ymate.framework.webmvc; import com.alibaba.fastjson.JSON; import net.ymate.framework.core.Optional; import net.ymate.framework.core.support.ExceptionProcessHelper; import net.ymate.framework.core.support.IExceptionProcessor; import net.ymate.framework.core.util.ViewPathUtils; import net.ymate.framework.core.util.WebUtils; import net.ymate.framework.exception.*; import net.ymate.platform.core.i18n.I18N; import net.ymate.platform.core.lang.BlurObject; import net.ymate.platform.core.util.DateTimeUtils; import net.ymate.platform.core.util.RuntimeUtils; import net.ymate.platform.validation.ValidateResult; import net.ymate.platform.webmvc.*; import net.ymate.platform.webmvc.context.WebContext; import net.ymate.platform.webmvc.support.GenericResponseWrapper; import net.ymate.platform.webmvc.view.IView; import net.ymate.platform.webmvc.view.View; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; /** * @author (suninformation@163.com) on 2018/2/22 ?10:47 * @version 1.0 */ public abstract class AbstractWebErrorProcessor implements IWebErrorProcessor, IWebInitializable { private static final Log _LOG = LogFactory.getLog(AbstractWebErrorProcessor.class); private static final ExceptionProcessHelper __exceptionProcessHelper = new ExceptionProcessHelper(); private boolean __inited; private String __resourceName; private String __errorDefaultI18nKey; private String __errorDefaultViewFormat; private boolean __disabledAnalysis; @Override public void init(WebMVC owner) throws Exception { if (!__inited) { __resourceName = StringUtils .defaultIfBlank(owner.getOwner().getConfig().getParam(Optional.I18N_RESOURCE_NAME), "messages"); __errorDefaultI18nKey = StringUtils.defaultIfBlank( owner.getOwner().getConfig().getParam(Optional.SYSTEM_ERROR_DEFAULT_I18N_KEY), Optional.SYSTEM_ERROR_DEFAULT_I18N_KEY); __errorDefaultViewFormat = StringUtils .trimToEmpty(owner.getOwner().getConfig().getParam(Optional.ERROR_DEFAULT_VIEW_FORMAT)) .toLowerCase(); __disabledAnalysis = BlurObject .bind(owner.getOwner().getConfig().getParam(Optional.SYSTEM_EXCEPTION_ANALYSIS_DISABLED)) .toBooleanValue(); // __doInit(owner); // __inited = true; } } protected void __doInit(IWebMvc owner) throws Exception { getExceptionProcessHelper() .registerProcessor(DataVersionMismatchException.class, new IExceptionProcessor() { @Override public IExceptionProcessor.Result process(Throwable target) throws Exception { return new IExceptionProcessor.Result(ErrorCode.DATA_VERSION_NOT_MATCH, i18nMsg(Optional.SYSTEM_DATA_VERSION_NOT_MATCH_KEY, "???")); } }).registerProcessor(RequestForbiddenException.class, new IExceptionProcessor() { @Override public IExceptionProcessor.Result process(Throwable target) throws Exception { return new IExceptionProcessor.Result(ErrorCode.REQUEST_OPERATION_FORBIDDEN, i18nMsg( Optional.SYSTEM_REQUEST_OPERATION_FORBIDDEN_KEY, "??")); } }).registerProcessor(RequestMethodNotAllowedException.class, new IExceptionProcessor() { @Override public IExceptionProcessor.Result process(Throwable target) throws Exception { return new IExceptionProcessor.Result(ErrorCode.REQUEST_METHOD_NOT_ALLOWED, i18nMsg(Optional.SYSTEM_REQUEST_METHOD_NOT_ALLOWED_KEY, "???")); } }).registerProcessor(RequestUnauthorizedException.class, new IExceptionProcessor() { @Override public IExceptionProcessor.Result process(Throwable target) throws Exception { return new IExceptionProcessor.Result(ErrorCode.REQUEST_RESOURCE_UNAUTHORIZED, i18nMsg(Optional.SYSTEM_REQUEST_RESOURCE_UNAUTHORIZED_KEY, "????")); } }).registerProcessor(ResourceNotFoundException.class, new IExceptionProcessor() { @Override public IExceptionProcessor.Result process(Throwable target) throws Exception { return new IExceptionProcessor.Result(ErrorCode.RESOURCE_NOT_FOUND_OR_NOT_EXIST, i18nMsg(Optional.SYSTEM_RESOURCE_NOT_FOUND_OR_NOT_EXIST_KEY, "??")); } }).registerProcessor(UserSessionInvalidException.class, new IExceptionProcessor() { @Override public IExceptionProcessor.Result process(Throwable target) throws Exception { return new IExceptionProcessor.Result(ErrorCode.USER_SESSION_INVALID_OR_TIMEOUT, i18nMsg( Optional.SYSTEM_SESSION_TIMEOUT_KEY, "??")); } }); } protected abstract IView __doShowErrorMsg(IWebMvc owner, int code, String msg, Map<String, Object> dataMap); @Override public void destroy() throws Exception { } public final ExceptionProcessHelper getExceptionProcessHelper() { return __exceptionProcessHelper; } public final String getResourceName() { return __resourceName; } public final boolean isDisabledAnalysis() { return __disabledAnalysis; } public final boolean isInited() { return __inited; } public final String getErrorDefaultI18nKey() { return __errorDefaultI18nKey; } public final String getErrorDefaultViewFormat() { return __errorDefaultViewFormat; } public final String i18nMsg(String msgKey, String defaultMsg) { return I18N.formatMessage(__resourceName, StringUtils.defaultIfBlank(msgKey, __errorDefaultI18nKey), StringUtils.defaultIfBlank(defaultMsg, "?, ???!")); } @Override public void onError(IWebMvc owner, Throwable e) { try { Throwable _unwrapThrow = RuntimeUtils.unwrapThrow(e); IExceptionProcessor _processor = __exceptionProcessHelper.bind(_unwrapThrow.getClass()); if (_processor != null) { IExceptionProcessor.Result _result = _processor.process(_unwrapThrow); __doShowErrorMsg(owner, _result.getCode(), i18nMsg(_result.getMessage(), _result.getMessage()), null).render(); } else { if (!__disabledAnalysis && owner.getOwner().getConfig().isDevelopMode()) { _LOG.error(__doParseExceptionDetail(_unwrapThrow)); } else { _LOG.error("", _unwrapThrow); } __doShowErrorMsg(owner, ErrorCode.INTERNAL_SYSTEM_ERROR, i18nMsg(null, null), null).render(); } } catch (Throwable e1) { _LOG.warn("", RuntimeUtils.unwrapThrow(e1)); } } private String __doParseExceptionDetail(Throwable e) { IRequestContext _requestCtx = WebContext.getRequestContext(); HttpServletRequest _request = WebContext.getRequest(); WebContext _context = WebContext.getContext(); // StringBuilder _errSB = new StringBuilder("An exception occurred at ") .append(DateTimeUtils.formatTime(System.currentTimeMillis(), DateTimeUtils.YYYY_MM_DD_HH_MM_SS_SSS)) .append(":\n"); _errSB.append("-------------------------------------------------\n"); _errSB.append("-- ThreadId: ").append(Thread.currentThread().getId()).append("\n"); _errSB.append("-- RequestMapping: ").append(_requestCtx.getRequestMapping()).append("\n"); _errSB.append("-- ResponseStatus: ").append(((GenericResponseWrapper) WebContext.getResponse()).getStatus()) .append("\n"); _errSB.append("-- Method: ").append(_requestCtx.getHttpMethod().name()).append("\n"); _errSB.append("-- RemoteAddrs: ").append(JSON.toJSONString(WebUtils.getRemoteAddrs(_request))).append("\n"); RequestMeta _meta = _context.getAttribute(RequestMeta.class.getName()); if (_meta != null) { _errSB.append("-- Controller: ").append(_meta.getTargetClass().getName()).append(":") .append(_meta.getMethod().getName()).append("\n"); } _errSB.append("-- ContextAttributes:").append("\n"); for (Map.Entry<String, Object> _entry : _context.getAttributes().entrySet()) { if (!StringUtils.startsWith(_entry.getKey(), "net.ymate.platform.webmvc")) { _errSB.append("\t ").append(_entry.getKey()).append(": ") .append(JSON.toJSONString(_entry.getValue())).append("\n"); } } _errSB.append("-- Parameters:").append("\n"); for (Map.Entry<String, Object> _entry : _context.getParameters().entrySet()) { _errSB.append("\t ").append(_entry.getKey()).append(": ").append(JSON.toJSONString(_entry.getValue())) .append("\n"); } _errSB.append("-- Attributes:").append("\n"); Enumeration _enum = _request.getAttributeNames(); while (_enum.hasMoreElements()) { String _attrName = (String) _enum.nextElement(); _errSB.append("\t ").append(_attrName).append(": ") .append(JSON.toJSONString(_request.getAttribute(_attrName))).append("\n"); } _errSB.append("-- Headers:").append("\n"); _enum = _request.getHeaderNames(); while (_enum.hasMoreElements()) { String _headName = (String) _enum.nextElement(); if ("cookie".equalsIgnoreCase(_headName)) { continue; } _errSB.append("\t ").append(_headName).append(": ") .append(JSON.toJSONString(_request.getHeader(_headName))).append("\n"); } _errSB.append("-- Cookies:").append("\n"); Cookie[] _cookies = _request.getCookies(); if (_cookies != null) { for (Cookie _cookie : _cookies) { _errSB.append("\t ").append(_cookie.getName()).append(": ") .append(JSON.toJSONString(_cookie.getValue())).append("\n"); } } _errSB.append("-- Session:").append("\n"); for (Map.Entry<String, Object> _entry : _context.getSession().entrySet()) { _errSB.append("\t ").append(_entry.getKey()).append(": ").append(JSON.toJSONString(_entry.getValue())) .append("\n"); } _errSB.append(__doExceptionToString(e)); _errSB.append("-------------------------------------------------\n"); // return _errSB.toString(); } private StringBuilder __doExceptionToString(Throwable e) { StringBuilder _errSB = new StringBuilder(); if (e != null) { _errSB.append("-- Exception: ").append(e.getClass().getName()).append("\n"); _errSB.append("-- Message: ").append(e.getMessage()).append("\n"); // _errSB.append("-- StackTrace:\n"); StackTraceElement[] _stacks = e.getStackTrace(); for (StackTraceElement _stack : _stacks) { _errSB.append("\t at ").append(_stack).append("\n"); } } return _errSB; } @Override public IView onValidation(IWebMvc owner, Map<String, ValidateResult> results) { String _message = i18nMsg(Optional.SYSTEM_PARAMS_VALIDATION_INVALID_KEY, "??"); Map<String, Object> _dataMap = new HashMap<String, Object>(); for (ValidateResult _vResult : results.values()) { _dataMap.put(_vResult.getName(), _vResult.getMsg()); } // if (!WebUtils.isAjax(WebContext.getRequest(), true, true) && !"json".equals(getErrorDefaultViewFormat())) { // ?? _message = WebUtils.messageWithTemplate(owner.getOwner(), _message, results.values()); } return __doShowErrorMsg(owner, ErrorCode.INVALID_PARAMS_VALIDATION, _message, _dataMap); } @Override public IView onConvention(IWebMvc owner, IRequestContext requestContext) throws Exception { String[] _fileTypes = { ".html", ".jsp", ".ftl", ".vm", ".btl" }; for (String _fileType : _fileTypes) { // ?? File _targetFile = new File(ViewPathUtils.pluginViewPath(), requestContext.getRequestMapping() + _fileType); if (_targetFile.exists()) { if (".html".equals(_fileType)) { return View.htmlView(owner, requestContext.getRequestMapping().substring(1)); } else if (".jsp".equals(_fileType)) { return View.jspView(owner, requestContext.getRequestMapping().substring(1)); } else if (".ftl".equals(_fileType)) { return View.freemarkerView(owner, requestContext.getRequestMapping().substring(1)); } else if (".vm".equals(_fileType)) { return View.velocityView(owner, requestContext.getRequestMapping().substring(1)); } else if (".btl".equals(_fileType)) { return View.beetlView(owner, requestContext.getRequestMapping().substring(1)); } } } return null; } }