j2EE 分层模式中的异常架构设计
2009-02-04 10:50
363 查看
Java引入了异常处理给程序调试带来的方便,但给客户带来的烦恼,任何客户都不希望看到一大串堆栈信息。这篇文章就是纪念一个教训。
事件缘由:老板在给客户做演示的时候,出现长串堆栈信息。尽管之前我们做过很多测试,都没有出现问题。因为数据库数据不完整性带来的灾难被老板碰到了。这让我们感到很尴尬。决定彻底解决这类隐患。
设计背景:
我们系统采用3层结构。即 DAO,SERVICE, ACTION(strut2)。DAO利用spring对hibernate的封装实现。 service 是核心业务逻辑的实现,同时也是事务处理层。action扮演controllor层的作用。
设计过程:
1,dao层的异常分可预测,和不可预测。
在可预测的异常我们可以抛给service层处理,有些包含了很有用的信息。如入户名重复的异常。
不可预测的异常我们可以自己封装起来,然后重现包装自定义的异常抛给servic处理。
2,servic层的异常也和dao一样。分两中。处理雷同。
3,在action中我们利用struts2的设计理念。action中可以处理任何来自底层的异常。这样如果是有用的信息,我们可以抛给用户,以便提示用户。如果是更友好点,我们可以包装起来抛出。抛给struts2,让她来处理。只要在struts.xml中配置相关处理即可。这样可以统一处理异常。也可以分类处理异常。重用性比较高。也灵活。减少手动编程。
4,框架本身的异常。struts2等框架自身有时候也会有异常抛出。当然这种情况很少。只要有可能,我们就要预防。以防患于未然。做法也很简单 在web.xml 中配置 <error-page> 标签的信息。这样有服务容器来处理并定向到指定的页面。
编码实现:
1,自定义异常(主要用于包装异常)
public class AMPException extends RuntimeException {
private static final long serialVersionUID = -3888868544018808942L;
public String errorCode;
public AMPException(String message) {
super(message);
}
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
}
public class ActionException extends AMPException {
private static final long serialVersionUID = 7637165153080210218L;
public ActionException(String message) {
super(message);
}
}
public class ServiceException extends AMPException {
private static final long serialVersionUID = 4872117656104037525L;
public ServiceException(String message) {
super(message);
}
}
public class DaoException extends AMPException{
private static final long serialVersionUID = 8037899278793078796L;
public DaoException(String message) {
super(message);
}
}
2接口 定义如下(以service为例,dao层类似)
public interface SigProfileManager {
/**
* Save a profile's information
* @param sigProfile the SigProfile object
* @return the SigProfile object
* @throws Exception
* */
SigProfile saveSigProfile(SigProfile sigProfile) throws Exception;
}
实现类
public class SigProfileManagerImpl implements SigProfileManager {
public SigProfile saveSigProfile(SigProfile sigProfile) throws Exception {
try {
// 逻辑处理代码
} catch (Exception e) {
throw new ServiceException(errorMsg + e.getMessage());
}
}
}
3action 层。可以处理也可不处理。这要看业务逻辑本身,和信息本身是否需要重包装。更重的是的
controllor层自身是否有异常处理机制。一般比较成熟的框架都会有异常的处理机制的。
public class SigProfileAction extends BaseAction {
public String list() throws Exception{
try {
//service tie call
} catch (Exception e) {
throw new ActionException(errorMsg + e.getMessage());
}
return SUCCESS;
}
}
我用的是struts2,处理配置起来很方便在struts2.xml 中有两个地方可以配置
1,批量处理。可以处理每个action的异常
<global-exception-mappings>
<exception-mapping exception="org.springframework.dao.DataAccessException" result="dataAccessFailure"/>
<exception-mapping exception="java.lang.Exception" result="dataAccessFailure"/>
</global-exception-mappings>
2,单个处理
<action name="users" class="userAction" method="list">
<interceptor-ref name="adminCheck"/>
<result name="success">/WEB-INF/pages/admin/userList.jsp</result>
<result name="failure">/WEB-INF/pages/admin/error.jsp</result>
<exception-mapping exception="java.lang.Exception" result="failure"/>
</action>
4,容器处理
<error-page>
<error-code>500</error-code>
<location>/error.jsp</location>
</error-page>
事件缘由:老板在给客户做演示的时候,出现长串堆栈信息。尽管之前我们做过很多测试,都没有出现问题。因为数据库数据不完整性带来的灾难被老板碰到了。这让我们感到很尴尬。决定彻底解决这类隐患。
设计背景:
我们系统采用3层结构。即 DAO,SERVICE, ACTION(strut2)。DAO利用spring对hibernate的封装实现。 service 是核心业务逻辑的实现,同时也是事务处理层。action扮演controllor层的作用。
设计过程:
1,dao层的异常分可预测,和不可预测。
在可预测的异常我们可以抛给service层处理,有些包含了很有用的信息。如入户名重复的异常。
不可预测的异常我们可以自己封装起来,然后重现包装自定义的异常抛给servic处理。
2,servic层的异常也和dao一样。分两中。处理雷同。
3,在action中我们利用struts2的设计理念。action中可以处理任何来自底层的异常。这样如果是有用的信息,我们可以抛给用户,以便提示用户。如果是更友好点,我们可以包装起来抛出。抛给struts2,让她来处理。只要在struts.xml中配置相关处理即可。这样可以统一处理异常。也可以分类处理异常。重用性比较高。也灵活。减少手动编程。
4,框架本身的异常。struts2等框架自身有时候也会有异常抛出。当然这种情况很少。只要有可能,我们就要预防。以防患于未然。做法也很简单 在web.xml 中配置 <error-page> 标签的信息。这样有服务容器来处理并定向到指定的页面。
编码实现:
1,自定义异常(主要用于包装异常)
public class AMPException extends RuntimeException {
private static final long serialVersionUID = -3888868544018808942L;
public String errorCode;
public AMPException(String message) {
super(message);
}
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
}
public class ActionException extends AMPException {
private static final long serialVersionUID = 7637165153080210218L;
public ActionException(String message) {
super(message);
}
}
public class ServiceException extends AMPException {
private static final long serialVersionUID = 4872117656104037525L;
public ServiceException(String message) {
super(message);
}
}
public class DaoException extends AMPException{
private static final long serialVersionUID = 8037899278793078796L;
public DaoException(String message) {
super(message);
}
}
2接口 定义如下(以service为例,dao层类似)
public interface SigProfileManager {
/**
* Save a profile's information
* @param sigProfile the SigProfile object
* @return the SigProfile object
* @throws Exception
* */
SigProfile saveSigProfile(SigProfile sigProfile) throws Exception;
}
实现类
public class SigProfileManagerImpl implements SigProfileManager {
public SigProfile saveSigProfile(SigProfile sigProfile) throws Exception {
try {
// 逻辑处理代码
} catch (Exception e) {
throw new ServiceException(errorMsg + e.getMessage());
}
}
}
3action 层。可以处理也可不处理。这要看业务逻辑本身,和信息本身是否需要重包装。更重的是的
controllor层自身是否有异常处理机制。一般比较成熟的框架都会有异常的处理机制的。
public class SigProfileAction extends BaseAction {
public String list() throws Exception{
try {
//service tie call
} catch (Exception e) {
throw new ActionException(errorMsg + e.getMessage());
}
return SUCCESS;
}
}
我用的是struts2,处理配置起来很方便在struts2.xml 中有两个地方可以配置
1,批量处理。可以处理每个action的异常
<global-exception-mappings>
<exception-mapping exception="org.springframework.dao.DataAccessException" result="dataAccessFailure"/>
<exception-mapping exception="java.lang.Exception" result="dataAccessFailure"/>
</global-exception-mappings>
2,单个处理
<action name="users" class="userAction" method="list">
<interceptor-ref name="adminCheck"/>
<result name="success">/WEB-INF/pages/admin/userList.jsp</result>
<result name="failure">/WEB-INF/pages/admin/error.jsp</result>
<exception-mapping exception="java.lang.Exception" result="failure"/>
</action>
4,容器处理
<error-page>
<error-code>500</error-code>
<location>/error.jsp</location>
</error-page>
相关文章推荐
- j2EE 分层模式中的异常架构设计
- VO(DTO)模式在分层架构设计中是否需要的扯淡
- J2EE架构下系统设计模式
- 软件设计分层模式(三层架构)
- VO(DTO)模式在分层架构设计中是否需要的扯淡
- 多层J2EE系统的架构与模式设计
- 『设计模式』分层架构设计原则
- 项目开发中的一些注意事项以及技巧总结 基于Repository模式设计项目架构—你可以参考的项目架构设计 Asp.Net Core中使用RSA加密 EF Core中的多对多映射如何实现? asp.net core下的如何给网站做安全设置 获取服务端https证书 Js异常捕获
- J2EE架构下系统设计模式
- VO(DTO)模式在分层架构设计中是否需要的扯淡
- VO(DTO)模式在分层架构设计中是否需要的扯淡
- .net平台分层架构于设计模式的初步探讨
- 【J2EE】:MVC是框架?是设计模式?是架构?还是……
- 软件架构设计原则和模式(上):分层架构设计
- J2EE之DAO设计模式
- 软件体系架构模式在J2EE中的应用 收藏
- 架构设计:生产者/消费者模式 第4页:注意事项
- Unity应用架构设计(1)—— MVVM 模式的设计和实施(Part 1)
- Java学习笔记四。设计模式、基本数据类型、包装类、异常、断言、包、访问权限、命名规范、jar
- Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析