• Struts2之处理请求参数


    时间:2017-1-11 11:05

    ——Struts2中获取请求参数(重点)

    1、Struts2是一个MVC框架,那么分别表示什么?
        View:JSP
        Model:Action
        Controller:Action、StrutsPrepareAndExecuteFilter

    2、为什么Action既是Model又是Controller?
        因为Action本身可以作为一个JavaBean。

    3、在Struts2中获取请求参数有两大种(三小种)方式可以获取:
        1)属性驱动(在Action中添加属性,对Action的属性进行操作)
            *   直接将Action作为一个Model,就可以得到请求参数,也就是将Action作为一个JavaBean,提供get/set方法。
                这种方式底层是通过反射来实现的。
                >   问题1:使用Action封装请求参数,会不会存在线程安全问题?
                    不会,每一次请求都会生成一个Action对象。
                >   问题2:使用该方式封装数据,将数据封装到Action属性中,不可能将Action对象传递给业务层。
                    需要单独定义JavaBean,将Action属性封装到JavaBean

                示例代码:
                        //属性驱动的第一种方式获取请求参数,直接将Action做为Model
                        public class Login1Action 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 {
                                HttpServletRequest request = ServletActionContext.getRequest();
     
                                if ("tom".equals(username) && "123".equals(password)) {
     
                                    request.getSession().setAttribute("username", username);
     
                                  return SUCCESS;
                                } else {
                                    request.setAttribute("login.message", "用户名或密码错误");
                                    return "failer";
                                }
                            }
                        }


                实现原理:
                    1、首先为Action类提供JavaBean属性,并提供get / set方法
                    2、在过滤器中添加如下代码,将请求参数封装到JavaBean中:
                        /*
                         * 在调用invoke()方法前,处理请求参数的封装
                         */
                        Object actionObject = c.newInstance();
                        // 将请求参数封装到Action中(底层也是反射实现的)
                        BeanUtils.populate(actionObject, request.getParameterMap());
                    3、在Action中使用属性 

    ------------------------------------------------------------------------------------------------------------------

            *   创建独立的Model对象,页面通过ognl表达式封装
                >   在Action中声明一个JavaBean对象
                >   private User user;
                >   提供get/set方法:public User getUser()....
                >   在页面中使用ognl表达式:<input type="text" name="user.username" />
                优点:简单,解决了第一种封装的问题。
                缺点:在页面中使用了ognl表达式,与Struts2框架耦合度高。

                示例代码:

                    /*
                     * 属性驱动的第二种方式获取请求参数,在Action中声明一个JavaBean
                     * 在表单中的name值需要修改为:
                     *  * name="user.username" name="user.password"
                     *  * <input type="text" name="user.username" />
                     * user表示Action内部封装JavaBean对象的名称
                     * 这是Struts2中提供的一个默认表达式语言:ognl
                     */
                    public class Login2Action extends ActionSupport {
                        private User user;
     
                        public User getUser() {
                            return user;
                        }
     
                        public void setUser(User user) {
                            this.user = user;
                        }
     
                        @Override
                        public String execute() throws Exception {
                            HttpServletRequest request = ServletActionContext.getRequest();
     
                            if ("tom".equals(user.getUsername()) && "123".equals(user.getPassword())) {
     
                                request.getSession().setAttribute("username", user.getUsername());
                                return SUCCESS;
                            } else {
                                request.setAttribute("login.message", "用户名或密码错误");
                                return "failer";
                            }
                        }
                    }
    ------------------------------------------------------------------------------------------------------------------

                这种方式底层通过Struts2中的一个interceptor进行了封装:
                    <interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor" />
                        @Override
                        public String doIntercept(ActionInvocation invocation) throws Exception {
                            Object action = invocation.getAction();
                            if (!(action instanceof NoParameters)) {
                                ActionContext ac = invocation.getInvocationContext();
                                // 相当于request.getParameters(); 
                                final Map<String, Object> parameters = retrieveParameters(ac);
     
                                if (LOG.isDebugEnabled()) {
                                    LOG.debug("Setting params " + getParameterLogMap(parameters));
                                }
     
                                if (parameters != null) {
                                    Map<String, Object> contextMap = ac.getContextMap();
                                    try {
                                        ReflectionContextState.setCreatingNullObjects(contextMap, true);
                                        ReflectionContextState.setDenyMethodExecution(contextMap, true);
                                        ReflectionContextState.setReportingConversionErrors(contextMap, true);
     
                                        ValueStack stack = ac.getValueStack();
                                        // 将参数赋值给Action中的JavaBean 
                                        setParameters(action, stack, parameters);
                                    } finally {
                                        ReflectionContextState.setCreatingNullObjects(contextMap, false);
                                        ReflectionContextState.setDenyMethodExecution(contextMap, false);
                                        ReflectionContextState.setReportingConversionErrors(contextMap, false);
                                    }
                                }
                            }
                            return invocation.invoke();
                        }

    ------------------------------------------------------------------------------------------------------------------

        2)模型驱动(在开发中应用比较多)
            使用ModelDriven接口,对请求数据进行封装。
            步骤:
                *   声明一个JavaBean对象并且必须实例化对象。
                    >   private User user = new User();
                *   Action类实现ModelDriven接口
                    >   public class Login3Action extends ActionSupport implements ModelDriven
                *   重写getModel()方法
                    >   public Object getModel() { return this.user; }

            优点:解决了属性驱动存在的问题
                *   不需要将Action封装成JavaBean
                *   解决了在页面中使用ognl表达式的问题
            缺点:一次只能封装一个JavaBean对象,getModel()方法只能返回一个Bean。

            很多关于模型驱动的拦截器都是ModelDriven拦截器操作的:
                com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor

            示例代码:

                /*
                 * 使用模型驱动获取请求参数
                 */
                public class Login3Action extends ActionSupport implements ModelDriven {
                    private User user = new User();
     
                    public Object getModel() {
                        return this.user;
                    }
     
                    public String login() throws Exception {
                        HttpServletRequest request = ServletActionContext.getRequest();
                        System.out.println(user.getUsername() + ": " + user.getPassword());
                        if ("tom".equals(user.getUsername()) && "123".equals(user.getPassword())) {
     
                            request.getSession().setAttribute("username", user.getUsername());
     
                            return "success.jsp";
                        } else {
                            request.setAttribute("msg", "用户名或密码错误");
                            return "login.jsp";
                        }
                    }
                }

            实现原理:
                1、在Action中声明一个初始化的JavaBean对象。
                2、实现ModelDriven接口
                3、重写getModel()方法
                4、在拦截器中实现如下代码:
                    /*
                     * 模型驱动
                     */
                    // 得到HelloAction类中声明的User对象
                    Object actionObject = c.newInstance();
     
                    // 判断HelloAction是否实现了MyModelDriven接口
                    if(actionObject instanceof MyModelDriven){
                        // 将子类强转成父类
                        MyModelDriven model = (MyModelDriven)actionObject;
     
                        // 获取HelloAction内部的User对象,然后把请求参数封装到User对象中
                        BeanUtils.populate(model.getModel(), request.getParameterMap());
                    } else {
                        // 1、属性驱动
                        actionObject = c.newInstance();
                        // 将请求参数封装到Action中(底层也是反射实现的)
                        BeanUtils.populate(actionObject, request.getParameterMap());
                    }
             

    ——将请求参数封装到集合(了解)

    原理:使用ognl表达式实现。

    1、将数据封装到List集合
        页面:
            用户名1:<input type="text" name="users[0].username" /><br/>
            密    码1:<input type="password" name="users[0].password" /><br/>
     
            用户名2:<input type="text" name="users[1].username" /><br/>
            密    码2:<input type="password" name="users[1].password" /><br/>

        Action类:
            private List<User> users;
            get / set方法

    2、将数据封装到Map集合
        页面:
            用户名1:<input type="text" name="users['aaa'].username" /><br/>
            密    码1:<input type="password" name="users['aaa'].password" /><br/>
     
            用户名2:<input type="text" name="users['bbb'].username" /><br/>
            密    码2:<input type="password" name="users['bbb'].password" /><br/>

        Action类:
            private Map<String, User> users;
            get / set方法



    ——总结

    1、Action接收请求参数

        *   关于Struts2中的MVC
        *   属性驱动
            >   直接将Action作为JavaBean。
            >   Action中封装JavaBean,在页面上需要使用ognl表达式来给组件起名。
        *   模型驱动
            >   让Action实现ModelDriven接口,重写getModel()方法实例化一个JavaBean对象,该方法返回的就是实例化的JavaBean对象。
        *   关于请求参数封装到集合
            >   List
            >   Map

  • 相关阅读:
    浅谈页面的瀑布流布局
    前端常用动画库
    JavaScript七宗罪和一些槽点
    prototype与 _proto__的关系
    Javascript之傻傻理不清的原型链、prototype、__proto__
    C#开发微信门户及应用(26)-公众号微信素材管理
    C#开发微信门户及应用(25)-微信企业号的客户端管理功能
    基于InstallShield2013LimitedEdition的安装包制作
    Entity Framework 实体框架的形成之旅--Code First模式中使用 Fluent API 配置(6)
    Entity Framework 实体框架的形成之旅--Code First的框架设计(5)
  • 原文地址:https://www.cnblogs.com/wwwwyc/p/6375401.html
Copyright © 2020-2023  润新知