`

Struts2参数赋值的方式和原理

 
阅读更多

参数赋值方式

1.属性驱动

 

public class LoginAction {
    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;
    }   
}

 

    <form action="login.action" method="post">
        姓名:<input type="text" name="username">
        密码:<input type="text" name="password">
        <input type="submit" value="提交">
    </form>

 

 

2.定义一个对象

 

public class LoginAction {
    private User user;  
    public User getUser() {
       return user;
    }
    public void setUser(User user) {
       this.user = user;
    }
}

 

    <form action="login.action" method="post">
        姓名:<input type="text" name="user.username">
        密码:<input type="text" name="user.password">
        <input type="submit" value="提交">
    </form>

 

 

3.模型驱动

 

public class LoginAction implements ModelDriven<User> {
    private User user=new User();
    public User getModel() {        
        return user;
    }
}

 

    <form action="login.action" method="post">
        姓名:<input type="text" name="username">
        密码:<input type="text" name="password">
        <input type="submit" value="提交">
    </form>

 

 

Value Stack

概念

ValueStack是一个接口 
OgnlValueStack是ValueStack接口的默认实现类。

用途

可以作为一个数据中转站。 
用于在前台-后台之间传递数据。

生命周期

ValueStack的生命周期随着request的创建而创建,随着request的销毁而销毁 
在PrepareOperations类的createActionContext中创建,cleanupRequest中清理

 

     /**
     * Creates the action context and initializes the thread local
     */
    public ActionContext createActionContext(HttpServletRequest request, HttpServletResponse response) {
        ActionContext ctx;
        Integer counter = 1;
        Integer oldCounter = (Integer) request.getAttribute(CLEANUP_RECURSION_COUNTER);
        if (oldCounter != null) {
            counter = oldCounter + 1;
        }

        ActionContext oldContext = ActionContext.getContext();
        if (oldContext != null) {
            // detected existing context, so we are probably in a forward
            ctx = new ActionContext(new HashMap<String, Object>(oldContext.getContextMap()));
        } else {
            //------创建ValueStack-------
            ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
            stack.getContext().putAll(dispatcher.createContextMap(request, response, null, servletContext));
            ctx = new ActionContext(stack.getContext());
        }
        request.setAttribute(CLEANUP_RECURSION_COUNTER, counter);
        ActionContext.setContext(ctx);
        return ctx;
    }

 

 

结构

在OgnlValueStack中有两个至关重要的东西,简称“对象栈”和“Map栈”。 

 

CompoundRoot root;
transient Map<String, Object> context;

 

对象栈的说明:1.处于对象栈中的对象,它的属性是可以直接访问的。2.如果在对象栈中有相同名称的属性,那么从栈顶开始查找,直到找到为止。3.一般情况下回显的数据应该放在对象栈中,这样效率比较高。4.用Ognl表达式访问对象栈,直接属性名称就可以了,不用加#。

map栈的说明:1.request,session,application都在map栈中。2.可以把一个对象放到map中。3.Ognl表达式访问map栈中的内容:如果一个对象在map中,那么就是#request.对象的key值.属性; 如果一个对象直接放入到map中,那么就是#对象的key值.属性。注意:把一个对象放到map栈中,你是不能直接访问这个对象的属性的。

这里写图片描述

ModelDriven

ModelDriven背后的机制就是ValueStack。界面通过username、password这样的名称,就能够被直接赋值给user对象。

那么,为什么user对象会在ValueStack中呢?它是什么时候被压入ValueStack的呢? 
答案是:ModelDrivenInterceptor。 
ModelDrivenInterceptor是缺省的拦截器链的一部分,当一个请求经过ModelDrivenInterceptor的时候,在这个拦截器中,会判断当前要调用的Action对象是否实现了ModelDriven接口,如果实现了这个接口,则调用getModel()方法,并把返回值(本例是返回user对象)压入ValueStack。

 

    public String intercept(ActionInvocation invocation) throws Exception {
        Object action = invocation.getAction();

        if (action instanceof ModelDriven) {
            ModelDriven modelDriven = (ModelDriven) action;
            ValueStack stack = invocation.getStack();
            Object model = modelDriven.getModel();
            if (model !=  null) {
                //放入栈中
                stack.push(model);
            }
            if (refreshModelBeforeResult) {
                invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven, model));
            }
        }
        return invocation.invoke();
    }

 

如何赋值

Struts2有个params拦截器(ParametersInterceptor),它是在调用你的LogonAction之前调用的,它会把request里面的参数(就是jsp页面上传递过来的那些值)取出来,去跟LogonAction里面的变量匹配,匹配到了就set进去,这里匹配是以setXXX方法为基准的。 
比如jsp页面上有个userName参数,拦截器就去LogonAction里面找setUserName()方法,找到了就把userName参数的值传递到setUserName()方法里面,setUserName()方法再把值赋给LogonAction里面的userName变量(这个名字随便是什么都行,因为拦截器只认setUserName()方法)。 
如果jsp页面上有个user.userName参数,拦截器就去LogonAction里面找setUser()方法,当然setUser()方法的参数就是一个User对象,所以拦截器会new一个User对象给这个setUser()方法,接着拦截器会到User对象中找setUserName()方法,并将user.userName参数的值传递给这个setUserName()方法。

流程图

赋值方法

(1)向map栈中存数据,即ValueStack中的context(OgnlContext)

ServletActionContext.getRequest().setAttribute("key","value");  
ServletActionContext.getSession().put("key","value");

    通过request,session等向map中存储数据

 

ActionContext.getContext().put("key","value");    

     直接向map栈中放数据,通过JSONResult返回json格式的数据时可以使用这种方式赋值

    @Action(value = "json", results = {@Result(type = "json", params = {"root", "result"})})
    public String queryFlowProject() {
        JSONArray result = new JSONArray();
        ServletActionContext.getContext().put("result", result);
        return "success";
    }

 

(2)向对象栈中存数据,即ValueStack中的root(CompoundRoot)对象

ValueStack valueStack = ActionContext.getContext().getValueStack();
valueStack.getRoot().add(new Object());

     先得到root,再把数据压入到root中,这中方式是放入到栈底.

 

ValueStack valueStack = ActionContext.getContext().getValueStack();
valueStack.getRoot().add(0,new Object());//这里0,表示压入栈顶.

     先得到root,利用add(index,Object)把一个对象压入到root中指定位置.

 

ValueStack valueStack = ActionContext.getContext().getValueStack();
valueStack.set("key","value");//先New一个Map,再调用push方法把Map放入到对象栈中,且放入栈顶.

     存放一个map到对象栈中

 

ValueStack valueStack = ActionContext.getContext().getValueStack();
valueStack.push(new Object());

     利用valueStack的push方法把一个对象直接压入栈顶

分享到:
评论

相关推荐

    Struts2 原理及搭建

    3. **OGNL(Object-Graph Navigation Language)表达式**:Struts2使用OGNL作为默认的表达式语言,它允许在Action和视图之间传递数据,如取值、赋值、方法调用等。OGNL的强大在于其灵活性,可以方便地处理复杂的数据...

    struts2数据类型转换器

    Struts2是一个非常流行的Java Web框架,它提供了一种优雅的方式来组织和控制应用程序的流程,同时也简化了MVC(模型-视图-控制器)架构的实现。在Struts2中,数据类型转换器是一个关键组件,它负责将HTTP请求参数...

    struts2培训笔记

    **编程方式**:Struts2支持多种编程模型,包括传统的JavaBean风格和POJO(Plain Old Java Object)风格。 **编程模型**:Struts2支持面向接口的编程模型,如Action接口等,这些模型有助于开发者更好地组织代码。 #...

    Xwork——Struts2核心

    通过深入理解Xwork框架的基本原理和关键技术,开发者不仅能够有效地利用Struts2框架来构建高性能的Web应用程序,还能够在更广泛的范围内应用Xwork的强大功能,从而提高开发效率并增强应用程序的可维护性。

    Struts2例子6

    Struts2是一个强大的MVC(模型-视图-控制器)框架,被广泛应用于Java Web开发。在Struts2中,转换器...通过实践"Struts2例子6",开发者可以更深入地了解Struts2框架的工作原理,提高处理复杂数据类型转换的能力。

    传智168期JavaEE struts2杜宏 day32~day33笔记

    ### 传智168期JavaEE Struts2杜宏 Day32~Day33 笔记 #### OGNL介绍与简单使用 ##### OGNL概述 ...通过深入理解OGNL的工作原理及其在Struts2中的应用方式,可以帮助开发者更好地利用这一工具提高开发效率。

    struts2通配符示例

    在Struts2中,通配符匹配功能是一个非常实用的特性,它允许我们使用一种相对灵活的方式来映射Action请求,从而简化配置并提高代码的可维护性。以下是对"struts2通配符示例"的详细解释: 1. **通配符匹配原理**: ...

    struts2注释

    Struts2注释是Struts2框架中一种重要的元数据表达方式,它允许开发者在Java代码中直接标注信息,以简化配置文件的管理和提高开发效率。Struts2框架支持两种主要的配置方式:XML配置和注解(Annotation)配置。 XML...

    struts2中循环标签id的设置

    下面将详细解释如何在Struts2中设置循环标签的ID以及其工作原理。 首先,`s:iterator`标签的基本结构如下: ```jsp &lt;!-- 迭代体内容 --&gt; ``` 这里的`collectionName`是要迭代的集合对象,而`statusVariable`则...

    Struts2-S2-029漏洞分析1

    在`org.apache.struts2.components.UIBean`类中,`id`参数在`setID`时被首次执行OGNL表达式。随后在`UIBean.populateComponentHtmlId(Form)`方法中,通过`findStringIfAltSyntax`方法进行了第二次解析,其中`find...

    Struts2验证操作文档

    ### Struts2框架的验证原理 Struts2框架的验证机制基于一种设计理念:类型转换与输入验证是相辅相成的过程。框架首先尝试将用户提交的数据转换为正确的数据类型。如果转换失败,则表明用户输入了非法数据。然而,...

    Struts2学习教程之拦截器机制与自定义拦截器

    Struts2内建的拦截器在Struts2框架中有很多内建的拦截器,这些拦截器几乎完成了Struts2框架70%的工作,包括解析请求参数,将请求参数赋值给Action属性等,Struts2这种灵巧的设计,很大程度上得益于拦截器的设计;...

    探讨Struts的初始化方法

    ### Struts框架初始化详解 #### 一、Struts框架简介 Struts是一个开源的MVC(Model-View-...理解这些初始化细节有助于开发者更好地掌握Struts的工作原理,并在开发过程中有效地利用其特性来提高应用的质量和性能。

    模仿struts的servlet

    模仿Struts的Servlet可能也提供了类似的机制,通过注解或者配置文件,可以自动将请求参数赋值给Servlet中的对象属性,简化了数据处理的步骤。 为了实现这个功能,Servlet可能使用了以下技术: 1. 请求参数解析:...

    Struts2+Spring+Hibernate知识点总结

    Struts2负责处理Web请求,Spring则关注于业务逻辑的组织和管理,而Hibernate专注于对象和数据库之间的映射。这三大框架相互配合,可以极大地提高开发效率,同时也使得项目结构更加清晰、易于维护。

    使用反射自动装填前台数据和struts自动装填很像

    总结来说,Struts的自动装填和反射自动装填前台数据虽然在概念上类似,都涉及到了数据绑定和对象的属性设置,但它们的实现方式有所不同。Struts依赖于框架内部的机制和约定,而反射则更底层,提供了更多的灵活性,但...

    Struts2学习教程之自定义类型转换器的方法

    至此,我们已经详细阐述了在Struts2中自定义类型转换器的步骤和原理。自定义转换器允许开发者根据实际需求灵活地处理不同类型之间的转换,极大地扩展了Struts2框架的功能性。在实际开发中,合理利用自定义类型转换器...

    Struts_config.xml详解

    Struts框架的核心配置文件`struts-config.xml`是整个应用的关键组成部分之一,它定义了应用程序中各个组件(如Action、FormBean等)的行为与交互方式。本文将详细介绍`struits-config.xml`中的关键配置项,并解释其...

    Strut2 in action [英文版]

    - **工作原理**:当Struts2接收到请求时,会尝试将请求参数转换为动作类中对应的属性类型。 - **示例代码**: ```java public class UserAction extends ActionSupport { private int userId; public void set...

    传智播客 赖家才老师 主讲 struts1 的课堂总结

    Struts 是一个经典的Java Web开发框架,主要用于构建MVC(Model-View-Controller)架构的应用程序。赖家才老师的课堂总结深入浅...通过赖家才老师的讲解,我们可以更好地掌握Struts1的工作原理,提升Java Web开发能力。

Global site tag (gtag.js) - Google Analytics