An unexpected exception caught the parameter "xxx" in the "class xxx: error setting expression" xxx "with value ['x',]

I pass some parameters to an action class that implements ModelDriven<Transporter> via the query string.

 <s:form namespace="/admin_side" action="Test" id="dataForm" name="dataForm"> <s:url id="editURL" action="EditTest" escapeAmp="false"> <s:param name="transporterId" value="1"/> <s:param name="transporterName" value="'DHL'"/> </s:url> <s:a href="%{editURL}">Click</s:a> </s:form> 

The action class is as follows.

 @Namespace("/admin_side") @ResultPath("/WEB-INF/content") @ParentPackage(value = "struts-default") public final class TestAction extends ActionSupport implements Serializable, Preparable, ModelDriven<Transporter> { private static final long serialVersionUID = 1L; private Transporter transporter = new Transporter(); @Action(value = "Test", results = { @Result(name = ActionSupport.SUCCESS, location = "Test.jsp"), @Result(name = ActionSupport.INPUT, location = "Test.jsp")}, interceptorRefs = { @InterceptorRef(value = "paramsPrepareParamsStack", params = {"params.acceptParamNames", "transporterId, transporterName"})}) public String load() throws Exception { return ActionSupport.SUCCESS; } @Action(value = "EditTest", results = { @Result(name = ActionSupport.SUCCESS, location = "Test.jsp"), @Result(name = ActionSupport.INPUT, location = "Test.jsp")}, interceptorRefs = { @InterceptorRef(value = "paramsPrepareParamsStack", params = {"params.acceptParamNames", "transporterId, transporterName"})}) public String edit() { System.out.println(transporter.getTransporterId() + " : " + transporter.getTransporterName()); return ActionSupport.SUCCESS; } @Override public Transporter getModel() { return transporter; } @Override public void prepare() throws Exception {} } 

The server terminal displays the following messages.

 Jan 09, 2014 4:06:32 PM com.opensymphony.xwork2.interceptor.ParametersInterceptor error SEVERE: Developer Notification (set struts.devMode to false to disable this message): Unexpected Exception caught setting 'transporterId' on 'class actions.TestAction: Error setting expression 'transporterId' with value ['1', ] Jan 09, 2014 4:06:32 PM com.opensymphony.xwork2.interceptor.ParametersInterceptor error SEVERE: Developer Notification (set struts.devMode to false to disable this message): Unexpected Exception caught setting 'transporterName' on 'class actions.TestAction: Error setting expression 'transporterName' with value ['DHL', ] 

Although the log level is SEVERE , the values โ€‹โ€‹of these parameters are available in the action class as

 System.out.println(transporter.getTransporterId() + " : " + transporter.getTransporterName()); 

in the edit() method.

If paramsPrepareParamsStack is replaced with defaultStack , then these messages disappear.

Expressions like ['DHL', ] point to an array. transporterId and transporterName in the model, however, are of type Long and String respectively.

What am I doing wrong?

+4
source share
2 answers

There is no problem with arrays (even if it looks like this): this kind of exception means that Struts cannot find the Setter for your parameter:

From the documentation of ParametersInterceptor :

Missing Parameters Warning

If there is no installer for the specified parameter name, a warning message similar to the one below will be written to devMode:

 SEVERE: Developer Notification (set struts.devMode to false to disable this message): Unexpected Exception caught setting 'search' on 'class demo.ItemSearchAction: Error setting expression 'search' with value ['search', ] Error setting expression 'search' with value ['search', ] - [unknown location] at com.opensymphony.xwork2.ognl.OgnlValueStack.handleRuntimeException(OgnlValueStack.java:201) at com.opensymphony.xwork2.ognl.OgnlValueStack.setValue(OgnlValueStack.java:178) at com.opensymphony.xwork2.ognl.OgnlValueStack.setParameter(OgnlValueStack.java:152) 

Thus, a behavior is expected that allows the developer to detect the missing installer or typo in either the parameter name or the installer.

You can easily reproduce this error by placing an element in the JSP that does not exist in the action.

Since your properties exist (with their installers) in the model, and you use ModelDriven and paramsPrepareParamsStack , I think what happens:

  • ModelDriven Interceptor delegated to handle the Model object;
  • The first time Parameters Interceptor ModelDriven Interceptor did not start yet;
  • Then your action does not know anything about the model object and will try to find the setters for your parameters in the action, and not in the model.
  • Instead, the second interceptor fires after ModelDriven and knows exactly where to set the parameters. This is why the parameters are set correctly in the Action method.

But if so, then you SHOULD NOT get these parameters in the prepare() method (which is why you are using this stack ...):
Please try and post the result here.

The first thing that comes to my mind to solve this problem is to place the ModelDriven Interceptor in front of the first Parameters Interceptor (either copying it or moving it, I'm not sure what side effect, if any, can occur in both cases, you should try again to report it here).

Then define the next stack and use it.

 <interceptor-stack name="modelParamsPrepareParamsStack"> <interceptor-ref name="exception"/> <interceptor-ref name="alias"/> <interceptor-ref name="i18n"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="multiselect"/> <!-- NEW ModelDriven Position --> <interceptor-ref name="modelDriven"/> <interceptor-ref name="params"> <param name="excludeParams">^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.*</param> </interceptor-ref> <interceptor-ref name="servletConfig"/> <interceptor-ref name="prepare"/> <interceptor-ref name="chain"/> <!-- OLD ModelDriven Position --> <!--interceptor-ref name="modelDriven"/--> <interceptor-ref name="fileUpload"/> <interceptor-ref name="staticParams"/> <interceptor-ref name="actionMappingParams"/> <interceptor-ref name="params"> <param name="excludeParams">^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.*</param> </interceptor-ref> <interceptor-ref name="conversionError"/> <interceptor-ref name="validation"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="workflow"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> </interceptor-stack> 

Hope this helps.

+5
source

In the code you gave, I cannot find the declaration of the Transporter class.

Therefore, I think this may be because your Transpoter class has more parameters than 2, and not just the identifier and name.

In fact, this error message always occurred in the situation I was talking about.

To solve this problem, you can define a data transfer object (DTO) that has only 2 attributes, id and name. Use this DTO to accept parameters from jsp and then pass the value of the attributes to the Transporter object.

I see this problem in 2019 and propose a solution, hoping that it can be useful for others in the future.

0
source

All Articles