Estoy pasando algunos parámetros para una clase de acción de la implementación de ModelDriven<Transporter> a través de una consulta de cadena.

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

La clase de acción es como sigue.

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

El servidor de terminal server muestra los siguientes mensajes.

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', ]

Aunque el nivel de registro es SEVERE, los valores de estos parámetros están disponibles en la clase de acciones, como

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

en el edit() método.

Si paramsPrepareParamsStack es reemplazado por defaultStack entonces, estos mensajes desaparecen.

Expresiones como ['DHL', ] indicar una matriz. transporterId y transporterName en el modelo son, sin embargo, de tipo Long y String respectivamente.

¿Qué estoy haciendo mal?

InformationsquelleAutor Tiny | 2014-01-09

2 Comentarios

  1. 6

    No de la matriz de problema que está implicado aquí (aunque parece que eso): este tipo de excepción significa que Struts no puede encontrar un Setter para el parámetro:

    De ParametersInterceptor documentación:

    Advertencia sobre los parámetros que faltan

    Cuando no hay setter para el parámetro dado nombre, un mensaje de advertencia
    como a continuación se registrará en 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)

    Así es el comportamiento esperado para permitir a los desarrolladores para detectar falta de incubadora
    o de un error, ya sea en nombre de parámetro o un setter.

    Usted puede fácilmente reproducir este error por poner un elemento en JSP que no existe en la Acción.

    Ya que sus propiedades existen (con sus Incubadoras) en el Modelo, y usted está utilizando ModelDriven y paramsPrepareParamsStack, lo que creo que está pasando es:

    • ModelDriven Interceptor se delega a manejar el Modelo de objeto;
    • La primera vez que llame a Parameters Interceptor, ModelDriven Interceptor no se ha ejecutado todavía;
    • A continuación, su Acción no sabe nada sobre el Modelo de objetos, y tratar de encontrar las Incubadoras para sus parámetros en la Acción, NO en el Modelo.
    • La segunda interceptor en su lugar se ejecuta después de que el impulsado por modelos uno, y sabe exactamente dónde establecer los parámetros. Esta es la razón por la que tienen correctamente los parámetros establecidos en el método de Acción.

    Pero si esto es cierto, entonces usted debe NO ser capaz de recuperar los parámetros en el prepare() método (que es la razón por la que usted está usando esta pila…):
    intente, y después aquí el resultado.

    La primera cosa que viene a mi mente para resolver este problema, es el lugar de los ModelDriven Interceptor antes de la primera Parameters Interceptor (ya sea copiando o moviendo, no estoy seguro de qué tipo de efectos secundarios, si los hubiere, que podrían producir en ambos casos, usted debe vuelva a intentar y presentación de informes aquí).

    A continuación, defina los siguientes pila, y el uso de la misma.

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

    Espero que ayude.

    • El uso de paramsPrepareParamsStack junto con ModelDriven<T extends Object>, campo de valores de la propiedad en el modelo no estaban disponibles en la prepare() método. El uso de esta pila, los mensajes se desvanecieron en el aire, modelo de valores también están disponibles en el prepare() método.
    • +1 Buena explicación detallada
    • bonito, me alegro de que funcionó !
  2. 0

    En el código que te han dado, no puedo encontrar la declaración del Transportador de la Clase.

    Así que supongo que tal vez es porque su Transpoter clase tiene más parámetros que la 2, no sólo id y nombre.

    De hecho, este mensaje de error siempre ha ocurrido en la situación que he mencionado.

    Para resolver este problema, se puede definir un transporte de datos de objeto(DTO), que sólo tiene 2 atributos id y nombre. El uso de este DTO para aceptar los parámetros de la jsp y, a continuación, pasar los valores de los atributos para el Transportador de objeto.

    Veo este problemas en 2019, y ofrecer una solución, con la esperanza de que puede ser de uso por parte de otros en el futuro.

Dejar respuesta

Please enter your comment!
Please enter your name here