首先我们的国际化资源文件中有
- user.not.found = 用户不能找到,用户名称=[{0}]
- user.password.error = user.password.error
第一种 声明式异常处理
为国际化配置文件中的每个key,设计一个异常。
用户登录验证,用户名错误抛出UserNotFoundException,密码错误抛出PasswordErrorException
代码
public
void
login(String username, String password) {
if ( ! " admin " .equals()) {
throw new UserNotFoundException();
}
if ( ! " admin " .equals(password)) {
throw new PasswordErrorException();
}
}
if ( ! " admin " .equals()) {
throw new UserNotFoundException();
}
if ( ! " admin " .equals(password)) {
throw new PasswordErrorException();
}
}
struts-config.xml文件中,<exception/>的key对应国际化配置文件中key,type是对应的异常处理类
代码
<
global-exceptions
>
<!-- 为所有Action使用的,全局异常 -->
< exception key ="user.not.found" type ="demo.struts.UserNotFoundException" />
< exception key ="user.password.error" type ="demo.struts.PasswordErrorException" />
</ global-exceptions >
< action-mappings >
< action path ="/login"
type ="demo.struts.LoginAction"
name ="loginForm"
scope ="request"
validate ="false"
input ="/login.jsp"
>
<!-- path 错误时候 跳转的页面,优先级高于 action中的input -->
<!-- 为每一个action配置
<exception key="user.not.found" type="demo.struts.UserNotFoundException" path="/login_error.jsp"/>
<exception key="user.password.error" type="demo.struts.PasswordErrorException" path="/login_error.jsp"/>
-->
< forward name ="success" path ="/login_success.jsp" />
< forward name ="error" path ="/login.jsp" />
</ action >
< action path ="/changelang"
type ="demo.struts.ChangeLanguageAction"
>
< forward name ="index" path ="/index.jsp" />
</ action >
</ action-mappings >
<!-- 为所有Action使用的,全局异常 -->
< exception key ="user.not.found" type ="demo.struts.UserNotFoundException" />
< exception key ="user.password.error" type ="demo.struts.PasswordErrorException" />
</ global-exceptions >
< action-mappings >
< action path ="/login"
type ="demo.struts.LoginAction"
name ="loginForm"
scope ="request"
validate ="false"
input ="/login.jsp"
>
<!-- path 错误时候 跳转的页面,优先级高于 action中的input -->
<!-- 为每一个action配置
<exception key="user.not.found" type="demo.struts.UserNotFoundException" path="/login_error.jsp"/>
<exception key="user.password.error" type="demo.struts.PasswordErrorException" path="/login_error.jsp"/>
-->
< forward name ="success" path ="/login_success.jsp" />
< forward name ="error" path ="/login.jsp" />
</ action >
< action path ="/changelang"
type ="demo.struts.ChangeLanguageAction"
>
< forward name ="index" path ="/index.jsp" />
</ action >
</ action-mappings >
Struts的RequestProcessor类
代码
protected
ActionForward processException(HttpServletRequest request,
HttpServletResponse response,
Exception exception,
ActionForm form,
ActionMapping mapping)
throws IOException, ServletException {
// 是否在配置了Exception
ExceptionConfig config = mapping.findException(exception.getClass());
// 找到的config就是下面这条信息
// <exception key="user.not.found" type="demo.struts.UserNotFoundException" path="/login_error.jsp"/>
if (config == null ) {
// 没有配置,struts不管了,往web容器里抛,看在web.xml文件中是否配置,
// 如果仍没有配置,则把异常显示到页面上
log.warn(getInternal().getMessage( " unhandledException " ,
exception.getClass()));
if (exception instanceof IOException) {
throw (IOException) exception;
} else if (exception instanceof ServletException) {
throw (ServletException) exception;
} else {
throw new ServletException(exception);
}
}
// struts异常默认处理类
try {
ExceptionHandler handler = (ExceptionHandler)
RequestUtils.applicationInstance(config.getHandler());
return (handler.execute(exception, config, mapping, form,
request, response));
} catch (Exception e) {
throw new ServletException(e);
}
}
HttpServletResponse response,
Exception exception,
ActionForm form,
ActionMapping mapping)
throws IOException, ServletException {
// 是否在配置了Exception
ExceptionConfig config = mapping.findException(exception.getClass());
// 找到的config就是下面这条信息
// <exception key="user.not.found" type="demo.struts.UserNotFoundException" path="/login_error.jsp"/>
if (config == null ) {
// 没有配置,struts不管了,往web容器里抛,看在web.xml文件中是否配置,
// 如果仍没有配置,则把异常显示到页面上
log.warn(getInternal().getMessage( " unhandledException " ,
exception.getClass()));
if (exception instanceof IOException) {
throw (IOException) exception;
} else if (exception instanceof ServletException) {
throw (ServletException) exception;
} else {
throw new ServletException(exception);
}
}
// struts异常默认处理类
try {
ExceptionHandler handler = (ExceptionHandler)
RequestUtils.applicationInstance(config.getHandler());
return (handler.execute(exception, config, mapping, form,
request, response));
} catch (Exception e) {
throw new ServletException(e);
}
}
struts默认的exceptionHandler
代码
public
ActionForward execute(
Exception ex,
ExceptionConfig ae,
ActionMapping mapping,
ActionForm formInstance,
HttpServletRequest request,
HttpServletResponse response)
throws ServletException {
ActionForward forward = null ;
ActionMessage error = null ;
String property = null ;
// 在<exception>中配置了path,返回actionForward就是path中的配置
if (ae.getPath() != null ) {
forward = new ActionForward(ae.getPath());
} else {
// 没有配置的话,返回actionForward就是<action>中的input
forward = mapping.getInputForward();
}
// Figure out the error
if (ex instanceof ModuleException) {
error = ((ModuleException) ex).getActionMessage();
property = ((ModuleException) ex).getProperty();
} else {
// 我们写的程序抛出的异常都是这种情况
// 从国际化文件中,根据key取
// ae.getKey() -- 拿到<exception>中key值 user.not.found
error = new ActionMessage(ae.getKey(), ex.getMessage());
// 集合ActionMessages中的key,和国际化资源文件中的key一样
property = error.getKey();
}
this .logException(ex);
// Store the exception
request.setAttribute(Globals.EXCEPTION_KEY, ex);
// 放到ActionMessages集合中 getScope()默认request
this .storeException(request, property, error, forward, ae.getScope());
return forward;
Exception ex,
ExceptionConfig ae,
ActionMapping mapping,
ActionForm formInstance,
HttpServletRequest request,
HttpServletResponse response)
throws ServletException {
ActionForward forward = null ;
ActionMessage error = null ;
String property = null ;
// 在<exception>中配置了path,返回actionForward就是path中的配置
if (ae.getPath() != null ) {
forward = new ActionForward(ae.getPath());
} else {
// 没有配置的话,返回actionForward就是<action>中的input
forward = mapping.getInputForward();
}
// Figure out the error
if (ex instanceof ModuleException) {
error = ((ModuleException) ex).getActionMessage();
property = ((ModuleException) ex).getProperty();
} else {
// 我们写的程序抛出的异常都是这种情况
// 从国际化文件中,根据key取
// ae.getKey() -- 拿到<exception>中key值 user.not.found
error = new ActionMessage(ae.getKey(), ex.getMessage());
// 集合ActionMessages中的key,和国际化资源文件中的key一样
property = error.getKey();
}
this .logException(ex);
// Store the exception
request.setAttribute(Globals.EXCEPTION_KEY, ex);
// 放到ActionMessages集合中 getScope()默认request
this .storeException(request, property, error, forward, ae.getScope());
return forward;
第二种 个性化异常处理
代码
public
void
login(String username, String password) {
if ( ! " admin " .equals(username)) {
// user.not.found资源文件中的key, username 占位符
throw new ErrorCodeException( " user.not.found " , username);
}
if ( ! " admin " .equals(password)) {
throw new ErrorCodeException( " user.password.error " );
}
if ( ! " admin " .equals(username)) {
// user.not.found资源文件中的key, username 占位符
throw new ErrorCodeException( " user.not.found " , username);
}
if ( ! " admin " .equals(password)) {
throw new ErrorCodeException( " user.password.error " );
}
代码
<
global-exceptions
>
<!-- key值随便配一个 具体的是在程序中控制 -->
<!-- type异常类 handler异常处理类 都是由我们来写和控制 -->
< exception key ="error.exception" type ="demo.struts.ErrorCodeException" handler ="demo.struts.ErrorCodeExceptionHandler" />
</ global-exceptions >
<!-- key值随便配一个 具体的是在程序中控制 -->
<!-- type异常类 handler异常处理类 都是由我们来写和控制 -->
< exception key ="error.exception" type ="demo.struts.ErrorCodeException" handler ="demo.struts.ErrorCodeExceptionHandler" />
</ global-exceptions >
代码
public
class
ErrorCodeException
extends
RuntimeException {
// 错误码就是国际化资源文件的key
private String errorCode;
// 占位符
private Object[] args;
public ErrorCodeException(String errorCode) {
this (errorCode, null );
}
public ErrorCodeException(String errorCode, Object arg) {
this (errorCode, new Object[]{arg});
}
public ErrorCodeException(String errorCode, Object[] args){
this .errorCode = errorCode;
this .args = args;
}
// 只提供get方法
public String getErrorCode() {
return errorCode;
}
public Object[] getArgs() {
return args;
}
// 错误码就是国际化资源文件的key
private String errorCode;
// 占位符
private Object[] args;
public ErrorCodeException(String errorCode) {
this (errorCode, null );
}
public ErrorCodeException(String errorCode, Object arg) {
this (errorCode, new Object[]{arg});
}
public ErrorCodeException(String errorCode, Object[] args){
this .errorCode = errorCode;
this .args = args;
}
// 只提供get方法
public String getErrorCode() {
return errorCode;
}
public Object[] getArgs() {
return args;
}
代码
public
class
ErrorCodeExceptionHandler
extends
ExceptionHandler {
public ActionForward execute(Exception ex, ExceptionConfig ae,
ActionMapping mapping, ActionForm formInstance,
HttpServletRequest request, HttpServletResponse response)
throws ServletException {
// 不是ErrorCodeException,我们不处理
if ( ! (ex instanceof ErrorCodeException)) {
return super .execute(ex, ae, mapping, formInstance, request, response);
}
ActionForward forward = null ;
ActionMessage error = null ;
String property = null ;
// Build the forward from the exception mapping if it exists
// or from the form input
if (ae.getPath() != null ) {
forward = new ActionForward(ae.getPath());
} else {
forward = mapping.getInputForward();
}
// Figure out the error
if (ex instanceof ModuleException) {
error = ((ModuleException) ex).getActionMessage();
property = ((ModuleException) ex).getProperty();
} else {
// 原来的代码 error = new ActionMessage(ae.getKey(), ex.getMessage());
// ae.getKey() 拿出的key是配置文件中<exception>写的,因为所有异常都用同一个key
// 无法找到国际化资源文件中的key,好在我们在抛异常时,把key写进异常的errorCode中
ErrorCodeException ece = (ErrorCodeException) ex;
// 拿到errorCode
String errorCode = ece.getErrorCode();
// 拿到占位符
Object[] args = ece.getArgs();
error = new ActionMessage(errorCode, args);
property = error.getKey();
}
this .logException(ex);
// Store the exception
request.setAttribute(Globals.EXCEPTION_KEY, ex);
this .storeException(request, property, error, forward, ae.getScope());
return forward;
}
public ActionForward execute(Exception ex, ExceptionConfig ae,
ActionMapping mapping, ActionForm formInstance,
HttpServletRequest request, HttpServletResponse response)
throws ServletException {
// 不是ErrorCodeException,我们不处理
if ( ! (ex instanceof ErrorCodeException)) {
return super .execute(ex, ae, mapping, formInstance, request, response);
}
ActionForward forward = null ;
ActionMessage error = null ;
String property = null ;
// Build the forward from the exception mapping if it exists
// or from the form input
if (ae.getPath() != null ) {
forward = new ActionForward(ae.getPath());
} else {
forward = mapping.getInputForward();
}
// Figure out the error
if (ex instanceof ModuleException) {
error = ((ModuleException) ex).getActionMessage();
property = ((ModuleException) ex).getProperty();
} else {
// 原来的代码 error = new ActionMessage(ae.getKey(), ex.getMessage());
// ae.getKey() 拿出的key是配置文件中<exception>写的,因为所有异常都用同一个key
// 无法找到国际化资源文件中的key,好在我们在抛异常时,把key写进异常的errorCode中
ErrorCodeException ece = (ErrorCodeException) ex;
// 拿到errorCode
String errorCode = ece.getErrorCode();
// 拿到占位符
Object[] args = ece.getArgs();
error = new ActionMessage(errorCode, args);
property = error.getKey();
}
this .logException(ex);
// Store the exception
request.setAttribute(Globals.EXCEPTION_KEY, ex);
this .storeException(request, property, error, forward, ae.getScope());
return forward;
}
如果我们不想写国际化配置文件,在程序中之际页面提示内容
<!--
用默认的handler也能能执行
-->
< exception key ="error.exception" type ="demo.struts.AppException" handler ="demo.struts.AppExceptionHandler" />
< exception key ="error.exception" type ="demo.struts.AppException" handler ="demo.struts.AppExceptionHandler" />
国际化资源文件:
- # 只有一个占位符
- error.exception={0}
代码public void login(String username, String password) {
if ( ! " admin " .equals(username)) {
// 直接写内容
throw new AppException( " 用户不能找到【 " + username + " 】 " );
}
if ( ! " admin " .equals(password)) {
throw new ErrorCodeException( " 密码错误 " );
}
}
public
class
AppException
extends
RuntimeException {
public AppException(String msg){
super (msg);
}
}
public AppException(String msg){
super (msg);
}
}
代码
public
class
AppExceptionHandler
extends
ExceptionHandler {
public ActionForward execute(Exception ex, ExceptionConfig ae,
ActionMapping mapping, ActionForm formInstance,
HttpServletRequest request, HttpServletResponse response)
throws ServletException {
if ( ! (ex instanceof AppException)){
return super .execute(ex, ae, mapping, formInstance, request, response);
}
ActionForward forward = null ;
ActionMessage error = null ;
String property = null ;
// Build the forward from the exception mapping if it exists
// or from the form input
if (ae.getPath() != null ) {
forward = new ActionForward(ae.getPath());
} else {
forward = mapping.getInputForward();
}
// Figure out the error
if (ex instanceof ModuleException) {
error = ((ModuleException) ex).getActionMessage();
property = ((ModuleException) ex).getProperty();
} else {
AppException appe = (AppException) ex;
// ae.getKey() 没用
// appe.getMessage() ("用户不能找到【" + username + "】
error = new ActionMessage(ae.getKey(), appe.getMessage());
property = error.getKey();
}
this .logException(ex);
// Store the exception
request.setAttribute(Globals.EXCEPTION_KEY, ex);
this .storeException(request, property, error, forward, ae.getScope());
return forward;
}
public ActionForward execute(Exception ex, ExceptionConfig ae,
ActionMapping mapping, ActionForm formInstance,
HttpServletRequest request, HttpServletResponse response)
throws ServletException {
if ( ! (ex instanceof AppException)){
return super .execute(ex, ae, mapping, formInstance, request, response);
}
ActionForward forward = null ;
ActionMessage error = null ;
String property = null ;
// Build the forward from the exception mapping if it exists
// or from the form input
if (ae.getPath() != null ) {
forward = new ActionForward(ae.getPath());
} else {
forward = mapping.getInputForward();
}
// Figure out the error
if (ex instanceof ModuleException) {
error = ((ModuleException) ex).getActionMessage();
property = ((ModuleException) ex).getProperty();
} else {
AppException appe = (AppException) ex;
// ae.getKey() 没用
// appe.getMessage() ("用户不能找到【" + username + "】
error = new ActionMessage(ae.getKey(), appe.getMessage());
property = error.getKey();
}
this .logException(ex);
// Store the exception
request.setAttribute(Globals.EXCEPTION_KEY, ex);
this .storeException(request, property, error, forward, ae.getScope());
return forward;
}