项目异常处理
来源:互联网 发布:mac玩qq游戏大厅 编辑:程序博客网 时间:2024/05/22 01:09
下面是我们项目的异常处理机制,在此记录一下。
一、自定义异常
首先,我们自定义了两种类型的异常:DataWarningException和ServerErrorException
DataWarningException.java
package com.augmentum.ot.exception;public class DataWarningException extends Exception { private static final long serialVersionUID = -1462714485890122558L; public DataWarningException(String message, Throwable cause) { super(message, cause); } public DataWarningException(String message) { super(message); } public DataWarningException(Throwable cause) { super(cause); }}
ServerErrorException.java
package com.augmentum.ot.exception;public class ServerErrorException extends Exception { private static final long serialVersionUID = -1462714485890122558L; public ServerErrorException(String message, Throwable cause) { super(message, cause); } public ServerErrorException(String message) { super(message); } public ServerErrorException(Throwable cause) { super(cause); }}
其中,当发生数据异常,比如说操作数据库失败,数据验证错误,在service抛出ServerErrorException;当出现业务逻辑错误,在service抛出 DataWarningException.
二、定义并初始化异常信息
在自定义完异常后,我们有创建了一个Exception.xml文件来记录异常信息,内容如下:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE PUBLIC><!-- 其中errorMessageKey表示的是传给前台的错误信息;logMessage表示的是当异常发生时打印的log信息;flag表示的是是否要跳页面,如果flag=1表示要跳页面,flag=0表示不跳页面 --><exception> <!-- Server internal error --> <errorCode id="E0001"> <errorMessageKey></errorMessageKey> <logMessage>Exception error.</logMessage> <flag>1</flag> </errorCode> <errorCode id="E0002"> <errorMessageKey></errorMessageKey> <logMessage>Validation failure.</logMessage> <flag>1</flag> </errorCode> <errorCode id="E0005"> <logMessage>Employee [#_employee_id] has no access to [actionName].</logMessage> <errorMessageKey>_no_privilege</errorMessageKey> <flag>1</flag> </errorCode> ...... <!-- Common message --> <errorCode id="W0001"> <logMessage>There is no data</logMessage> <errorMessageKey>no_data</errorMessageKey> <flag>0</flag> </errorCode> <!-- Course part exception --> <errorCode id="W1001"> <logMessage>Failed to view detail course [#_course_id] that it is already deleted.</logMessage> <errorMessageKey>_course_not_exist_error</errorMessageKey> <flag>1</flag> </errorCode> </exception>
创建一个和其对应的DTO类存放每个异常信息
ErrorCode.java
public class ErrorCode { private String errorCodeId; private String flag; private String errorMessage; private String logMessage; public String getLogMessage() { return logMessage; } public void setLogMessage(String logMessage) { this.logMessage = logMessage; } public String getFlag() { return flag; } public void setFlag(String flag) { this.flag = flag; } public String getErrorCodeId() { return errorCodeId; } public void setErrorCodeId(String errorCodeId) { this.errorCodeId = errorCodeId; } public String getErrorMessage() { return errorMessage; } public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; }}定义一个常量类存放ErrorCodeId
ErrorCodeConstants.java
public class ErrorCodeConstants { // Common Part public static final String SERVER_ERROR = "E0001"; public static final String SERVER_VALIDATION_ERROR = "E0002"; public static final String ERROR = "E0004"; public static final String NO_ACCESS = "E0005"; ...... }
在启动项目的时候,写一个Servlet解析这些异常信息,并将其放入ServletContext中。
InitDataServlet.java
package com.augmentum.ot.initServlet;import java.util.Map;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import org.springframework.stereotype.Component;import com.augmentum.ot.dataObject.ErrorCode;import com.augmentum.ot.dataObject.constant.FlagConstants;import com.augmentum.ot.util.ReaderXmlUtils;@Componentpublic class InitDataServlet extends HttpServlet { private static final long serialVersionUID = 2705746245967369017L; @Override public void init() throws ServletException { super.init(); ServletContext servletContext = getServletContext(); try { Map<String, ErrorCode> errorCodeMap = ReaderXmlUtils.getErrorCodes(); //自定义的解析xml的工具类 servletContext.setAttribute(FlagConstants.ERROR_CODE_MAP, errorCodeMap); } catch (Exception e) { e.printStackTrace(); } }}
web.xml
<servlet> <display-name>InitDataServlet</display-name> <servlet-name>InitDataServlet</servlet-name> <servlet-class>com.augmentum.ot.initServlet.InitDataServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>InitDataServlet</servlet-name> <url-pattern>/InitDataServlet</url-pattern> </servlet-mapping>
三、在service层和action层抛出异常
下面是service方法的一个方法
@Override public Course getDetailCourseById(Integer id) throws DataWarningException, ServerErrorException { logger.debug(LogConstants.getDebugInput("courseId", id)); if (id == null || id <= 0) { logger.error(LogConstants.objectIsNULLOrEmpty("id")); throw new ServerErrorException(ErrorCodeConstants.SERVER_VALIDATION_ERROR); } Course course; try { course = courseDao.findByPrimaryKey(id); } catch (Exception e) { logger.error(e.getStackTrace(), e); throw new ServerErrorException(ErrorCodeConstants.SERVER_ERROR); } if (course == null || course.getCourseIsDeleted() == FlagConstants.IS_DELETED) { logger.warn(LogConstants.getLogCourseByErrorCode(ErrorCodeConstants.VIEW_COURSE_DELETED, id)); throw new DataWarningException(ErrorCodeConstants.VIEW_COURSE_DELETED); } ...... logger.debug(LogConstants.getDebugOutput("Course", course.toString())); return course; }
下面是action层的一个方法
public String viewCourseDetail() throws DataWarningException, ServerErrorException { ...... course = courseService.getDetailCourseById(courseId); ...... return SUCCESS; }
四、在Interceptor中处理异常
在我们系统中,每个Action类都继承一个BaseAction,在BaseAction中有个JSONObject对象,存放返回给前台的数据。所以错误数据我们可以存放到jsonObject中
ExceptionInterceptor.java
public class ExceptionInterceptor extends ExceptionMappingInterceptor { private static final long serialVersionUID = -3837674457299306885L; private static final Logger logger = Logger.getLogger(ExceptionInterceptor.class); private BaseAction baseAction; private boolean isAjaxRequest(HttpServletRequest request) { String header = request.getHeader("X-Requested-With"); if (header != null && "XMLHttpRequest".equals(header)) return true; else return false; } private String handleExceptionByServerErrorException(Exception e, boolean isAjax) { String errorCode = e.getMessage(); if (null == errorCode || "".equals(errorCode)) { errorCode = ErrorCodeConstants.SERVER_ERROR; } ServletContext context = ServletActionContext.getServletContext(); @SuppressWarnings("unchecked") Map<String, ErrorCode> errorCodeMap = (Map<String, ErrorCode>) context.getAttribute(FlagConstants.ERROR_CODE_MAP); ErrorCode errorCodeEntity = errorCodeMap.get(errorCode); logger.error(errorCodeEntity.getErrorMessage()); if (isAjax) { // Make the JSON object. baseAction.setJsonObject(JSONObject.fromObject(errorCodeEntity)); return FlagConstants.ERROR_JSON; // "error_json" } else { baseAction.setErrorCode(errorCodeEntity); return FlagConstants.ERROR_PAGE; //"error_page" } } private String handleDataWarningException(Exception e, boolean isAjax) { String errorCode = e.getMessage(); ServletContext context = ServletActionContext.getServletContext(); @SuppressWarnings("unchecked") Map<String, ErrorCode> errorCodeMap = (Map<String, ErrorCode>) context.getAttribute(FlagConstants.ERROR_CODE_MAP); ErrorCode errorCodeEntity = errorCodeMap.get(errorCode); errorCodeEntity.setErrorMessage(baseAction.getText(errorCodeEntity.getErrorMessageKey())); if (isAjax == true) { baseAction.setJsonObject(JSONObject.fromObject(errorCodeEntity)); return FlagConstants.ERROR_JSON; } else { baseAction.setErrorCode(errorCodeEntity); return FlagConstants.ERROR_PAGE; } } private String handleException(boolean isAjax) { String errorCode = ErrorCodeConstants.SERVER_ERROR; ServletContext context = ServletActionContext.getServletContext(); @SuppressWarnings("unchecked") Map<String, ErrorCode> errorCodeMap = (Map<String, ErrorCode>) context.getAttribute(FlagConstants.ERROR_CODE_MAP); ErrorCode errorCodeEntity = errorCodeMap.get(errorCode); if (isAjax) { // Make the JSON object. baseAction.setJsonObject(JSONObject.fromObject(errorCodeEntity)); return FlagConstants.ERROR_JSON; } else { baseAction.setErrorCode(errorCodeEntity); return FlagConstants.ERROR_PAGE; } } @Override public String intercept(ActionInvocation invocation) throws Exception { try { return invocation.invoke(); } catch (Exception e) { baseAction = (BaseAction) invocation.getAction(); HttpServletRequest request = ServletActionContext.getRequest(); boolean isAjax = isAjaxRequest(request); if (e instanceof ServerErrorException) { return handleExceptionByServerErrorException(e, isAjax); } else if (e instanceof DataWarningException) { return handleDataWarningException(e, isAjax); } else { logger.error(e.getStackTrace(), e); return handleException(isAjax); } } }}
struts.xml
<global-results><result name="error_page" type="chain"><param name="actionName">handleError</param><param name="namespace">/error</param></result><result name="error_json" type="json"><param name="root">jsonObject</param></result></global-results>
其中handleError 是用于非ajax时的页面跳转的Action
五、前台处理
/* data: 前台返回的数据 customUrl: 当发生异常要跳转页面时页面的URL finalHandleFunc:弹出对话框后点击对话框后执行的函数 finalHandleFuncParam:上面函数所需参数*/function handleException(data, customUrl, finalHandleFunc, finalHandleFuncParam) { if (data && data.errorCodeId) { // 不跳转页面 if (data.flag == "0") {//先弹出对话框提示错误信息,当点击OK按钮时执行finalHandleFunc函数 initialErrorMsgBar(data.errorMessage, function() { if(finalHandleFunc) { finalHandleFunc(finalHandleFuncParam); } }); } // 跳转页面 if (data.flag == "1") { if (data.errorCodeId == "E0001" || data.errorCodeId == "E0002") {//特殊情况,如无权限情况 window.onbeforeunload = null; window.location.href = $("#basePath").val() + "error/handleError?errorCode.errorCodeId=" + data.errorCodeId; } else if(customUrl){// 自定义跳转页面时,先弹出对话框提示错误信息,在跳错误页面 initialErrorMsgBar(data.errorMessage, function() { window.onbeforeunload = null;window.location = customUrl; }); } else { // 先弹出对话框提示错误信息,再跳到系统默认页面 initialErrorMsgBar(data.errorMessage, function() { window.onbeforeunload = null; window.location = $('#basePath').val() + 'dashboard/dashboard_dashboard'; }); } } return false; } return true;}
0 0
- J2EE项目异常处理
- J2EE项目异常处理
- J2EE项目异常处理
- J2EE项目异常处理
- J2EE项目异常处理
- J2EE项目异常处理
- J2EE项目异常处理
- J2EE项目异常处理
- J2EE项目异常处理
- J2EE项目异常处理
- J2EE项目异常处理
- J2EE项目异常处理
- J2EE项目异常处理
- 项目异常处理
- 项目异常处理架构
- J2EE项目异常处理
- 项目全局异常处理
- J2EE项目异常处理
- liferay6.1之在portal-ext.properties中定义常量
- 程序函数与数学函数概念的区别
- python中自定义函数的使用
- Xcode build 自动更新资源
- ZwMakeTemporaryObject 函数
- 项目异常处理
- UIScrollView类详解
- IOS的变量前加extern和static字段
- 设计模式之策略模式
- poj2653
- 前缀与后缀表达式 【for_wind】
- oracle常用的hint /*+ 提示信息*/
- myEclipse安装svn插件的几种方法
- LeetCode Valid Number