通过Struts 2中的ModelDriven将参数传递给操作

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

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", results=@Result(location = "/modelDriven/modelDriven.jsp")), @Action(value="modelDrivenResult", results=@Result(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:

     

modelDrivenResult.jsp:

 

在动作execute方法中,我们获取参数name ,该name应由params拦截器填充并初始化model属性以在结果中显示它。 但问题是参数未填充。 如何获取参数name由params拦截器填充,所以动作可以显示值?

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

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

如果应在操作上设置名称为name的属性,则可以直接将该属性命名为[1].name 。 但是, params拦截器的默认模式不接受这样的参数名称。 但是,它是一个有效的OGNL表达式。 因此,要让它通过拦截器,您需要将其添加到接受的参数名称模式中。 像那样

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

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