Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
275 views
in Technique[技术] by (71.8m points)

java - Passing parameters to action through ModelDriven in Struts 2

The issue is related to the ModelDriven and Struts 2.3.16. Since the behavior of the params interceptor changed to access parameters passed to the action requires to configure acceptParamNames list to use with ModelDriven action. If acceptParamNames list is empty, it works by default accepting params via default pattern. Suppose we have a

ModelDriven action:

@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;
  }
}

the model:

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/>

In the action execute method we are getting parameter name which should be populated by the params interceptor and initializing the model property to display it in the result. But the problem is the parameter is not populated. How to get parameter name being populated by the params interceptor, so the action could display the value?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The name is the property of the model and also the property of the action class. The modelDriven interceptor pushes the model on top of the value stack, so it is easy to use it in JSP. The action object is below the model. So, it could be referenced directly using [1] prefix. See OGNL basics.

But it's not necessary if there's no duplicate property names in the model and action object. When the name such as name is evaluated by OGNL it searches from the top of the valueStack to down the stack for the property accessor. The first found accessor will be executed. So, the model property has a priority because the model is on top of the value stack.

If the property with the name name should be set on the action then you could directly name that property as [1].name. But, such parameter name is not accepted by default pattern of params interceptor. However, it is a valid OGNL expression. So, to get it pass through the interceptor you need to add it to a pattern of accepted parameter names. Like that

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

This is because OGNL also checks the pattern of accepted parameters and this regex pattern allows to match both params and OGNL matchers.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...