zoukankan      html  css  js  c++  java
  • 三、Action及异常处理

    一、Action介绍

    在Struts2中,Action是最重要的,因为struts2是由多个Action组成的;比如要对业务进行分发都需要使用Action;

    Struts2相比Struts1,采用低侵入式设计,即一个普通的Java类也可以作为一个Action,不一定要继承或实现Action接口;

    而定义Action通常需要遵循几个规范:

    1.可以选择继承ActionSupport;

    2.重写public String execute()throws Exception 方法,此方法是访问Action默认调用的方法(当然可以自己设定调用任意方法,此配置需要在struts.xml进行);

    3.Action类中的属性是用于封装HTTP请求、页面结果数据的在访问Action时,如果带有请求参数,则会通过params拦截器对Action同名的属性进行赋值


     Action和ActionSupport:用于规范action类的处理;


    二、配置Action

    我们在struts.xml中配置Action;

    模板:

    <struts>
    <constant name="struts.devMode" value="true"></constant>
    <package name="" extends="struts-default" namespace="" >
    	<action name="" class="">
                     <param name="name">xiazdong</param>
       		 <result>1.jsp</result>
    	</action>
    </package>
    </struts>
    
    

    配置Action规范:<action>元素必须在<package>中;

    下面开始介绍配置action时的常用元素;

    1.<package>

    package能够用几个属性:

    (1)name:表示包名称,通过随意指定即可;

    (2)extends:继承哪个父包,如果继承了某个父包,则会继承父包的action;通常我们需要继承 struts-default ,此package定义了内建拦截器

    (3)namespace:定义命名空间,如果不指定,则为默认的命名空间;如果为"/",则表示根命名空间;

    (4)abstract:不常用,如果为true,则不能定义action;

    举例:

    <package name="myPackage" namespace="/" extends="struts-default">
    
    </package>
    
    

    默认命名空间和根命名空间:

    默认命名空间是一个很特殊的命名空间,如果要访问一个action,最后都会在默认命名空间中寻找;

    比如/aaa/bbb.action,首先先去命名空间为"/aaa"中去找,如果找不到,则去默认命名空间中寻找bbb.action;

    而根命名空间只是一个普通的命名空间;

    访问某个action时的URL 通常为:  http://localhost:8080/ApplicationName/Namespace/ActionName.action;


    命名空间的查找规则:

    比如 http://localhost:8080/StrutsProject/a/b/c/d/aa.action;

    1.查找是否存在/a/b/c/d 命名空间

        如果不存在,则跳到步骤2

        如果存在则查找是否存在aa.action

            如果不存在该action,则到默认命名空间中查找是否存在aa.action;

            如果存在即可;

    2.查找是否存在/a/b/c 命名空间

        如果不存在,则跳到步骤3

        如果存在则查找是否存在aa.action

            如果不存在该action,则到默认命名空间中查找是否存在aa.action;

            如果存在即可;

    3.查找是否存在/a/b 命名空间

        如果不存在,则跳到步骤4

        如果存在则查找是否存在aa.action

            如果不存在该action,则到默认命名空间中查找是否存在aa.action;

            如果存在即可;

    4.查找是否存在/a 命名空间

        如果不存在,则跳到步骤5

        如果存在则查找是否存在aa.action

            如果不存在该action,则到默认命名空间中查找是否存在aa.action;

            如果存在即可;

    5.查找是否存在/ 命名空间

        如果不存在,则跳到步骤6

        如果存在则查找是否存在aa.action

            如果不存在该action,则到默认命名空间中查找是否存在aa.action;

            如果存在即可;

    6.在默认命名空间中查找;


    2.<action>

    <action>的属性有:

    (1)name:指定了Action的名字,也是对外的URL;

    (2)class:访问此Action的处理类,不指定则默认为ActionSupport,ActionSupport的返回值为SUCCESS,注意:必须要写出类的全名;

    (3)method:如果不指定,则默认调用execute方法,如果指定,则调用此方法;

    3.<result>

    定义了Action的返回结果所对应的JSP(当然可以是任意的视图页面);

    <result>的常用属性为

    (1)name:Action方法返回的字符串,默认为success;

    (2)type:结果类型,默认为dispatcher,此问题在下面会详细讲解;

    代码示例:

    <package name="MyPackage" extends="struts-default" namespace="/" >
    		<action name="loginAction" class="org.login.action.LoginAction" >
    			<result name="success" type="redirect">
    				<param name="location">/result.jsp</param>
    			</result>
    			<result name="error" type="redirect">/result.jsp</result>
    		</action>
    		
    	</package>


     

    逻辑Action和物理Action的区别:

    逻辑Action是在struts.xml中配置的action元素,物理Action是实际的Action类;

    如果某个Action类存在fun1() 和fun2()方法,则可以定义两个逻辑Action,虽然处理类都是一样的;



    局部结果和全局结果:

    全局结果是在<global-results>元素中配置,此结果映射关系对于所有action都起作用;

    局部结果是在<action>元素中配置,是指此结果映射关系只对特定的Action起作用;

    当局部结果和全局结果同时满足要求,则局部结果优先;

    全局结果放在<package>元素中,对于该package的所有Action都有效;

    全局结果的语法:

    <global-results>

        <result> 

        </result>

    </global-results>

      


    4.<param>


    如果是<action>的子元素,用于为action注入值;

    比如

    当HelloAction中有name属性,struts.xml中包含如下代码:

    <action name="hello" class="org.xiazdong.HelloAction">
    	<param name="name">xiazdong</param>
    	<result>/1</result>
    </action>


     

    则执行此action时会自动为name属性赋值;


     

    三、DMI

    Dynamic Method Invocation,即动态决定调用Action的哪个方法,即不是提前配置决定,比如一个页面有登陆按钮和注册按钮,只有一个Action类,里面有login()方法和regist()方法,如果点击注册按钮,则调用regist方法,如果点击登录按钮,则调用login()方法,此时可以使用动态方法调用;

    注意:在struts2.3 中动态方法调用默认开启,因此不需要配置,否则

    <constant name="struts.enable.dynamicMethodInvocation" value="true"></constant>

    默认配置文件:struts2-core-2.3.1.1.jar\org\apache\struts2\default.properties;

    动态方法调用语法:ActionName!methodName

    比如loginAction!login则调用loginAction类中的login方法;

    示例代码:

    LoginAction.java

    package org.login.action;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    public class LoginAction extends ActionSupport{
    	private String user;
    	private String password;
    	private String result;
    	public String login()throws Exception{
    		if(user.equals("xiazdong")&&password.equals("12345")){
    			setResult("登陆成功");
    			return SUCCESS;
    		}
    		else{
    			setResult("登陆失败");
    			return ERROR;
    		}
    	}
    	public String regist()throws Exception{
    		setResult("注册成功");
    		return SUCCESS;
    	}
    	public String getUser() {
    		return user;
    	}
    	public void setUser(String user) {
    		this.user = user;
    	}
    	public String getPassword() {
    		return password;
    	}
    	public void setPassword(String password) {
    		this.password = password;
    	}
    	public void setResult(String result) {
    		this.result = result;
    	}
    	public String getResult() {
    		return result;
    	}
    	
    }


    login.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">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>登录界面</title>
    <script type="text/javascript">
    	function regist(){
    		document.forms[0].action = "loginAction!regist";
    	}
    </script>
    
    </head>
    <body>
    	<form action="loginAction!login">
    		用户名:<input type="text" name="user"/><br />
    		密码:<input type="password" name="password"/><br />
    		<input type="submit" value="登录"/> 
    		<input type="submit" value="注册" onClick="regist();"/>
    	</form>
    </body>
    </html>


    struts.xml

    <?xml version="1.0" encoding="GBK" ?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">
    
    <struts>
    	<constant name="struts.devMode" value="true"></constant>
    	
    	<package name="MyPackage" extends="struts-default" namespace="/" >
    		<action name="loginAction" class="org.login.action.LoginAction" >
    			<result name="success" type="redirect">
    				<param name="location">/result.jsp</param>
    			</result>
    			<result name="error" type="redirect">/result.jsp</result>
    		</action>
    		
    	</package>
    </struts>
    


     

    四、通配符使用

    我们可能会遇到这种情况:需要配置很多个逻辑Action,但是名称上有许多相似的地方,比如:

    <action name="loginAction" class="org.login.action.LoginAction" >
    	<result name="success" type="dispatcher">/result.jsp</result>
    	<result name="error" type="dispatcher">/result.jsp</result>
    </action>
    <action name="registAction" class="org.login.action.registAction" >
    	<result name="success" type="dispatcher">/result.jsp</result>
    	<result name="error" type="dispatcher">/result.jsp</result>
    </action>
    
    

    则如果使用通配符则可以表示成:

    <action name="*Action" class="org.login.action.{1}Action" >
    	<result name="success" type="dispatcher">/result.jsp</result>
    	<result name="error" type="dispatcher">/result.jsp</result>
    </action>
    
     

    在name属性中使用“*”,而在class、method、result元素中都可以使用{1}、{2}表示第一个*的值、第二个*的值;

    <action name="*">时可以匹配任意的action请求,因为他是位于默认命名空间;

    注意:如果同时匹配多个action,则除非完全相同,否则按先后顺序决定;


    {N}表达式可以用于class属性、method属性、result属性;

    在result中还可以使用${attributeName} 通过OGNL表达式引用Action类的属性的值;

    比如 <result>/${name}.jsp


    五、默认Action和默认处理类

    都配置在<package>元素下;

    默认Action是指当全部的action不匹配时,执行此action;

    默认处理类是指如果不指定class属性时的处理类,如果不指定,则是ActionSupport;

    语法分别如下:

    <default-action-ref name="actionName">

    <default-class-ref class="Action"/>

    六、<result>的type属性

    逻辑视图和物理视图的定义:

    逻辑视图是Action处理完后的返回值即String,而物理视图是JSP页面;

    1.dispatcher

    默认值,与JSP相关联;

    2.redirect

    重定向到JSP页面,与dispatcher的区别是:

    dispatcher是服务器跳转;redirect是客户端跳转;

    3.redirectAction

    重定向到另一个Action类;

    <result>子元素<param>可以填写如下两个属性指定Action:

    <result type="redirectAction">

    <param name="actionName">actionname</param>

    <param name="namespace">namespace</param>

    </result> 

    4. stream

    一般用于文件下载,此处不细讲;

    5.plainText

    用于显示视图资源的源代码;

    配置plainText的模板:

    <result type="plainText">

    <param name="location">/index.jsp</param>

    <param name="charSet">UTF-8</param>

    </result>

     七、访问Servlet

    ServletActionContext能够很方便的获得Servlet的常用对象;在execute()方法中通过:

    		HttpServletRequest request = ServletActionContext.getRequest();
    		HttpServletResponse response = ServletActionContext.getResponse();
    		PageContext page = ServletActionContext.getPageContext();
    		ServletContext application = ServletActionContext.getServletContext();
    		HttpSession session = request.getSession();


    获得;


    补充:

    PreResultListener的使用

    PreResultListener触发于执行完Action代码之后、进入物理视图之前;

    模板代码如下:

    ActionInvocation invocation = ActionContext.getContext().getActionInvocation();
    invocation.addPreResultListener(new PreResultListener(){
    	public void beforeResult(ActionInvocation invocation,String resultCode){
    		.....
    	}
    });
    


    八、异常处理

    根据Action的execute方法定义public String execute()throws Exception可知,此方法可以抛出任何异常;因此我们遇到任何异常,只需要抛出,交给struts2的框架即可,框架会通过拦截器exception进行捕捉;

    我们在struts.xml中配置异常处理的方案,当execute抛出异常后,就会在struts.xml 中寻找解决方案;

    异常分为全局异常和局部异常;

    全局异常的语法:

     

    <global-exception-mappings> 
    
        <exception-mapping exception="" result=""/>  
    
    </global-exception-mapping> 
    
    


     

    exception 指定异常所属类;

    result是指逻辑视图名;

    比如:

    <exception-mapping exception="java.sql.SQLException" result="error"/>


     

    局部异常语法:

     

    <action> 
    
     <exception-mapping exception="" result=""/> 
    
    </action>  
    
    

     

    输出异常信息:通过<s:property value="exception.messaeg"/>输出;

    代码:

    ExceptionAction.java

    package org.login.action;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    public class ExceptionAction extends ActionSupport{
    	private String str;
    	public String execute()throws Exception{
    		if("".equals(str) || str==null){
    			throw new NullPointerException();
    		}
    		else{
    			throw new ArithmeticException();
    		}
    	}
    }
    


    struts.xml

    <action name="exceptionAction" class="org.login.action.ExceptionAction">
    			<exception-mapping result="xxxx" exception="java.lang.NullPointerException"></exception-mapping>
    			<exception-mapping result="yyyy" exception="java.lang.ArithmeticException"></exception-mapping>
    			<result name="xxxx">/xxxx.jsp</result>
    			<result name="yyyy">/yyyy.jsp</result>
    		</action>


     

    作者:xiazdong
    出处:http://blog.xiazdong.info
    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
  • 相关阅读:
    纪念这一天,我找到了实习工作
    在编程的道路上坚定地走下去
    今天是1024程序员节
    趣谈函数调用与返回值
    为期3个月的实训结束了,有感而发
    学习编程时遇到难点怎么办?
    今天学习了安卓中的UI线程
    Java程序员要掌握的常用快捷键
    我是一个注重基础的人
    我也有自己的小家啦
  • 原文地址:https://www.cnblogs.com/xiazdong/p/3058087.html
Copyright © 2011-2022 走看看