Struts2 笔记(2) --Struts传值/跳转/拦截器/注解等
2016-07-13 10:57
405 查看
1.action中如何接受页面传过来的参数
第一种情况:(同名参数) 例如: 通过页面要把id=1 name=tom age=20这三个参数传给action 1.action里面定义三个成员变量id name age,这个三个变量的名字一定要和所传变量的名字一致. 2.提供get/set方法 3.将来页面把这三个参数传过来的时候,struts2框架会自动的帮我们把这个三个参数值放action中的三个属性里面.(同时还做了类型的转换) 注意:这个工作其实是由defaultStack这个拦截器栈里面的拦截器来完成了. 传值完成之后,我们只要在execute方法中去直接使用就可以了,不需要做其他事情. 第二种情况:(域模型) 在接收到页面传值的时候,还可以让struts2框架直接帮我们把这些接收到的值封装到一个javabean对象里面. 1.action中定义一个User类型的变量user,User类中有三属性值,id name age,同时User类中还有get/set方法 2.action中给这个user属性提供get/set方法 3.页面向action传值的时候,参数的名字要写成user.id=1 user.name=tom user.age=20 将来接收到这个参数值以后,struts2框架会帮我们去创建一个User对象,并且把所传参数的三个值封装到对象的三个属性里面,最后把这个封装好的对象放到action的user属性中 第三种情况:(模型驱动) class TestAction implements ModelDriven<User>{ @Override public User getModel() { if(user == null){ user= new User(); } return user; } }
2.action中跳转的方式
<result name="" type="">..</result> name属性指的是跳转的名字(默认值success),也就是action返回的字符串 type属性指的是跳转的类型(默认值dispatcher),常用到的跳转类型有已下四种:
内部跳转
dispatcher(action->jsp)
从一个action里面服务器内部跳转到一个页面中.这个是type属性的默认值.
chain(action->action) 从一个action里面服务器内部跳转到另一个action中. <result type="chain">methodTest1</result> 或者: <result type="chain"> <param name="method">方法名</param> <param name="actionName">action名</param> <param name="namespace">命名空间</param> </result>
外部跳转
redirect(action->jsp)
从一个action里面客户端重定向到一个页面中.
/success.jsp
redirectAction(action->action) 从一个action里面客户端重定向到另一个action里面 1.同一个package下面的action跳转: /test下面的action跳转到/test下面的action <result type="redirectAction">methodTest1</result> 或者 <result type="redirectAction"> <param name="actionName">methodTest1</param> <param name="namespace">/test</param> </result> 2.不同的俩个package下面的action跳转 /test下面的action跳转到/user下面的action <result type="redirectAction"> <param name="actionName">mytest</param> <param name="namespace">/user</param> </result>
3.配置全局的跳转.
<global-results> <result name="success">/success.jsp</result> <result name="error">/error.jsp</result> </global-results> 作用: 将来在其他任何action中,如果有需要返回success字符串跳转到success.jsp或者返回error字符串跳转到error.jsp的时候,就不需要在单独定义,因为已经把这个俩个跳转定义成了全局的跳转,对当前package里面的所有action都起作用.同时还可以在某一个action中再重新定义一下这个俩个跳转,这个时候全局跳转就不会对这个action起作用了.
4.配置package中默认的action
<default-action-ref name="methodTest1"></default-action-ref> 作用:如果地址栏中访问到了当前package下面一个不存在的action的时候,正常情况下是会直接报错的,错误信息显示这个action找不到,但是我们一旦配置了这个默认的action之后,那么再去访问一个不存在的action就不会报错了,而是直接就去访问这个默认的action.这个默认的action需要我们在当前package里面定义出来,并且在<default-action-ref>标签中引用一下. 注意:访问某个package下面action的时候有几种错误的情况: 1.action找不到 2.action找到了但是action对应的类找不到. 3.action找到了,对应的类找到了,但是在类中要执行的方法没找到。 4.action找到了,对应的类找到了,类中要执行的方法找到了,但是方法返回的字符串在<result>标签中没有定义. 5.action找到了,对应的类找到了,类中要执行的方法找到了,方法返回的字符串在<result>标签也定义了出来,但是要跳转的页面没有找到.
5.从action向页面传值
在action中依然可以像以前在servlet里面一样, 使用request、session、application向页面传送,除此之外, action里面还有俩个独有的传值方式:ValueStack ActionContext 1.ValueStack是一个接口:com.opensymphony.xwork2.util.ValueStack ActionContext是一个类:com.opensymphony.xwork2.ActionContext 我们可以使用这个俩个类型的对象,从action里面把值带到页面. 2.我们在页面中,可以通过一个struts2的标签来看到action传到页面中的值: <s:debug/> 页面引入标签库:<%@taglib uri="/struts-tags" prefix="s" %> 3.当前action进行跳转的时候,struts2框架会自动的把当这个action对象本身分别放到ValueStack和ActionContext这个俩个对象, <s:property value="customer.username"/> 然后struts2框架再把这个俩个对象传给页面,所以我们在页面中只要通过这个俩个对象,就可以拿到之前放进去的值.(在页面的debug标签中,可以看到struts框架放到这俩个对象里面的action) 4.除了struts框架自动的像ValueStack和ActionContext里面放值以外, 我们还可以手动的向这俩个对象里面放值. (在execute方法中拿到这个俩个对象就可以向里面放值了) 5.如何拿到ValueStack和ActionContext对象 获得ActionContext对象: ActionContext ac = ActionContext.getContext(); 获得ValueStack对象: ValueStack vs = ac.getValueStack(); 6.自己向ac和vs中主动放值 向ActionContext对象中放值: ac.put(String,Object); ac.put("hello","world"); 向ValueStack对象中放值: User user = new User(); vs.push(user); 7.ValueStack的特点(值栈) 1.把一个对象放到vs里面之后,我们从这个vs中是拿不到这个对象的,但是我们可以直接拿到这个对象里面的属性以及属性值. 2.从vs中拿值的时候,是从vs中的property name这一个列来拿的,拿到的是property value这一列的值.(在debug中的vs视图可以看这些列) 所以如果我们通过vs把一个值传到页面,我们不能直接把这个值放到vs里,因为这样拿不到,我们应该把这个值放到一个对象的属性里面,然后再把这个对象放vs中,这个时候就可以通过vs拿到这个对象的属性了,也就是我们要传的值. 3.每次浏览器发送一个新的请求,都会生成一个新的ValueStack对象,上一次的ValueStack对象就没了,找不到了.(类似之前学习的request对象的特点) 4.每次创建一个新的ValueStack对象后,会把这个对象放到ActionContext里面. 8.ActionContext的特点 1.向ac里面放值的时候是通过key-value的形式存放的,key是String类型,value是Object类型,取值的是同样通过key拿到value. 2.struts框架默认向这个对象里面存放的对象(数据)很多,包括request、session、application、ValueStack、parameters等 3.每次请求都会创建一个新的ActionContext对象(每次请求打印出ac的地址值可以看出来) 9.注意:使用vs和ac传值的时候,要使用服务器内部跳转的方式.
客户端发送一个请求到action,struts2框架会创建俩个对象:
ValueStack对象和ActionContext对象,action执行完进行跳转的的同时,struts2框架会这个当前执行的action对象分别放到ValueStack对象和ActionContext对象里面,在页面中通过debug标签可以到放到这俩个对象里面的action对象.所以最终我们在页面就可以通过ValueStack对象或者ActionContext对象拿到action里面的属性值(get/set方法)
6.在action中访问web元素(request session application)
1.在struts2框架中,这三个对象分别都有俩个类型:原类型 Map类型(这个对象都在ActionContext里面)2.原类型: (指的就是之前在servlet中使用的对象类型)
HttpServletRequest request
HttpSession session
ServletContext application
Map类型:
Map
7.页面中获得action传过来的值
在struts2框架所提供的页面取值方式中,需要使用到俩个东西:struts2框架的标签、OGNL表达式注意:同时我们也可以使用jsp内置对象取值已经使用jstl标签+EL表达式取值.
struts2中可以使用的取值方式:
1.jsp内置对象取值
2.jstl标签+EL表达式取值
3.struts2标签+OGNL表达式
注意:OGNL表达式只能写在struts2的标签属性中,在这里面我们先使用一下struts2的这样一个标签:,这个标签的作用就是向页面输出值.
例如:
1)从ValueStack和ActionContext中取值
1.从ValueStack中取值. //注意这个value属性中的值name,其实就是ongl表达式 //这个表示从valueStack中取一个名字叫做name的property值 <s:property value="name"/> <s:property value="user"/> <s:property value="user.id"/> <s:property value="user.name"/> 注意:从ValueStack中取值的时候,如果Valuestack里面有俩个名字相同的值,我们只能取到最上面的值(从debug标签中看vs中最上面的值)(其实取值的方式特殊处理一下还是可以取到下面的属性值的) 2.从ActionContext中取值. 要使用ognl表达式通过AC中的key来拿相对于的value值。取值的时候需要加上一个符号:# <s:property value="#action.name"/><br> <s:property value="#msg"/><br> <s:property value="#user"/><br> <s:property value="#user.id"/><br> <s:property value="#user.name"/><br> <s:property value="#user.age"/><br> 3.ActionContext中的parameters、attr、request、session、application等key值.(这些都是AC中的key) parameters对应的值中存放的是客户端所传过来的参数. //接收客户端传来的名字为name的参数值 <s:property value="#parameters.name"/><br> //获得request中的值 <s:property value="#request.MyName"/><br> //获得session中的值 <s:property value="#session.MyName"/><br> //获得application中的值 <s:property value="#application.MyName"/><br> //默认依次从request、session、appliction中取值,取到了就直接输出,取不到就算了. <s:property value="#attr.MyName"/><br>
2)还可以使用以前的方式从request、session、application中取值.
注意:如果我们用request通过key去取值的时候,会先在request里面找,request里面找不到会到ValueStack里面找。因为ValueStack默认也被放在request里面.但是session和application没有像request的这样的特点.
使用jsp脚本代码取值
<%=request.getAttribute(“name”) %>
<%=session.getAttribute(“name”) %>
<%=application.getAttribute(“name”) %>
使用EL表达式取值:
${requestScope.MyName } ${requestScope.name } ${sessionScope.MyName } ${applicationScope.MyName } ${MyName } ${name }
8.strut2框架中的拦截器(interceptor)
1.什么是拦截器(interceptor)拦截器是strut2框架的中提供的一种java类。
作用:1.可以拦截访问action的请求
2.给这个action加入新的丰富功能(上传、参数自动接收、类型自动转换等等)需要配置之后,指明哪一个拦截器去拦截哪一个action或者哪一些action,这样这个拦截器才会去拦截我们的这个action每一个拦截器就可以给我们的action加入一个新的功能.
2.拦截器(interceptor)如何工作的
a.有一个拦截器的类(struts2框架自带的或者我们自己定义的一个类)
b.在配置文件中把这个拦截器类配置出来.
c.指明这个拦截器要拦截哪一个或者哪一些action.
d.客户端发送一个请求访问一个被拦截器拦截的action
e.这个请求会先被struts2的filter所拦截,filter会先检查这个请求是不是请求的action,如果是action的话,那么会再检查这个action有没有被定义的拦截器所拦截,有如果那么就把这个请求交给拦截器去处理.
3.如何自定义一个拦截器
struts2框架已经写好了很多个拦截器(在struts2的核心jar包),同时也把这些拦截器配置在配置文件里面(在struts-default.xml中).
除此以外,我们还能写自己的的拦截器。
要写一个拦截器,首先要实现一个接口:com.opensymphony.xwork2.interceptor.Interceptor 例如: public class MyInterceptor implements Interceptor{ public void destroy() { System.out.println("in destory() of MyInterceptor"); } public void init() { System.out.println("in init() of MyInterceptor"); } //拦截到访问action的情况的时候调用这个方法 public String intercept(ActionInvocation ai) throws Exception { System.out.println("before..."); //ai.invoke()其实就是帮我们去调用action中将要执行的方法,比如execute方法 //ai.invoke()的放回值其实就是action中方法执行完返回的字符串 String s = ai.invoke(); System.out.println("after..."); return s; } } 然后再struts.xml文件中配置出这个拦截器类: <interceptors> <interceptor name="myInterceptor" class="com.briup.web.interceptor.MyInterceptor"></interceptor> </interceptors> 最后指明这个拦截器在哪一个action中起作用: <action name="MyTest"> <result>/index.jsp</result> <interceptor-ref name="myInterceptor"></interceptor-ref> </action>
4.拦截器栈
当前一个action需要被多个拦截器拦截的时候,正常情况下,我们需要在这个action中去引用要使用到的多个拦截器,但是我们可以使用一个拦截器栈去包含那几个拦截器,然后在action中直接引用这个拦截器栈就可以了.
1.一个拦截器栈可以包含多个拦截器
2.一个拦截器栈还可以包含其他拦截器栈
3.定义拦截器或者拦截器栈都要在标签中
例如:
<interceptors> <interceptor name="myInterceptor" class="com.briup.web.interceptor.MyInterceptor"></interceptor> <interceptor-stack name="myStack"> <!-- 这是我们自己定义的一个拦截器 --> <interceptor-ref name="myInterceptor"></interceptor-ref> <!-- 这是struts-default.xml文件中定义的一个拦截器 --> <interceptor-ref name="params"></interceptor-ref> <!-- 这是struts-default.xml文件中定义的一个拦截器栈 --> <interceptor-ref name="basicStack"></interceptor-ref> </interceptor-stack> </interceptors>
5.默认拦截器/拦截器栈 在一个package中,我们可以把一个拦截器或者拦截器栈声明为一个默认的拦截器/拦截器栈 作用:将来这个package中所有的action都会被这个默认的拦截器/拦截器栈所拦截。 例如: myStack是一个拦截器或者拦截器栈 <default-interceptor-ref name="myStack"></default-interceptor-ref> 注意: 一般情况下,我们所写的任何action都会被一个叫做defaultStack的拦截器栈所拦截,这个拦截器栈中包含了十几个拦截器,这些拦截器给我们的action提供了很多丰富的功能.因为我们写所有的package都是直接或间接的继承了struts-default.xml文件中的一个名字叫struts-default的package,struts-default包中又把名字叫defaultStack的拦截器栈配置成了一个默认的拦截器栈,那么我们的package就把这个配置继承了过来,所有我们的action正常情况下都会被defaultStack所拦截 但是如果我们一旦指明了某一个action被我们所写的一个拦截器/拦截器栈所拦截,那么这个action就不会被defaultStack拦截了.所以我们可以在action中主动的再声明 这个action被defaultStack所拦截,或者把defaultStack加入到我们自定义的拦截器栈里面(拦截器栈可以包含拦截器栈) 6.package之间的继承 我们可以专门再定义一个package,在这个package里面我们只做拦截器/拦截器栈的定义: <!-- 在这个package中,我们只定义拦截器/拦截器栈 --> <package name="MyInter" extends="struts-default" namespace="/"> <interceptors> <interceptor name="myInterceptor" class="com.briup.web.interceptor.MyInterceptor"></interceptor> <interceptor-stack name="myStack"> <interceptor-ref name="myInterceptor"></interceptor-ref> <!-- 这是struts-default.xml文件中定义的一个拦截器栈 --> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <!-- 声明默认拦截器/拦截器栈 --> <!-- 当前包中所有的action都会被这个myStack所拦截器 --> <!-- 继承了当前包的其他包里面的所有action也会被这个myStack所拦截器 --> <default-interceptor-ref name="myStack"></default-interceptor-ref> </package> 然后我们可以让其他的package去继承我们这个MyInter包,这样一来,其他包中的action都会被我们这个MyInter包中的默认拦截器栈myStack所拦截了。 注意:一定要保证action至少是被defaultStack这个拦截器栈所拦截的. 7.注意:在struts.xml中只定义出来一个拦截器,这个拦截器是不会被初始化和销毁的,在action中引用过以后才能让struts2框架帮我们去初始化这个拦截器,但是还是不能销毁,如果还想销毁的话,那么就要在一个拦截器栈中去引用一下这个拦截器才可以.
9.拦截器(interceptor)和过滤器(filter)的比较
相同点: 1.都是一种java类 2.都能拦截客户端发给服务器端的请求 3.拦截到请求之后都可以做一些相应的处理,最后还可以把这个请求放行. 4.都需要实现各自相应的接口以及在相应的配置文件中配置. 不同点: 1.拦截器(interceptor)是struts2框架中的定义的,过滤器(filter)是web里面的对象,是J2EE标准里面定义的. 2.拦截器(interceptor)只会拦截器访问action的请求,过滤器(filter)能够拦截所有请求. 3.拦截器(interceptor)定义在struts.xml文件中,过滤器(filter)定义在web.xml文件中. 4.拦截器(interceptor)对象的创建、调用、销毁是struts2框架负责的,过滤器(filter)对象的创建、调用、销毁服务器负责的. 我们自己定义的filter能不能拦截Struts2框架中的action 1.可以拦截 2.需要在web.xml文件中把我们自己的filter配置在struts2的filter的上面才可以. 因为web.xml文件中filter配置的先后顺序控制filter起作用的顺序,同时如果struts的filter先拦截到访问action的请求后,不会把这个请求交给下面的filter,而是交给了他它内部的拦截器(interceptor)了,但是如果我们自己filter拦截到请求之后,还是依然会交给下一个filter,也就是交给struts2的filter.
10. Struts2 注解方式(Annotation)
1.引入 支持Struts2框架注解开发的jar包 struts2-convention-plugin-2.3.4.1 2.struts.xml <constant name="struts.convention.action.suffix" value="Action"/> 2.Struts2使用注解开发需要遵循一些规范: 1)Action要必须继承ActionSupport父类; 2)Action所在的包名必须以 Action 结尾。 3.package-info.java @Namespace("/") @ParentPackage("struts-default") package com.briup.action.manager; import org.apache.struts2.convention.annotation.Namespace; import org.apache.struts2.convention.annotation.ParentPackage; 3.action中常用的注解: Namespace Annotation 1.通过在ActionClass上定义 @Namespace("/custom") 2.通过 package-info.java 定义 @org.apache.struts2.convention.annotation.Namespace("/custom") package com.example.actions; Action Annotation 1. @Action(interceptorRefs={ @InterceptorRef("validation"), @InterceptorRef("defaultStack") }) 2. chain @Action("foo") public String foo() { return "bar"; } @Action("foo-bar") public String bar() { return SUCCESS; } Result Annotation 1.全局,整个类可以访问 2.局部,某个方法可以访问 @Results({ @Result(name="failure", location="fail.jsp") }) public class HelloWorld extends ActionSupport { @Action(value="/different/url",results={@Result(name="success", location="http://struts.apache.org", type="redirect")} ) public String execute() { return SUCCESS; } } 可以传递参数: results={ @Result(name="success", type="httpheader", params={"status", "500", "errorMessage", "Internal Error"})}
相关文章推荐
- Java设计模式(学习整理)---命令模式
- SpringMVC 实例 --非注解【过时的,留作回忆】
- Java程序将amr格式音频转成mp3格式
- Java中的异常总结
- 为期15天的JAVA实习
- web开发(五)之struts校验
- 线程死锁和解决方案
- 获取Java程序运行的路径 | 获取当前jar包的路径
- SpringMVC访问静态资源的三种方式
- Struts2 笔记(1) Struts2引入/Action
- Spring Security3安全框架的学习
- Intellij Idea java文件不显示
- 感谢你们投票给了鸡腿
- Myeclipse 更改web项目的访问名
- SpringMVC和MyBatis基本框架搭建
- JAVA对象拷贝(copy)问题
- java正则匹配email,手机号,数字
- Java并发编程:Lock
- java中,部分jar包下载地址(持续补充)
- springmvc注解开发——Springmvc总结(二)