zoukankan      html  css  js  c++  java
  • Struts2学习笔记三 访问servlet

    结果跳转方式

    转发

    <!--  转发 -->
            <action name="Demo1Action" class="cn.itheima.a_result.Demo1Action" method="execute" >
                <result name="success" type="dispatcher" >/hello.jsp</result>
            </action>

    重定向

    <!-- 重定向 -->
            <action name="Demo2Action" class="cn.itheima.a_result.Demo2Action" method="execute" >
                <result name="success" type="redirect" >/hello.jsp</result>
            </action>

    转发到Action

    <!-- 转发到Action -->
            <action name="Demo3Action" class="cn.itheima.a_result.Demo3Action" method="execute" >
                 <result name="success" type="chain">
                         <!-- action的名字 -->
                     <param name="actionName">Demo1Action</param>
                         <!-- action所在的命名空间 -->
                     <param name="namespace">/</param>
                 </result>
            </action>

    重定向到Action

    <!-- 重定向到Action -->
            <action name="Demo4Action" class="cn.itheima.a_result.Demo4Action" method="execute" >
                <result  name="success"  type="redirectAction">
                     <!-- action的名字 -->
                     <param name="actionName">Demo1Action</param>
                     <!-- action所在的命名空间 -->
                     <param name="namespace">/</param>
                </result>
            </action>

    Struts2访问servlet的API

    在Struts2中,Action并没有直接和Servlet API进行耦合,即在Struts2的Action中不能直接访问Servlet API。这是Struts2中Action的重要改良之一,方便Action进行单元测试。

    在Struts2中,访问Servlet API有3中方法,具体如下:

    通过ActionContext类访问

    ActionContext是Action执行的上下文对象,保存了Action执行所需要的所有对象,包括parameters,request,Session,application等。下面列举ActionContext类访问Servlet API的几个常用方法,具体如表所示。

    //如何在action中获得原生ServletAPI
    public class Demo5Action extends ActionSupport {
    
        public String execute() throws Exception {
            //request域=> map (struts2并不推荐使用原生request域)
            //不推荐
            Map<String, Object> requestScope = (Map<String, Object>) ActionContext.getContext().get("request");
            //推荐
            ActionContext.getContext().put("name", "requestTom");
            //session域 => map
            Map<String, Object> sessionScope = ActionContext.getContext().getSession();
            sessionScope.put("name", "sessionTom");
            //application域=>map
            Map<String, Object> applicationScope = ActionContext.getContext().getApplication();
            applicationScope.put("name", "applicationTom");
            
            return SUCCESS;
        }
    }

    Struts2中,每次提交请求都是不同的线程,每个线程都会绑定一个新的action实例。所以和request的生命周期相同。

    通过ServletActionContext访问

     为了直接访问Servlet API,Struts2框架还提供了ServletActionContext类,该类包含了几个常用的静态方法,具体如下:

    //如何在action中获得原生ServletAPI
    public class Demo6Action extends ActionSupport {
        //并不推荐
        public String execute() throws Exception {
            //原生request
            HttpServletRequest request = ServletActionContext.getRequest();
            //原生session
            HttpSession session = request.getSession();
            //原生response
            HttpServletResponse response = ServletActionContext.getResponse();
            //原生servletContext
            ServletContext servletContext = ServletActionContext.getServletContext();
            return SUCCESS;
        }
    }

    通过实现接口方式访问

     上面的两种方式都无法直接获得Servlet API实例,为了在Action中直接访问Servlet API,Struts2还提供了一系列接口,具体如下:

    //如何在action中获得原生ServletAPI
    public class Demo7Action extends ActionSupport implements ServletRequestAware {
        
        
        private HttpServletRequest request;
    
        public String execute() throws Exception { 
            
            System.out.println("原生request:"+request);
            return SUCCESS;
        }
    
        @Override
        public void setServletRequest(HttpServletRequest request) {
            this.request = request;
        }
    }

    获取参数

    以前的Servlet开发中,获取界面传递的参数,然后封装到javabean中,然后将javabean传递到业务层。需要两步操作。在Struts2中,自动将参数进行了封装。Struts2将数据的封装分成两大类,一类被称为是属性驱动,一类被称为是模型驱动。

    每次请求到来时,都会创建一个新的Action实例。Action是线程安全的,可以使用成员变量接收参数。

    属性驱动可以细分成两种:

    1. 只需要提供属性的set方法即可
    2. 通过表达式方式直接封装到对象中。

    属性驱动

    提供属性set方法的方式

    package cn.itheima.c_param;
    
    import java.util.Date;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    //struts2如何获得参数
    //每次请求Action时都会创建新的Action实例对象
    public class Demo8Action extends ActionSupport  {
        
        public Demo8Action() {
            super();
            System.out.println("demo8Action被创建了!");
        }
    
    
        //准备与参数键名称相同的属性
        private String name;
        //自动类型转换 只能转换8大基本数据类型以及对应包装类
        private Integer age;
        //支持特定类型字符串转换为Date ,例如 yyyy-MM-dd
        private Date   birthday;
        
    
        public String execute() throws Exception { 
            
            System.out.println("name参数值:"+name+",age参数值:"+age+",生日:"+birthday);
            
            return SUCCESS;
        }
    
    
        public String getName() {
            return name;
        }
    
    
        public void setName(String name) {
            this.name = name;
        }
    
    
        public Integer getAge() {
            return age;
        }
    
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
    
        public Date getBirthday() {
            return birthday;
        }
    
    
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    
    
        
    }
    <form action="${pageContext.request.contextPath}/Demo8Action">
            用户名:<input type="text" name="name" /><br>
            年龄:<input type="text" name="age" /><br>
            生日:<input type="text" name="birthday" /><br>
            <input type="submit" value="提交" />
        </form>

    以上方式不够优雅,在类中存在大段的set/get方法,不利于代码维护。

    把属性和相应的getter/setter方法从action中提取出来,单独作为一个值对象,一般以javaBean来实现,所封装的属性和表单的属性一一对应,JavaBean将称为数据传递的载体。

    页面提供表达式方式

    package cn.itheima.c_param;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    import cn.itheima.domain.User;
    
    //struts2如何获得参数-方式2
    public class Demo9Action extends ActionSupport  {
        //准备user对象
        private User user;
    
        public String execute() throws Exception { 
            
            System.out.println(user);
            
            return SUCCESS;
        }
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    
        
    }
        <form action="${pageContext.request.contextPath}/Demo9Action">
            用户名:<input type="text" name="user.name" /><br>
            年龄:<input type="text" name="user.age" /><br>
            生日:<input type="text" name="user.birthday" /><br>
            <input type="submit" value="提交" />
        </form>

    以上实现方式需要在表单里以user.name的方式,看起来怪怪的。

    模型驱动

     通过实现ModelDriven接口来接收请求参数,Action类必须实现ModelDriven接口,并且要重写getModel()方法,这个方法返回的就是Action所使用的数据模型对象。

    模型驱动方式通过JavaBean模型进行数据传递。只要是普通的JavaBean,就可以充当模型部分。采用这种方式,JavaBean所封装的属性与表单的属性一一对应,JavaBean将成为数据传递的载体。

    大部分我们会优先使用该方式。因为Struts2内部有很多结果围绕模型驱动设计的。但如果页面向多个对象中封装,那么就需要使用属性驱动的方式二了。

    //struts2如何获得参数-方式2
    public class Demo10Action extends ActionSupport implements ModelDriven<User> {
        //准备user 成员变量
        private User user =new User();
    
        public String execute() throws Exception { 
            
            System.out.println(user);
            
            return SUCCESS;
        }
    
        @Override
        public User getModel() {
            return user;
        }
    }
        <form action="${pageContext.request.contextPath}/Demo10Action">
            用户名:<input type="text" name="name" /><br>
            年龄:<input type="text" name="age" /><br>
            生日:<input type="text" name="birthday" /><br>
            <input type="submit" value="提交" />
        </form>

    集合类型的参数封装

    在实际开发中,有些时候我们需要批量插入用户或者批量插入其他的对象,在Action中需要接受到这多个Action中封装的对象,然后传递给业务层。这时候就需要将表单中的数据封装到集合中。

    package cn.itheima.c_param;
    
    import java.util.List;
    import java.util.Map;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    //struts2 封装集合类型参数
    public class Demo11Action extends ActionSupport  {
        //list
        private List<String> list;
        //Map
        private Map<String,String> map;
        
        
        public String execute() throws Exception { 
            
            System.out.println("list:"+list);
            System.out.println("map:"+map);
            
            return SUCCESS;
        }
    
        public List<String> getList() {
            return list;
        }
    
        public void setList(List<String> list) {
            this.list = list;
        }
    
        public Map<String, String> getMap() {
            return map;
        }
    
        public void setMap(Map<String, String> map) {
            this.map = map;
        }
    
    }
    <form action="${pageContext.request.contextPath}/Demo11Action" method="post" >
            list:<input type="text" name="list" /><br>
            list:<input type="text" name="list[3]" /><br>
            map:<input type="text" name="map['haha']" /><br>
            <input type="submit" value="提交" />
        </form>
  • 相关阅读:
    C#秘密武器之表达式树
    C#秘密武器之特性
    [转]拷贝构造函数详解
    [转]STL 容器一些底层机制
    C++ Qt多线程 TcpSocket服务器实例
    QByteArray储存二进制数据(包括结构体,自定义QT对象)
    [转]浅谈 C++ 中的 new/delete 和 new[]/delete[]
    [转]QList内存释放
    Subscribe的第四个参数用法
    ROS多线程订阅消息
  • 原文地址:https://www.cnblogs.com/ginb/p/7297878.html
Copyright © 2011-2022 走看看