viernes, 28 de diciembre de 2012

Struts 2 y JSONException

Ya hablamos anteriormente de como usar una llamada asincrona que devuelva JSON con Struts 2. En ese caso la configuración para el action la hicimos a través de anotaciones.

En este post mataremos dos pajaros de un tiro y explicaremos como hacerla a través del fichero de configuración de Struts y como evitar problemas al integrar estas dos tecnologias con Spring. Vayamos por parte, en el fichero de configuración donde hemos declarado el paquete donde van incluidas las clases que usan JSON, añadimos el nuevo action a usar.

   
      
   

Como podéis ver, indicamos el action a usar y le decimos que el resultado va a ser de tipo JSON, ya no necesitamos indicar mediante anotaciones nada en la clase. Este sería un ejemplo de su uso
public class LoadParamsAction extends ActionSupport{
   private static final Logger LOGGER = Logger.getLogger(LoadParamsAction.class);
   @Autowired
   private ConsultService service;
   private String exit;

   public String execute(){
      ...
      return Action.SUCCESS;
   }
}
Ya solo quedaría la llamada mediante javascript tal y como la hemos hecho antes
function loadParams() {
   var formulario = dojo.byId("form01");
   formulario.action = 'loadParamsJson.action';
   var xhrArgs = {
      form : formulario,
      handleAs : "json",
      load : function(data) {
          ...
      }
   };
   dojo.xhrPost(xhrArgs);
}
Ahora bien, tal y como hemos puesto el código puede darte el siguiente error:
org.apache.struts2.json.JSONException: org.apache.struts2.json.JSONException: org.apache.struts2.json.JSONException: java.lang.IllegalAccessException: Class org.apache.struts2.json.JSONWriter can not access a member of class org.springframework.aop.interceptor.ExposeInvocationInterceptor$1 with modifiers "public"
Porque es esto? si todo esta puesto como indica cualquier manual? Es debido a que tal y como hemos indicado en el otro post, Struts tratará de pasar a JSON todos los atributos que tengas en la clase. Esto incluye el Service que hemos inyectado a través de Spring. Por lo que al tratar de pasar a JSON el service con todo lo que ello acarrea (AOP), la aplicación simplemente no es capas de hacerlo. Para evitar esto, tenemos la siguiente solución, que no es más que indicarle que atributos de la clase no queremos que sean transmitidos a través de JSON. Esto nos puede servir no solo para evitar esta excepción sino que también nos sirve para retornar solo los valores necesarios desde el action y evitar un flujo excesivo de datos. Debemos modificar la llamada en el fichero de configuración e indicar que no queremos transmitir.

   
      service
   

No hay comentarios:

Publicar un comentario