2014-01-22 35 views
3

该问题与ModelDriven和Struts 2.3.16有关。由于params拦截器的行为改为访问传递给动作的参数,需要配置acceptParamNames列表才能使用ModelDriven动作。如果acceptParamNames列表为空,则默认情况下它通过默认模式接受参数。假设我们有一个通过ModelDriven在Struts 2中传递参数以采取行动

ModelDriven行动:

@Namespace("/modelDriven") 
public class ModelDrivenAction extends ActionSupport implements ModelDriven { 

    private Gangster model = new Gangster(); 

    private String name; //getter and setter 

    public Object getModel() { 
    return model; 
    } 

    @Actions({ 
    @Action(value="modelDriven", [email protected](location = "/modelDriven/modelDriven.jsp")), 
    @Action(value="modelDrivenResult", [email protected](location = "/modelDriven/modelDrivenResult.jsp")) 
    }) 
    public String execute() throws Exception { 
    model.setName(name); 
    return SUCCESS; 
    } 
} 

模型:

public class Gangster { 
    private String name; //getter and setter 
} 

modelDriven.jsp:

<s:form id="modelDrivenForm" action="modelDrivenResult" method="POST" namespace="/modelDriven">  
    <s:textfield 
     label="Gangster Name" 
     name="[1].name"/> 
    <sj:submit cssClass="btn btn-primary" executeScripts="true" targets="div1"/> 
</s:form> 

<div id="div1"/> 

modelDrivenResult.jsp:

<s:label 
    label="Gangster Name" 
    name="name"/><br/> 

在操作execute方法我们得到参数name应由params拦截器来填充和初始化模型属性的结果显示它。但问题是参数没有填充。如何获取参数name由params拦截器填充,因此该操作可以显示值?

回答

0

name是模型的属性,也是动作类的属性。拦截器将模型推到值栈的顶部,因此在JSP中使用它很容易。操作对象位于模型下方。因此,可以使用[1]前缀直接引用它。见OGNL basics

但是,如果模型和操作对象中没有重复的属性名称,则不需要。当名称(如name)由OGNL评估时,它会从值栈的顶部搜索到属性访问器的堆栈下。找到的第一个访问器将被执行。因此,模型属性具有优先级,因为模型位于值栈顶部。

如果应在行动上设置名称为name的房产,那么您可以直接将该房产命名为[1].name。但是,此类参数名称不被默认格式的params拦截器接受。但是,这是一个有效的OGNL表达式。所以,为了让它通过拦截器,你需要将它添加到可接受参数名称的模式中。这样

@Action(value="modelDrivenResult", [email protected](location = "/modelDriven/modelDrivenResult.jsp"), 
    interceptorRefs = @InterceptorRef(value="defaultStack", params={ 
    "params.acceptParamNames", "(\\[\\d+\\]\\.)*\\w+((\\.\\w+)|(\\[\\d+\\])|(\\(\\d+\\))|(\\['\\w+'\\])|(\\('\\w+'\\)))*" 
    }) 
) 

这是因为OGNL还检查接受参数的模式,此正则表达式模式允许同时匹配params和OGNL的匹配。

+0

我试着在struts-2.3.15.2中做类似于你的问题的东西,它工作正常,没有必要改变acceptParamNames。这只是2.3.16新? –

+0

'acceptParamNames'即使在旧版本中也需要更改,以获取参数通过拦截器,但在新版本中,如果排除参数,则不会生效。另请参阅[Struts 2 Acceptable Parameters](http://stackoverflow.com/a/20267397/573032)和[struts 2 action with no setter getter](http://stackoverflow.com/a/16604527/573032) –

+0

@ SiddharthTrikha你不明白这不是2.3.15.x吗? Struts 2.3。16有不同的实现和行为。 –