2009-07-01 16 views
10

Si tengo una acción donde el resultado es una acción de redirección a otra acción en una clase diferente, ¿es posible obtener errores de validación para mostrar en la acción resultante? P.ej. en el siguiente ejemplo, si un usuario ejecuta actionA (que no tiene vistas asociadas), y hay errores, ¿hay alguna forma de mostrar esos errores en el resultado de actionB (foo.jsp)? ¿O estoy haciendo esto de una manera completamente incorrecta?¿Puedo propagar struts2 ActionErrors entre diferentes clases de acción?

<package name="a" extends="struts-default" namespace="/a"> 
    <action name="actionA" class="actionAClass"> 
     <result name="input" type="redirectAction"> 
      <param name="actionName">actionB</param> 
      <param name="namespace">/b</param> 
     </result> 
     <result type="redirectAction"> 
      <param name="actionName">actionB</param> 
      <param name="namespace">/b</param> 
     </result> 
    </action> 
</package> 
<package name="b" extends="struts-default" namespace="/b"> 
    <action name="actionB" class="actionBClass"> 
     <result>/foo.jsp</result> 
    </action> 
</package> 
+0

Trate de usar MessageStore Interceptor - http://struts.apache.org/release/2.3.x/docs/message-store-interceptor.html –

Respuesta

4

Puede haber una forma de hacerlo, pero no creo que sea una muy buena manera de utilizar los puntales. Si la acción A está fallando la validación, lo más probable es que desee tener un resultado de entrada que no sea de redireccionamiento que muestre los errores, o tal vez una página de error global que pueda mostrarlo.

Supongo que podría almacenar los errores de acción en algún lugar como la sesión entre el redireccionamiento, pero realmente no estaría utilizando el marco de cómo fue diseñado.

0

Struts2 no es compatible de forma predeterminada. Sin embargo, existe una solución (se realiza mediante un simple interceptor de puntales que almacena los mensajes en sesión).

solution with source code

7

Básicamente se tienen que utilizar interceptores predefinidos llamados tienda que lleva operationMode: almacenar y recuperar:

<package name="a" extends="struts-default" namespace="/a"> 
    <action name="actionA" class="actionAClass"> 
     <!-- Here you are storing the Error messages --> 
     <interceptor-ref name="store"> 
      <param name="operationMode">STORE</param> 
     </interceptor-ref> 

     <!-- include your default stack in case you need to load other interceptors --> 
     <interceptor-ref name="defaultStack" /> 

     <result name="input" type="redirectAction"> 
      <param name="actionName">actionB</param> 
      <param name="namespace">/b</param> 
     </result> 
     <result type="redirectAction"> 
      <param name="actionName">actionB</param> 
      <param name="namespace">/b</param> 
     </result> 
    </action> 
</package> 
<package name="b" extends="struts-default" namespace="/b"> 
    <action name="actionB" class="actionBClass"> 

     <interceptor-ref name="store"> 
      <param name="operationMode">RETRIEVE</param> 
     </interceptor-ref> 

     <!-- include your default stack in case you need to load other interceptors --> 
     <interceptor-ref name="defaultStack" /> 

     <result>/foo.jsp</result> 
    </action> 
</package> 
10

Struts2 por defecto tiene un interceptor tienda. Almacena los actionMessages, actionErrors y fieldErrors en sesión en modo STORE y puede recuperarlos en el siguiente redireccionamiento utilizando el mismo interceptor utilizándolo en el modo RETRIEVE. Más detalles se pueden encontrar here

2

Uso ActionContext.getContext().getSession().put(key, value) en la primera acción y recuperarlo utilizando ActionContext.getContext().getSession().get(key) en el redirectedAction y addActionErrors a la acción principal

+0

supongo MessageStoreInterceptor sería una manera mucho mejor. –

+0

MessageStoreInterceptor - http://struts.apache.org/release/2.3.x/docs/message-store-interceptor.html –

0

Puede utilizar tipo de resultado "cadena".

<action name="delete" class="com.example.Delete"> 
    <result name="error" type="chain"> 
     <param name="actionName">show</param> 
    </result>   
</action> 
<action name="show" class="com.example.Show"> 
    <result name="success" type="dispatcher">/jsp/show.jsp</result>      
</action> 

en show.jsp se puede mostrar errores de acción o mensajes de acción que se configuran en la acción de eliminación

+0

Se desaconseja usar 'chain'. –

6

me parece una mejor solución para pasar errores de acción y mensajes en actionRedirect tipo de resultado. Está funcionando para mí.

<action name="action1" class="action.Action1" > 
    <result>/abc.jsp</result> 
    <result name="input" type="redirectAction"> 
    <param name="actionName">action2</param> 
    <param name="param1">${param1}</param> 
    <param name="param2">${param2}</param> 
    <param name="actionErrors">${actionErrors}</param> 
    </result> 
    </action> 
    <action name="action2" class="action.Action2" > 
    <result>/def.jsp</result> 
    <result name="input">/def.jsp</result> 
    </action/> 

Esta es ..... Feliz codificación de cadena de tipo

+0

' $ {actionErrors}' esto hace toda la magia. – Jibran

+0

¿Esto pasa los mensajes y los errores de acción o necesita ' $ {actionMessages}' para pasar un mensaje? – ponder275

+1

' $ {actionMessages}' pasa los mensajes. ¡Gracias! – ponder275

3

Resultado copiará los mensajes/errores a la acción resultante si siguiente en struts.xml o struts.properties archivo -

struts.xwork.chaining.copyErrors - set to true to copy Action Errors 
struts.xwork.chaining.copyFieldErrors - set to true to copy Field Errors 
struts.xwork.chaining.copyMessages - set to true to copy Action Messages 

Ejemplo (struts.xml) -

<constant name="struts.xwork.chaining.copyErrors" value="true"/> 
0

Esta obra en mí

agregue esta línea en los puntales.xml:

<constant name="struts.xwork.chaining.copyErrors" value="true"/> 
<constant name="struts.xwork.chaining.copyMessages" value="true"/> 

uso tipo de resultado "cadena" y añadir resultado con el nombre de "entrada":

<package name="a" extends="struts-default" namespace="/a"> 
    <action name="actionA" class="actionAClass"> 
     <result name="input" type="chain"> 
      <param name="actionName">actionB</param> 
      <param name="namespace">/b</param> 
     </result> 
     <result type="chain"> 
      <param name="actionName">actionB</param> 
      <param name="namespace">/b</param> 
     </result> 
    </action> 
</package> 
<package name="b" extends="struts-default" namespace="/b"> 
    <action name="actionB" class="actionBClass"> 
     <result>/foo.jsp</result> 
     <result name="input">/foo.jsp</result> 
    </action> 
</package> 
1

El interceptor tienda (MessageStoreInterceptor) se puede utilizar para almacenar y recuperar actionErrors, actionMessages y fieldErrors.

Puede cambiar el funcionamiento del almacén de interceptor sobre la marcha pasando el parámetro operationMode a la acción

http://localhost/sample.action?operationMode=STORE

Puede configurar el interceptor tienda en STORE modo en su pila por defecto que permite a todo mensaje de acción a ser almacenado en la sesión.

<interceptor-ref name="store"> 
      <param name="operationMode">STORE</param> 
    </interceptor-ref> 

para obtener los mensajes que necesita añadir store interceptor en RETRIEVE modo a la acción específica que necesita estos mensajes.

Esta es una página de error global muestra que se redirige a, esta acción puede leer actionErrors, fieldErrors y actionMessages cuando añadimos el interceptor store a la misma y establecer el operationMode a RETRIEVE:

@Action(value = "error-page" , 
       interceptorRefs = 
        {@InterceptorRef(value = "store", params = {"operationMode", "RETRIEVE"})} 
      ) 
public String execute() throws Exception {  
    LOG.error("An error accrued during action ActionErrors '{}' , FieldErrors '{}' " , getActionErrors() , getFieldErrors()); 
    //Rest of the code 
} 

El MessageStoreInterceptor remove errores previos antes de agregar nuevos.

Puede configurar la tienda en AUTOMATIC en su pila predeterminada. De esta forma, todos los mensajes se almacenan siempre y se volverán a intentar automáticamente cuando el resultado de la acción sea ServletRedirectResult (Por ejemplo, si la acción 'redirectAction', 'redirect'). No necesita definir un interceptor explícito store en el modo RETRIEVE.

Aunque no es un buen enfoque, pero puede acceder a los mensajes de la tienda en la sesión con estas teclas.

session.get(MessageStoreInterceptor.fieldErrorsSessionKey) 
session.get(MessageStoreInterceptor.actionErrorsSessionKey) 
session.get(MessageStoreInterceptor.actionMessagesSessionKey) 
Cuestiones relacionadas