struts2中的異常對映處理機制
阿新 • • 發佈:2019-02-02
首先在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
程式碼很明顯看出,如果使用者名稱為user丟擲自定義異常,如果為sql丟擲系統定義的SQLException異常,這裡順便說一下equalsIgnoreCase()方法與equals()區別,從字面上也看出來了equalsIgnoreCase()字面不拘小節嘛,所以它不區分大小寫,比如使用者名稱getUsername.equalsIgnoreCase("mao"),你輸mao和Mao都是可以可以的,而equals()嚴格區分位元組和長度,比較苛刻。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; } } }
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頁面的情況下,全域性對映永遠都是"備胎"。