首先在struts2中有兩種異常處理機制:局部異常映射和全局異常映射。
拿經典的用戶登錄功能來說:
一:局部異常:
1:首先我們的登錄界面:表單交由exAction.action 處理。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<s:form action="exAction" id="form" method="post">
<s:textfield name="username" key="user"/>
<s:textfield name="password" key="pass"/><br/>
<s:submit key="login"/>
</s:form>
</body>
</html>
2:我們先定義一個異常myException:申明message屬性並提供get,set方法,封裝提示信息。該類繼承Exception
package com.mao;
public class myException extends Exception {
private String message;
public myException(String message) {
super(message);
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
3:然後我們的邏輯控制器Action,實現類:ExceptionAction
package com.mao;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class ExceptionAction extends ActionSupport{
private String username;
private String password;
private String tip;
//省略所有屬性的set、get方法
public String execute()throws Exception{
ActionContext act=ActionContext.getContext();
if(getUsername().equalsIgnoreCase("user")){
throw new myException("自定義異常");
}
if(getUsername().equalsIgnoreCase("sql")){
throw new java.sql.SQLException("用戶名不能爲sql");
}
if(getUsername().equals("mao")&&getPassword().equals("3214")){
setTip("服務器提示:登陸成功");
return SUCCESS;
}else{
return ERROR;
}
}
}
代碼很明顯看出,如果用戶名爲user拋出自定義異常,如果爲sql拋出系統定義的SQLException異常,這裏順便說一下equalsIgnoreCase()方法與equals()區別,從字面上也看出來了equalsIgnoreCase()字面不拘小節嘛,所以它不區分大小寫,比如用戶名getUsername.equalsIgnoreCase("mao"),你輸mao和Mao都是可以可以的,而equals()嚴格區分字節和長度,比較苛刻。
4:然後我們的配置文件struts.xml
此處我只列舉出局部異常的部分:
<!-- 定義局部異常和局部結果集 -->
<action name="exAction" class="com.mao.ExceptionAction">
<exception-mapping result="my" exception="com.mao.myException"/>
<result name="my">/ecpt.jsp</result>
<result name="success">/welcom.jsp</result>
<result name="error">/error.jsp</result>
</action>
這裏注意,局部異常是在<action></action>標籤內通過<exception-mapping/>標籤定義的的,而且需要指定結果字符串result="my",和exception="com.mao.myException"異常映射所指定的異常類型,拿此處來講,映射的就是咱們前面定義的myException異常,com.mao爲該類所在的包。可以看出,局部異常全部定義在<action></action>標籤之內。一快看下來就是,前臺表單交給exAction去處理,好,處理的過程中拋出了一個myException異常,然後該異常返回了一個my的結果字符串,然後,在下面<result
name="my">/ecpt.jsp</result>標籤中定義此異常所返回的視圖。這裏也可以發現struts2框架的優點,耦合度低,前臺表單僅傳過來一個action,然後核心控制器filet截獲並匹配相應邏輯控制器action去處理,處理完成後不是直接用視圖的形式顯示出來,而是返回一個字符串my,然後再通過相應字符串映射到相應視圖。這大大提高了代碼的複用性,哪天我們需要映射到不同視圖時,只需修改<result>映射就可以(好了,扯多了)
5:這是返回的ecpt.jsp頁面:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
異常信息:<s:property value="exception.message"/>
</body>
</html>
這裏的exception就是指的咱們定義的異常com.mao.myException.
另外提示一點,本人在測試的時候由於在此頁面中一直沒有加
<%@taglib prefix="s" uri="/struts-tags" %>
這樣就沒法使用struts2標籤,也就一直沒法輸出異常信息,希望大家不要犯此類低級錯誤。
6:運行結果
在表單輸入user或者User
二:全局異常:
1:同樣拿這個用戶登錄界面來講,前面的表單,控制器exAction都已經給出,不再多說,我們直接看Struts.xml配置信息的如何配置全局異常:
<!-- 定義全局結果映射 -->
<global-results>
<result name="sql">/ecpt.jsp</result>
<result name="root">/ecpt.jsp</result>
</global-results>
<!-- 定義全局異常 -->
<global-exception-mappings>
<exception-mapping result="sql" exception="java.sql.SQLException"/>
<exception-mapping result="root" exception="java.lang.Exception"/>
</global-exception-mappings></span></span>
以上就定義了全局結果映射和全局異常映射,可以看出全局結果映射和全局異常都需要包含在<global...></global...>中,相當於,加上這個標籤,你們就牛X了,就可以在全局有用了。說回來:全局異常需要定義在<global-exception-mappings></global-exception-mappings>中,這個標籤就相當於給他們加了牛X屬性,然後再在這裏面通過<exception-mapping result="" exception=""/>標籤定義全局異常映射(與局部相同)另外<exception-mapping/>標籤注意結束形式,全局異常不能定義在<action></action>標籤中,因爲它需要在全局起作用,而不是某個action中起作用。:
2:結果:我們分別輸入sql和正確的用戶名密碼 mao 3214顯示
三:總結:
局部異常映射只對該Action有效,全局異常映射對所有Action有效。
但是局部異常映射"執行力"強,在都局部異常和全局異常都定義了相同映射的情況,程序會先去局部映射尋找相應的<result name="">所返回的視圖,如果有,返回該視圖,如果沒有,那好,去全局映射裏找。
例如:
<global-results>
<result name="my">/welcom.jsp</result>
</global-results>
<!-- 定義全局異常 -->
<global-exception-mappings>
<exception-mapping result="my" exception="com.mao.myException"/>
</global-exception-mappings>
<!-- 定義局部異常和局部結果集 -->
<action name="exAction" class="com.mao.ExceptionAction">
<exception-mapping result="my" exception="com.mao.myException"/>
</action>
如上,我們在局部以及全局異常映射裏都定義了com.mao.myException的映射,而且返回結果字符串都爲my,程序會先去局部找,發現並沒有找到相應的<result name="my">定義的返回視圖,這時他就會去全局找,正好找到有個定義的<result name="my">所以將返回welcom.jsp頁面,記住一句話:在局部映射和全局映射都存在相同<resule
name="">屬性,而且局部異常映射指定了jsp頁面的情況下,全局映射永遠都是"備胎"。