Struts2框架学习(第四讲)

来源:互联网 发布:vue.js tomcat 编辑:程序博客网 时间:2024/06/05 02:48

Struts2的action知识介绍
1、Struts2拦截器及原理

拦截器的工作原理:当接收到一个httprequest ,1)当外部的httpservletrequest到来时 2)初始到了servlet容器 传递给一个标准的过滤器链 3)FilterDispatecher会去查找相应的ActionMapper,如果找到了相应的ActionMapper它将会将控制权限交给ActionProxy 4)ActionProxy将会通过ConfigurationManager来查找配置struts.xml    a. 下一步将会 通过ActionInvocation来负责命令模式的实现(包括调用一些拦截Interceptor框架在调用action之前)    b. Interceptor做一些拦截或者初始的工作 e)一旦action返回,会查找相应的Result 5)Result类型可以是 jsp或者freeMark 等 6)这些组件和ActionMapper一起返回给请求的url(注意拦截器的执行顺序) 7)响应的返回是通过我们在web.xml中配置的过滤器 8)如果ActionContextCleanUp是当前使用的,则FilterDispatecher将不会清理sreadlocal ActionContext;如果ActionContextCleanUp不使用,则将会去清理sreadlocals。
拦截器实现原理:1)拦截器是基于java反射机制的,而过滤器是基于函数回调的。2)过滤器依赖于servlet容器,而拦截器不依赖于servlet容器。3)拦截器只能对Action请求起作用,而过滤器则可以对几乎所有请求起作用。4)拦截器可以访问Action上下文、值栈里的对象,而过滤器不能。5)在Action的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化时被调用一次。

2、我们在自己写action可以选择实现Action接口或者继承ActionSupport,两者的区别是什么呢?
Action接口:

public static final java.lang.String SUCCESS ="success";   public static final java.lang.String NONE = "none";   public static final java.lang.String ERROR = "error";   public static final java.lang.String INPUT = "input";      public static final java.lang.String LOGIN = "login";   public abstract java.lang.String execute() throws java.lang.Exception;   

而Actionsupport这个工具类在实现了Action接口的基础上还定义了一个validate()方法,重写该方法,它会在execute()方法之前执行,如校验失败,会转入input处,必须在配置该Action时配置input属性。如果没有重写validate()方法,可不用配置action的input属性。
struts2不要求我们自己设计的action类继承任何的struts基类或struts接口,但是我们为了方便实现我们自己的action,大多数情况下都会继承com.opensymphony.xwork2.ActionSupport类,并重写此类里的public String execute() throws Exception方法。因为此类中实现了很多的实用借口,提供了很多默认方法,这些默认方法包括国际化信息的方法、默认的处理用户请求的方法等,这样可以大大的简化Acion的开发。

3、action数据校验
在应用中,即使浏览者输入任何用户名、密码,系统也会处理用户请求。在我们整个应用中,这种空用户名、空密码的情况不会引起太大的问题。但如果数据需要保存到数据库,或者需要根据用户输入的用户名、密码查询数据,这些空输入可能引起异常。为了避免用户的输入引起底层异常,通常我们会在进行业务逻辑操作之前,先执行基本的数据校验。
Action数据校验功能是struts2给我们提供的一个服务器端简单验证的功能,这个功能使我们简化了一些没必要的代码。
action校验的实现过程:
1)继承ActionSupport

ActionSupport类是一个工具类,它已经实现了Action接口。除此之外,它还实现了Validateable接口,提供了数据校验功能。通过继承该ActionSupport类,可以简化Struts 2的Action开在Validatable接口中定义了一个validate()方法,重写该方法,如果校验表单输入域出现错误,则将错误添加到ActionSupport类的fieldErrors域中,然后通过OGNL表达式负责输出为了让Struts 2增加输入数据校验的功能,改写程序中的LoginAction,增加重写validate方法。下面看一下具体代码实现:package com.test.action;   import com.opensymphony.xwork2.ActionSupport;    public class LoginAction extends ActionSupport {    private String username;    private String password;  public String getUsername() {       return username;    }  public void setUsername(String username) {       this.username = username;    }  public String getPassword() {       return password;    }  public void setPassword(String password) {       this.password = password;    }  public void validate() {       if("".equals(username))       this.addActionError("soory,the username can't blank");      if("".equals(password))       this.addActionError("soory,the password can't blank");   //if(user.getUname().length()==0){   //addFieldError("uname", "soory,the username can't    blank");   //}   //或者   //this.addActionMessage("soory,the username can't  blank");   }  public String execute(){    if(username.equals("admin")&&password.equals("123456"))       return "success";       return "fail";    }    } 这里简单的实现了表单数据验证功能,上面的Action类重写了validate方法,该方法会在执行系统的execute方法之前执行,如果执行该方法之后,Action类的fieldErrors中已经包含了数据校验错误,请求将被转发到input逻辑视图处。但还是要注意以下几点:1.在实现表单验证功能的时候一定不要忘记了在struts.xml中相对应的action中配置result=“input”,因为表单验证失败默认返回的字符串为input,如果没有的话会找不到这个结果而报错。2.数据验证中,如果数据不符的时候可以报三种错误,我们上面代码中只是列举了action错误,另外两种是Field字段的错误,还有一种就是actionMessage。3.注意在显示界面接收action错误时,要在想显示错误的地方加上 <s:actionerror/>标签,如果想接收Filed域的错误时,一定要用struts标签,如果不用的话是不会显示字段错误的

2)使用Struts 2的校验框架

上面的输入校验是通过重写ActionSupport类的validate方法实现的,这种方法虽然不错,但需要大量重写的validate方法——毕竟,重复书写相同的代码不是一件吸引人的事情。类似于Struts1,Struts2也允许通过定义配置文件来完成数据校验。Struts2的校验框架实际上是基于XWork的validator框架。下面还是使用原来的Action类(即不重写validate方法),却增加一个校验配置文件,校验配置文件通过使用Struts2已有的校验器,完成对表单域的校验。Struts2提供了大量的数据校验器,包括表单域校验器和非表单域校验器两种。本应用主要使用了requiredstring校验器,该校验器是一个必填校验器——指定某个表单域必须输入。下面是校验规则的定义文件:    <?xml version="1.0" encoding="UTF-8"?>       <!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">  <validators>  <field name="username">  <field-validator type="requiredstring">  <param name="trim">false</param>     <message>username can't be blank!</message>     </field-validator>      <field-validator type="stringlength"> <param name="minLength">4</param>      <param name="maxLength">6</param>  <param name="trim">false</param>     <message key="username.invalid"></message>      </field-validator>  </field>  <field name="password">      <field-validator type="requiredstring">      <message>password can't be blank!</message>       </field-validator>   <field-validator type="stringlength">      <param name="minLength">4</param>    <param name="maxLength">6</param>    <message>length of password should be between ${minLength} and ${maxLength}</message>    </field-validator>  </field>  <field name="age">  <field-validator type="required">      <message>age can't be blank!</message>      </field-validator>     <field-validator type="int">      <param name="min">10</param>      <param name="max">40</param>  <message>age should be between ${min} and ${max}</message>      </field-validator>      </field>  </validators>  定义完该校验规则文件后,该文件的命名应该遵守如下规则:ActionName-validation.xml:其中ActionName就是需要校验的Action的类名。因此上面的校验规则文件应该命名为“LoginAction-validation.xml”,且该文件应该与Action类的class文件位于同一个路径下。因此,将上面的校验规则文件放在WEB-INF/classes/lee路径下即可。当然,在struts.xml文件的Action定义中,一样需要定义input的逻辑视图名,将input逻辑视图映射到login.jsp页面。在这种校验方式下,无需书写校验代码,只需要通过配置文件指定校验规则即可,因此提供了更好的可维护性。

3)action中的执行方法
Action中默认的执行方法是execute方法,这个方法执行请求,然后转向其他的页面,这是常规的做法,但有时候我们不想用这个方法名,为了代码的可读性,我们希望让他执行我们自己定义的方法,下面我们就来看一下执行其他方法的方法:

1.在struts.xml配置method属性其实执行execute方法是对应action在配置文件method的默认方法,所以要想执行其他的方法,我们可以修改这里的默认方法,只要把默认的方法改为我们自定义的方法就可以了。部分配置代码:<action name="LoginAction" class="com.test.action.LoginAction" method="login">  <result name="success">success.jsp</result>     <result name="fail">fail.jsp</result>  <result name="input">login.jsp</result>  </action>  <action name="RegisteAction" class="com.test.action.LoginAction" method="registe">     <result name="success">success.jsp</result>  <result name="fail">fail.jsp</result>  <result name="input">login.jsp</result>  </action>  
2.DMI(动态直接调用)这种方法,不需要进行struts.xml的配置。而是在html或者jsp页面中通过标示符号指定了要调用的方法。 关键的标示符号为"!"号,具体看一下下面表单:<s:form action="LoginAction!login">     <s:actionerror/>  username:<s:textfield name="username"></s:textfield>      password:<s:password name="password"></s:password>  <s:submit value="提交"></s:submit>   </s:form>  
3.提交按钮指定提交方法,普通的提交按钮我们会这么写: <s:submit value="提交"></s:submit>当我们想提交到我们指定的方法时我们可以在这个标签里添加一个method属性指定要提交的方法,如下:<s:submit value="提交" method="login"></s:submit>  
4.使用通配符配置Action,这种方法可以解决action配置文件混乱的问题,减少action的配置:<action name="test_*" class="com.test.action.HelloWorld" method="{1}">   <result name="success">/WEB-INF/jsp{1}_success.jsp</result>     </action>  在name属性的值后面加上*,意思是只要你请求的action名字以helloworld开头,本action就是你找的action,然后method是大括号加上1,这个1代表第一个星号的值,这样就可以动态执行请求的方法。<s:form action="test_add"> <s:form action="test_delete"> 上面两个表单提交会分别提交到HelloWord的action中对应的add()和delete()方法中。

最后说一点,有时候用户在地址栏随便输入的时候,找不到对应的action,直接对报出一些错误,这样的界面一般都很难看,所以为了能给用户一个友好的提示界面,一般我们会再struts.xml文件配置默认的action,代码如下:

<struts><package name="default" extends="struts-default">   <default-action-ref name="defaultAction" />      <action name="defaultAction">           <result name="input">/save.jsp</result>      </action>   </package></struts>      
0 0
原创粉丝点击