• Struts2的API&数据封装(二)


    一 Servlet的API的访问

    1 完全解耦和的方式

     完全看不到request、response、session。

     (1)创建jsp界面

    <h1>Struts2的servlet的API的访问</h1>
    <h3>完全解耦和的方式,方式一</h3>
    <form method="post" action="${pageContext.request.contextPath}/requestAction.action" >
        姓名:<input type="text" name="name">
        密码:<input type="password" name="password">
        <input type="submit" value="提交">
    </form>

    (2)编写action

    /**
     * 访问servlet API的完全解耦和的方式一
     */
    public class requestAction extends ActionSupport {
        public requestAction() {
            System.out.println("Action对象被创建了");
        }
    
        @Override
        public String execute() throws Exception {
            ActionContext actionContext=ActionContext.getContext();
            Map<String, Object> map = actionContext.getParameters();
            for (String key:map.keySet()
                 ) {
               String[] values  = (String[]) map.get(key);
                System.out.println(key +"   "+Arrays.toString(values));
            }
            //存值
            actionContext.put("attName","attValue");
            actionContext.getSession().put("sessName","sessValue");
            actionContext.getApplication().put("appName","appValue");
            return SUCCESS;
        }
    }

    (3)struts_xml

     <action name="requestAction" class="com.itheima.demo1.requestAction">
                <result name="success" type="redirect">/demo1/demo2.jsp</result>
            </action>

    运行效果图

    调用put方法相当于往request域中存数据
    注意:这种方式只能获得像 request session application集合中的值,不能操作对象的本身的方法


    2 使用Servlet的API的原生方式(这种必须要会)

    编写jsp

    <h3>使用原生的方式,方式二</h3>
    <form method="post" action="${pageContext.request.contextPath}/requestAction2.action" >
        姓名:<input type="text" name="name">
        密码:<input type="password" name="password">
        <input type="submit" value="提交">
    </form>

    编写action

    public class requestAction2 extends ActionSupport {
        @Override
        public String execute() throws Exception {
            HttpServletRequest request = ServletActionContext.getRequest();
    
            Map<String, String[]> map = request.getParameterMap();
            for (String key:map.keySet()
                 ) {
                String[] values = map.get(key);
                System.out.println(key+"   "+Arrays.toString(values));
            }
            request.setAttribute("attName","attValue");
            request.getSession().setAttribute("sessName","sessValue11");
            ServletActionContext.getServletContext().setAttribute("appName","appValue11");
            return SUCCESS;
        }
    }

    运行效果图

     这种方式既可以操作域中的数据,也可以操作对象的方法


    3 接口注入的方式(这种方式很少用,了解)

    action类

    public class requestAction3 extends ActionSupport implements ServletRequestAware,ServletContextAware {
    
        private HttpServletRequest request;
        private ServletContext context;//可以通过快捷键来生成
    
        public requestAction3() {
            System.out.println("Action被创建了");
        }
    
        @Override
        public String execute() throws Exception {
            Map<String, String[]> map = request.getParameterMap();
            for (String key:map.keySet()
                 ) {
                String[] values = map.get(key);
                System.out.println(key+""+Arrays.toString(values));
            }
            request.setAttribute("attName","attValues111");
            request.getSession().setAttribute("sessName","sessValues2");
            context.setAttribute("appName","appValues3");//存到application中
            return super.execute() ;//这里是返回sucess,可以查看源代码
        }
    
        @Override
        public void setServletRequest(HttpServletRequest request) {
            this.request=request;
        }
    
        @Override
        public void setServletContext(ServletContext servletContext) {
            this.context=servletContext;
        }
    }


    Servlet是单例的,只会创建一个对象。而action是多例的,每一次请求都会创建一个对象
    action是线程安全的,action是多例的,在类中定义成员变量不会有线程安全的问题

    二 配置结果页面

    1 全局结果页面

    全局结果页面,指的是这个包底下的都有效

    <global-results>
                <result name="success">/demo1/demo2.jsp</result>
    </global-results>

    2 局部结果页面

    局部结果页面,针对当前的action有效

    <action name="requestAction" class="com.itheima.demo1.requestAction">
                <result name="success" type="redirect">/demo1/demo2.jsp</result>
            </action>

    result就是用于配置页面的跳转的,里面有两个属性 name type

    name的默认值是success,假如返回值是success就不需要写了
    type属性:页面跳转的类型,前两种类型经常用,记住
      dispacher 默认值,请求转发,Action转发jsp
      redirect 重定向 Action重定向jsp
      chain 转发 ,Action转发到Action
      redirctAction 重定向,Action重定向Action (这个案例中就用到了这个)
      stream struts2中提供文件下载的功能(了解)


    三 数据封装

    1 方式一属性驱动:提供set方法
     提供属性set方法的方式 (这种方式很少用,比如文件下载,传过来个文件名)
    jsp页面
    <h1>struts2的数据封装</h1>
    <h3>方式一属性驱动:提供set方法</h3>
    <form action="${pageContext.request.contextPath}/Action1" method="post">
    <s:fielderror/>
        用户名:<input type="text" name="name"/><br>
        密码:<input type="text" name="password" /><br>
        年龄:<input type="text" name="age"/><br>
        生日:<input type="text" name="birthday"/><br>
        工资:<input type="text" name="salary"/><br>
        <input type="submit" value="提交">
    </form>
    action类
    /**
     * 方式一属性驱动:提供set方法
     */
    public class Action1 extends ActionSupport {
        private String name;
        private  String password;
        private Integer age;
        private Date birthday;
        private double salary;//工资
        //需要提供set方法
    
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    
        public void setSalary(double salary) {
            this.salary = salary;
        }
    
        @Override
        public String execute() throws Exception {
            System.out.println(name);
            System.out.println(password);
            System.out.println(age);
            System.out.println(birthday);
            System.out.println(salary);
            return NONE;
        }
    }



    方式二属性驱动:页面中提供表达式(可以同时向多个对象中同时封装数据)

      在action中创建一个私有对象,提供get和set方法,一定要提供get方法
      在页面中用user.的方式

    jsp界面
    <h3>方式二:属性驱动,提供页面表达式</h3>
    <form action="${pageContext.request.contextPath}/Action2" method="post">
        用户名:<input type="text" name="user.name"/><br>
        密码:<input type="text" name="user.password" /><br>
        年龄:<input type="text" name="user.age"/><br>
        生日:<input type="text" name="user.birthday"/><br>
        工资:<input type="text" name="user.salary"/><br>
        <input type="submit" value="提交">
    </form>

    编写action

    /**
     * 二 属性驱动:页面中提供表达式
     */
    public class Action2 extends ActionSupport {
        //创建一个私有对象,提供get和set方法,一定要提供get方法
        private User user;
    
        public User getUser() {        //在拦截器中获取到user对象
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    
        @Override
        public String execute() throws Exception {
            System.out.println(user);
            return NONE;
        }
    }

    方式三:采用模型驱动的方式(开发中最常用的方式)

    模型驱动:只须实现一个接口,提供一个对象,页面不用改
    在action中实现模型驱动的接口(ModelDriven),后面跟上对象的泛型
    使用的对象,必须手动提供对象的实例(new这个对象)
    缺点:只能同时向一个对象中封装数据(一般开发中都是同时向一个对象中封装数据)

    jsp界面

    <h3>方式一:提供set方法</h3>
    <form action="${pageContext.request.contextPath}/Action3" method="post">
        用户名:<input type="text" name="name"/><br>
        密码:<input type="text" name="password" /><br>
        年龄:<input type="text" name="age"/><br>
        生日:<input type="text" name="birthday"/><br>
        工资:<input type="text" name="salary"/><br>
        <input type="submit" value="提交">
    </form>

    编写action类

    **
     * 方式三:采用模型驱动的方式
     */
    public class Action3 extends ActionSupport implements ModelDriven<User> {
        private User user=new User();//创建实例
        @Override
        public User getModel() {
            //实例化对象
    
            return user;
        }
    
        @Override
        public String execute() throws Exception {
            System.out.println(user);
            return NONE;
        }
    }

    2 封装复杂数据到List集合中

    jsp界面

    <h1>struts2封装复杂数据</h1>
    <h3>封装数据到List集合中</h3>
    <form action="${pageContext.request.contextPath}/productAction1.action" method="post">
        商品名称:<input type="text" name="products[0].name"><br>
        商品价格:<input type="text" name="products[0].price"><br>
        商品名称: <input type="text" name="products[1].name"><br>
        商品价格: <input type="text" name="products[1].price"><br>
        商品名称: <input type="text" name="products[2].name"><br>
        商品价格: <input type="text" name="products[2].price"><br>
        <input type="submit" value="提交数据">

    </form>

    编写Action

    /**
     * 封装数据到List集合中
     */
    public class productAction1 extends ActionSupport {
            private List<Product> products;
    
        public List<Product> getProducts() {
            return products;
        }
    
        public void setProducts(List<Product> products) {
            this.products = products;
        }
    
        @Override
        public String execute() throws Exception {
            System.out.println(products);
            return NONE;
        }
    }

    3封装复杂数据到map集合中

    jsp界面

    <h3>封装数据到Map集合中</h3>
    <form action="${pageContext.request.contextPath}/productAction2.action" method="post">
        商品名称:<input type="text" name="map['one'].name"><br>
        商品价格:<input type="text" name="map['one'].price"><br>
        商品名称: <input type="text" name="map['two'].name"><br>
        商品价格: <input type="text" name="map['two'].price"><br>
        商品名称: <input type="text" name="map['three'].name"><br>
        商品价格: <input type="text" name="map['three'].price"><br>
        <input type="submit" value="提交数据">
    </form>

    编写Action类

    **
     * 封装数据到Map集合中
     */
    public class productAction2 extends ActionSupport {
        private Map<String,Product> map;
    
        public Map<String, Product> getMap() {
            return map;
        }
    
        public void setMap(Map<String, Product> map) {
            this.map = map;
        }
    
        @Override
        public String execute() throws Exception {
            //遍历Map集合
            for (String key :map.keySet()
                    ) {
                Product product = map.get(key);
                System.out.println(key+"  "+product);
            }
            return NONE;
        }
    }

    4 写程序时遇到的错误

    (1)input视图(报了input的异常,可以配一个input)
      引入一个struts2的标签库
      Invalid field value for field "age".
    (2)jsp页面中报element is not closed

      两个form表单写到了一个表单中

    
    
  • 相关阅读:
    Linux sort -n 与 -g 排序对比
    shell中IF的用法介绍
    Firewalld 用法解析
    Centos7最小化安装后再安装图形界面
    PXE无人值守部署centos7.4操作系统
    kali之获取靶机的图片和看的url
    Kali的源得数字验证问题
    kali之Nmap (Network Mapper(网络映射器)
    kali之EtterCap学习
    Kali linux查看局域网内其他用户的输入信息
  • 原文地址:https://www.cnblogs.com/bao6/p/10366554.html
Copyright © 2020-2023  润新知