zoukankan      html  css  js  c++  java
  • struts2第二天——数据操作

      先介绍一下大致内容: 

        大致内容:
            结果页面配置
            action获取表单提交数据
            提供获取表单数据的方式(封装数据)
            表单数据封装到集合中
            表达式封装和模型驱动封装比较

    一、结果页面配置: 

      result标签是配置action的返回值,然后到不同的路径去
      (复制昨天的项目过来时,除了改项目名称外,还必须改web 项目名
      改web项目的项目名可以右击->properties->搜索web找到settings->修改context name
      回顾流程:导包——创建action——创建核心配置文件——在web.xml中配置过滤器 

      1.全局结果页配置
        场景:多个action返回的结果页是相同的,可以使用全局结果页作为共用的部分
      在同一个package里的,在package下的作为子标签配置
      <global-results>
        <result name="success">/hello.jsp</result>
      </global-results>
      2.局部结果页配置
        在action里面写的就是局部结果页面,

        同时配置全局与局部,以局部结果页配置为准

      【重点】
        result标签中的 type 属性:通俗理解是如何到路径去的(默认是转发)
      type属性值:
        1.dispatcher(默认):用来转向页面,通常处理JSP ===转发页面
        2.redirect:重定向到一个URL,被跳转的页面中丢失传递的信息,如request.===重定向页面
          (ctrl + F5) :无缓存刷新,俗称大刷新
          以上 1 2 针对到其他页面的
        3.chain:用来处理Action链,被跳转的action中仍能获取上个页面的值,如request信息 ===转发action
        4.redirectAction:重定向到一个Action,跳转的页面中丢失传递的信息. ===重定向action
          !注意要写action的访问名称,直接写要去的action的name(不用写路径的加/的等)
      3.4针对的是到其它action的操作,一般用4,因为3会有缓存

      这是以上几点配置后的struts.xml配置文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">
    <struts>
        <package name="demo2" extends="struts-default" namespace="/">
            <!-- 全局结果页面配置 -->
            <global-results>
                <result name="success">/hello.jsp</result>
            </global-results>
            <action name="book" class="cn.action.BookAction">
                <!-- 重定向action,写的是action的name -->
                <result name="success" type="redirectAction">orders</result>
            </action>
            <action name="orders" class="cn.action.OrdersAction">
                <result name="success">/hello2.jsp</result>
            </action>
        </package>
        <package name="formDemo" extends="struts-default" namespace="/">
            <action name="form1" class="cn.action.FormAction"></action>
            <action name="data1" class="cn.action.FiledAction"></action>
            <action name="data2" class="cn.action.ModelAction"></action>
            <action name="list" class="cn.action.ListAction"></action>
        </package>
    </struts>    

    二、在action中获取表单提交数据(实际开发中使用最多的为模型驱动封装) 

      在web阶段,使用的是request对象,通过getParameter()等方法
      但是action中不能直接使用request,
      主要有三种方式
        1.通过ActionContext类
        2.通过ServletActionContext类
        3.接口注入的方式(使用较少)
      1和2 为struts封装的好的类

      1ActionContext类:

        (找的是xwork下的api)底层是使用request的封装,没有直接得到request对象,虽然官方推荐(解耦合),但更多人喜欢的是第二种
        ActionContext如何获取:静态方法 getContext
        可以简单创建表单页面提交到action进行获取
        如何获取:getParameters() 得到一个map key为string value为Object[]数组是由于可能有复选框等,得到的是所有表单数据的map集合
        如何直接输出数组值:Arrays.toString()

            ActionContext context = ActionContext.getContext();
            Map<String, Object> map = context.getParameters();

      2:ServletActionCotext类(类似web一个顶九个的类,可以召唤其它域对象等)

        (找的是org.apache.struts2包)可以直接调用静态方法得到request
        喜欢用的理由是比较直观
        表单提交中文没有乱码问题:因为struts2中存在处理POST提交的中文乱码问题(见day01)

    package cn.action;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.apache.struts2.ServletActionContext;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    public class FormAction extends ActionSupport {
    
        /**
         * 演示ServletActionContext类的使用
         */
        @Override
        public String execute() throws Exception {
            HttpServletRequest request = ServletActionContext.getRequest();
            /*request.getSession();
            ServletActionContext.getServletContext();*/
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            System.out.println(username+password);
            return NONE;
        }
        
    } 

      3.(只做了解)让action实现接口(ServletRequestAware),也能得到request对象


      在action中操作域对象
        Servlet域对象:request session servletContext
        使用ServletActionContext进行操作(先get得到,再get/setAttribute()等)
        当然,用的最多的还是request域

        HttpServletRequest request = ServletActionContext.getRequest();
        request.getSession(); //注意session的获取
        ServletActionContext.getServletContext();

    三、表单数据的封装

      1.原始方式封装表单数据(案例DemoAction)(越是原始方式越是强大,但有时不是那么方便快捷 走路最原始,乘坐交通工具虽快,但有时不是那么高效)

    package cn.action;
    
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.apache.struts2.ServletActionContext;
    
    import com.opensymphony.xwork2.ActionContext;
    import com.opensymphony.xwork2.ActionSupport;
    
    import cn.entiry.User;
    /**
     * 封装表单数据到实体类中
     * @author jiangbei01
     *
     */
    public class DemoAction extends ActionSupport {
    
        @Override
        public String execute() throws Exception {
            
            HttpServletRequest request = ServletActionContext.getRequest();
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            
            User user = new User();
            user.setUsername(username);
            user.setPassword(password);
            
            return NONE;
        }
    }

      struts2提供了:

        1.属性封装  

               在action定义成员变量,而且变量名需要和表单项name属性需要一致
            再生成get/set(虽然实际上只需要set方法)
            思想类似于 beanutils 底层是内省
            会进行属性匹配,匹配完成后调用set进行设置
            这种情况要封装到对象中去还需要手动set数据,这种形式也不是特别方便

    package cn.action;
    
    import com.opensymphony.xwork2.ActionSupport;
    /**
     * 使用属性封装获取表单数据
     * @author jiangbei01
     *
     */
    public class FiledAction 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;
        }
        
        //测试
        @Override
        public String execute() throws Exception {
            System.out.println(username+password);
            return NONE;
        }
    }

        2.【重点】模型驱动封装,最常用  

             底层也就是利用上一步的属性封装的操作
            action实现ModelDrivern 模型驱动接口(传入泛型类型,也就是对应实体类类名)
            创建实体类对象

            实现getModel()方法,返回对象
            代码量大大减少(request也不用自己得了)

        大致执行流程:getModel()方法获取要赋值的实体类,此实体类必须要实例化,否则为空;此时实体类置于值栈栈顶,相关属性

                也可以通过setValue()进行赋值,而 实现person的getter方法,用于当请求转发后,其他界面数据访问 

    package cn.action;
    
    import com.opensymphony.xwork2.ActionSupport;
    import com.opensymphony.xwork2.ModelDriven;
    
    import cn.entiry.User;
    
    public class ModelAction extends ActionSupport implements ModelDriven<User>{
    
        //手动创建实体类对象
        private User user = new User();
      //考虑是否需要user的set/get方法! @Override
    public User getModel() { //返回创建的user对象 return user; } @Override public String execute() throws Exception { System.out.println(user); return NONE; } }
        

      使用属性封装和模型驱动封装注意的问题:
            不能同时使用两种方式来获取同一个表单的数据。

        3.表达式封装(会用)有时候也可以归类到属性封装      

             也可以把表单数据封装到实体类
            在action里声明一个实体类;private User user
            生成实体类的set/get方法 this.user = user等
            在表单项的 name 值里写表达式的形式:<input type="text" name="user.username"/>
            写法略显麻烦,但功能可以实现

      表达式封装和模型驱动封装对比:
          两者都可以封装数据到实体类对象中;
          模型驱动只能封装到一个实体类中(ModelDrivern<T> T只能确定一个实体类),
          而表达式封装可以封装到不同实体类中

    四、表单数据封装到集合中(会用)      

      封装数据到list集合:(用的较少)
        在action里面声明list
        生成list的set/get方法
        在表单输入项里写表达式的写法:

    <form action="${pageContext.request.contextPath }/list.action" method="post">
              用户名:<input type="text" name="list[0].username"/><br/>
               密   码:<input type="password" name="list[0].password"/><br/>
              用户名2:<input type="text" name="list[1].username"/><br/>
               密   码2:<input type="password" name="list[1].password"/><br/>
             
           用户名3:
    <input type="text" name="map['one'].username"/><br/> 密 码3:<input type="password" name="map['two'].password"/><br/> <input type="submit" value="提交"/> </form>

      其中list[0] 表示List的第一个元素,也就是第一个User对象

    package cn.action;
    
    import java.util.List;
    import java.util.Map;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    import cn.entiry.User;
    /**
     * 表单数据封装到list中
     * @author jiangbei01
     *
     */
    public class ListAction extends ActionSupport {
    
        private List<User> list;
    
        public List<User> getList() {
            return list;
        }
    
        public void setList(List<User> list) {
            this.list = list;
        }
        
        @Override
        public String execute() throws Exception {
            //可以对list进行其他的操作等
        System.out.println(list);
    return NONE; } }

      

      封装数据到map集合:(用的更少)
        在action里声明map
          private Map<String,User> map;
        生成map的set/get方法

    private Map<String,User> map;
    
        public Map<String, User> getMap() {
            return map;
        }
    
        public void setMap(Map<String, User> map) {
            this.map = map;
        }
        @Override
        public String execute() throws Exception {
            System.out.println(map.get("one").getUsername());
            return NONE;
        }

           在表单项改成相应的写法
        先设置key的值,再放value (代码见封装到List代码处)
          用户名3:<input type="text" name="map['one'].username"/><br/>
          密 码3:<input type="password" name="map['one'].password"/><br/>
        key是one,把username设置进value的User中

    小结:

      封装到集合使用的都较少,因为需要知道固定的对象,写法非常固定

      常用的是ServletActionContext操作域对象获取数据
      封装表单数据常用的是模型驱动,实现接口,实现方法,注意实体类与表单项name属性值一致

  • 相关阅读:
    最短路径-Dijkstra算法(转载)
    递归算法到非递归算法的转换
    向量点乘(内积)和叉乘(外积、向量积)概念及几何意义(转载)
    数据预处理之独热编码(One-Hot Encoding)(转载)
    MyEclipse中手工添加dtd支持
    怎样sublime显示文件夹
    sublime_Text3中snippet设置信息头(包括作者、日期)
    解决Sublime_Text不能安装插件的方法
    Python设置默认编码为UTF-8
    解决火狐启动缓慢的方法
  • 原文地址:https://www.cnblogs.com/jiangbei/p/6761479.html
Copyright © 2011-2022 走看看