JavaEE学习笔记之SSH—Struts2(3)

一、action中如何接受页面传过来的参数

第一种情况:(同名参数)

 例如:
   通过页面要把id=1 name=tom age=20这三个参数传给action

 1.action里面定义三个成员变量id name age,这三个变量的名字一定要和所传变量的名字一致.

 2.提供get、set方法

 3.将来页面把这三个参数传过来的时候,struts2框架会自动的帮我们把这个三个参数值放action中的三个属性里面.(同时还做了类型的转换)
 注意:这个工作其实是由defaultStack这个拦截器栈里面的拦截器来完成了.

 传值完成之后,我们只要在execute方法中去直接使用就可以了,不需要做其他事情.

(深度解析:

    实际上,当前台想后台的一个action发出请求的时候,struts会相应的new出来一个action对象,并调用action中的setXXX方法,注意其实action中设置的变量名 可以不和前台传来参数名相同,但setXXX,这个XXX必须与前台的参数名相同

    就这样 struts通过这个set方法将前台传来的值赋给了 action中的变量

  )

第二种情况:(域模型)

在接收到页面传值的时候,还可以让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属性中

例如,一个bbs系统,实现用户注册模块,那么后台module中 我们就会相应的建立一个 User类,这个user类就是我们前面说过的module,

  分析下为什么要用DomainModule来接收参数,我们从前台向后台的action中传递参数,action做的处理无非是紧接着再把这个参数传递给对应的module,那么假如我们的module有100个变量(呵呵,我说的是假如),那么我们用第一种方法接收参数时就要在action中设置100个变量,但如果我们用domainmodule的话就简单的多,说了这么多,还没讲到怎么用呵呵,切入正题:

  eg:有一个用户登录系统,前台需要向后台传递一个user的name 和 password 两个属性,

    那么我们可以这么处理,首先在相应的action 设一个private User user; 变量(假如我们已经有了User这个Module了),好那么前台传递参数的时候可以这么来写,

    
action?user.name=chance&user.password=123
JSP提交页面如下编写:
    <s:form action="UserAction">
        <s:textfield name="user.username" lable="UserName" />
        <s:textfield name="user.password" lable="Password" />
        <s:submit />
    </s:form>
  注意:我们依然需要继续给user设置 set get方法

  另外需要注意的是,在action中设置的变量 无论是基本类型,还是引用类型,我们只需要声明,但不需要定义(简单的说,就是我们不需要去 new 一个变量)

  new的过程 由struts来帮我们完成
  
第三种情况:(模型驱动)
    class TestAction implements ModelDriven<User>{
        @Override
        public User getModel() {
            if(user == null){
                user= new User();
            }
            return user;
        }
    }

ModelDrivenAction类的执行流程是:首先调用getModel()方法得到User对象接着根据JavaBean的原则将客户端传过来的属性,一个一个的set到User对象的属性中将属性全部set完之后,再执行execute()方法。

二、action中跳转的方式

 <result name="" type="">..</result>
name属性指的是跳转的名字(默认值success),也就是action返回的字符串

type属性指的是跳转的类型(默认值dispatcher),常用到的跳转类型有已下四种:

内部跳转

dispatcher(action->jsp)
   从一个action里面服务器内部跳转到一个页面中.这个是type属性的默认值.

chain(action->action)
   从一个action里面服务器内部跳转到另一个action中.
   <result type="chain">Test1</result>
   (默认调用 Test1的execute()方法)
   或者:
    <result type="chain">
        <param name="method">方法名</param>
        <param name="actionName">action名</param>
        <param name="namespace">命名空间</param>
    </result>

外部跳转

redirect(action->jsp)
   从一个action里面客户端重定向到一个页面中.
   <result type="redirect">/success.jsp</result>

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>

三、配置全局的跳转.

    <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起作用了.

四、配置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>标签也定义了出来,但是要跳转的页面没有找到.

提醒:

action、interceptors、default-action-ref、global-results在package中的配置顺序:

interceptors—>default-action-ref—>global-results—>action

五、从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方法)

六、在action中访问web元素(request session application)

1.在struts2框架中,这三个对象分别都有两个类型:原类型、 Map类型(这个对象都在ActionContext里面)

2.原类型: (指的就是之前在servlet中使用的对象类型)

       HttpServletRequest request
       HttpSession    session
       ServletContext     application
 Map类型:
       Map<String,Object> request
       Map<String,Object> session
       Map<String,Object> application

3.在使用的时候,我们可以选择使用原类型的request或者选择使用Map类型的request.(session和application也是这样的情况)

4.不管是原类型的还是Map类型的对象,都是被struts2框架默认存放到了ActionContext对象里面.(使用debug标签可以看到)

5.原类型的和Map类型的关系.

   Map<String,Object> session1 = ActionContext.getContext().getSession();

   HttpSession session2 = ServletActionContext.getRequest().getSession();
  a.使用Map类型的对象,可以降低代码中对  servlet的API的依赖(降耦)

  b.我们使用原类型大多时候也是存值和取值,
  而且原类型里面本身也是封装了Map对象。
  所以我们使用Map类型的对象也可以完成存值和取值.

  c.Map类型的request对象里面的值(k-v),其实就是复制的原类型的request对象里面的值(k-v),当然原类型的request对象里面除了k-v类型的键值对以外,还有其他的属性和方法,因为它毕竟是HttpServletRequest类型的对象.

  d.所以原类型的request和Map类型的request对象,我们可以理解为他们里面的值(k-v)是相通的,相通的意思就是:这个对象里面有什么值,那个对象里就也会什么值.所以我们在action里面向Map类型的对象中存放一个值(k-v),将来在页面中同样是可以使用原类型的request对象那这个值(k-v)取出来的.    

  注:session和application的情况也是一样的道理.

原类型和Map类型相当于下面这个例子:

张三手里有一个钱包,我们平时都是把钱给张三,张三再把钱放到钱包里面, 我们拿钱的时候也是通过张三,张三从钱包里拿出钱,然后再把钱给我们.现在我们不想这么做,觉得很麻烦,我们直接从张三手里抢过来这个钱包,我们存钱和拿钱都直接操作这个钱包原类型的request就相当于这里的张三,Map类型对象就相当于这个钱包

6.在action中如果拿到Map类型和原类型的对象

1.获取Map类型对象
   第一种方式:自己在方法中主动获得
       ActionContext ac = ActionContext.getContext();
       //获得Map类型request
       Map<String,Object> request =
             (Map<String, Object>) ac.get("request");

       //获得Map类型session
           Map<String, Object> session = ac.getSession();

       //获得Map类型application
       Map<String, Object> application = ac.getApplication();

    第二种方式:让struts2框架把Map类型的对象自动的放到action里(依赖注入)

    第一种方式是自己主动拿到这个对象,第二种方式是自己被动接受这个对象.
    实现三个接口,分别可以让struts2框架把Map类型的request、session、application对象通过调用实现的接口中方法传给我们的action,在action里面我们只要接收这三个对象就可以了,那到后面可以直接使用.三个接口依次为:
    RequestAware,SessionAware,ApplicationAware

    例如:
public class WebActionTest extends ActionSupport implements RequestAware,SessionAware,ApplicationAware{
            private Map<String, Object> request;
            private Map<String, Object> session;
            private Map<String, Object> application;

            @Override
            public String execute() throws Exception {
                //页面中用原类型的对象取正常值就可以了
                request.put("MyName", "tom");
                session.put("YourName", "zhansan");
                application.put("HerName", "lily");
                return SUCCESS;
            }
            public void setRequest(Map<String, Object> request) {
                this.request = request;
            }

            public void setSession(Map<String, Object> session) {
                this.session = session;
            }

            public void setApplication(Map<String, Object> application) {
                this.application = application;
            }
        }
2.获取原类型对象

    第一种方式:自己主动获得
    获得原类型request对象
    HttpServletRequest req = ServletActionContext.getRequest();
    获得原类型response对象
    HttpServletResponse res = ServletActionContext.getResponse();
    获得原类型session对象
    HttpSession sess = req.getSession();
    获得原类型application对象
    ServletContext app1 = sess.getServletContext();
    或者
    ServletContext app2 = ServletActionContext.getServletContext();

    第二种方式:自己被动接收
    struts2框架中提供了一个接口,可以用来获得原类型的request对象,
    因为通过原类型的request对象就可以获得原类型的session对象和原类型的application对象

    实现接口:ServletRequestAware,然后struts2框架会通过action所实现的抽象方法,把原类型的request对象自动放到action里面.

    类似的还有一接口:ServletResponseAware,和上面的效果、用法是一样的。

七、页面中获得action传过来的值

在struts2框架所提供的页面取值方式中,需要使用到两个东西:struts2框架的标签、OGNL表达式

注意:同时我们也可以使用jsp内置对象取值已经使用jstl标签+EL表达式取值.

struts2中可以使用的取值方式:

  1.jsp内置对象取值

  2.jstl标签+EL表达式取值

  3.struts2标签+OGNL表达式
注意:OGNL表达式只能写在struts2的标签属性中,在这里面我们先使用一下struts2的这样一个标签:<s:property value=""/>,这个标签的作用就是向页面输出值.
例如:
<s:property value=" OGNL表达式写在这 "/>

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 }

时间: 2024-10-13 02:09:36

JavaEE学习笔记之SSH—Struts2(3)的相关文章

JavaEE学习笔记之SSH—Struts2(1)

现在来学习SSH中的第二个框架--Struts2 Struts2是一个基于MVC设计模式的Web应用框架. 首先将Struts2的框架搭建起来: 1)获取发布包 可以从 Struts2官网.Apache.GitHub等,当然直接百度肯定也是可以的. 2)导入相关 jar 包 将 struts-2.3.24.1-all\struts-2.3.24.1\apps\struts2-blank.war 压缩文件解压,然后将 E:\utils\struts2\struts-2.3.24.1-all\str

JavaEE学习笔记之SSH—Struts2(4)

这篇文章讲讲 Struts2 的核心所在--拦截器 一.strut2框架中的拦截器(interceptor) 1.什么是拦截器(interceptor) 拦截器是strut2框架中提供的一种java类. 作用: 1.可以拦截访问action的请求 2.给这个action加入新的丰富功能(上传.参数自动接收.类型自动转换等等)需要配置之后,指明哪一个拦截器去拦截哪一个action或者哪一些action,这样这个拦截器才会去拦截我们的这个action,每一个拦截器就可以给我们的action加入一个新

JavaEE学习笔记之SSH—Spring(1)

一.Spring相关概念 1:轻量级的容器: 容器:spring容器帮我们管理业务逻辑层,里边有很多业务逻辑对象,有对象就有对象的生命周期的管理(创建,销毁). 轻量级:容器给予的业务逻辑对象多少种服务?spring给用户提供的服务完全由用户自己决定,spring想用什么服务自己开启使用.但是重量级的都是只要你用就把所有的服务都给你,不能自己定制. spring容器从来不能独立运行,一定借助于其他容器启动,或者借助web容器启动,或者ejb容器启动. 特点: 应用模块之间耦合度小,组件都是可重用

JavaEE学习笔记之SSH—Spring(3)

一.代理模式 代理模式是常用的Java 设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务. 注意: 委托类对象就是我们后面说到的 目标对象(需要[被]代理的对象) 代理类对象就是我们后面说到的 代理对象(目标对象就是需要这个对象做为代理) 按照代理类的

JavaEE学习笔记之SSH—Hibernate(4)

今天来讲讲 Hibernate 的灵魂所在--> Session 缓存 session缓存是由一系列的Java集合构成的.当一个对象被加入到Session缓存中,这个对象的引用就加入到了java的集合中,以后即使应用程序中的引用变量不再引用该对象,只要Session缓存不被清空,这个对象一直处于生命周期中. Session缓存的作用: 1)减少访问数据库的频率. 2)保证缓存中的对象与数据库中的相关记录保持同步. Session清理缓存的时机: 1)当调用Transaction的commit()

JavaEE学习笔记之SSH—Hibernate(2)

对象关系映射 ORM 解决的主要问题就是对象-关系的映射,域模型和关系模型都分别建立在概念模型的基础上,域模型是面向对象的,关系模型是面向关系的,一般情况下,一个持久化类和一个表对应,类的每个实例对应表中的一条记录. (可能存在类中多个属性对应一列的情况,映射组成关系) ORM中间件采用元数据来描述对象-关系映射细节,元数据通常采用XML格式,并且存放在专门的对象-关系映射文件中,如果希望把ORM软件集成到自己的java应用中,用户首先要配置对象-关系映射文件(**.hbm.xml). sess

[原创]java WEB学习笔记75:Struts2 学习之路-- 总结 和 目录

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

[原创]java WEB学习笔记6:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) 使用 paramsPrepareParamsStack 重构代码 ,PrepareInterceptor拦截器,paramsPrepareParamsStack 拦截器栈

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

[原创]java WEB学习笔记70:Struts2 学习之路-- struts2拦截器源码分析,运行流程

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------