struts2中的異常映射處理機制

首先在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頁面的情況下,全局映射永遠都是"備胎"。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章