2011-03-22 13 views
7

Estoy usando Spring MVC con Controladores, mi pregunta es ¿cómo devuelvo una respuesta JSON que es diferente del objeto @ResponseBody que se devuelve y se genera para que se devuelva un JSON.Spring MVC return JSONS y excepción Handling

Para dar más detalles, tengo el objeto llamado "DetallesUsuario", que tiene dos campos llamados "nombre", "emailAddress"

@ResponseBody UserDetails 

ahora el JSON devuelto se verá como

{nombre : "TheUsersName", emailAddress: "[email protected]"}

¿hay alguna manera de que pueda modificar el JSON antes de regresar (A LL jsons en todos los métodos en todos los controladores) donde se agregará un campo de "estado" y los otros datos json estarán bajo la tecla "datos" en el json.

También cómo puedo devolver un JSON a la interfaz cuando el servidor Java desde algún lugar se produce una excepción, el JSON debe tener "status: true" y el nombre de la excepción (al menos la parte de estado aunque)

+0

Quizás relacionado: http://stackoverflow.com/questions/6014784/serialize-specific-exceptions-with-spring-mvc – Bozho

Respuesta

2

Sí. Devuelve un modelo y una vista en su lugar.

public ModelMap getUserDetails() { 
    UserDetails userDetails; // get this object from somewhere 
    ModelMap map = new ModelMap()(; 
    map.addAttribute("data", userDetails); 
    map.addAttribute("success", true); 
    return map; 
} 

Para agregar la excepción, lo haría de la misma manera con una clave y éxito = falso.

+0

No veo qué valor 'ModelAndView' agrega aquí. ¿Por qué no simplemente devuelve 'ModelMap'? – skaffman

+0

No estoy seguro de por qué querría usar un ModelAndView, sin embargo, me dio la idea de usar un mapa (HashMap) que funcionó como un amuleto y me dio el resultado deseado. Sin embargo, ¿cómo hago lo mismo en un escenario fallido? Sin embargo, ¿hay alguna idea de una forma de centralizar esto cuando para todos los controladores y todas las funciones en los controladores? – MilindaD

+0

@skaffman Tienes razón. Fart de cerebro de devolver puntos de vista también. @milindaD ModelMap no requiere claves, pero no es muy diferente. Implementa Map. –

14

Crear una clase de respuesta:

public class Response<T> { 
    T data; 
    boolean status = true; 

    public Response(T d) { data = d; } 
} 

A continuación, volver que a partir de los controladores:

@ResponseBody public Response getUserDetails) { 
    //... 
    return new Response(userDetails); 
} 

Para la excepción que querrá devolver un objeto como:

public class BadStatus { 
    String errorMessage; 
    boolean status = false; 

    public BadStatus(String msg) { errorMessage = msg; } 
} 

@ExceptionHandler(Exception.class) 
public BadStatus handleException(Exception ex, HttpServletRequest request) { 
    return new BadStatus(ex.getMessage()); 
} 
+0

Consulte este hilo para obtener una respuesta más detallada: http://stackoverflow.com/questions/5641091/spring-3-exception-handling-using-json – Sydney

2

Una solución alternativa (funciona con el resorte 3.1), que es menos invasiva

en su configuración de primavera:

<bean id="jacksonConverter"  class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" /> 
<mvc:annotation-driven> 
    <mvc:message-converters> 
     <bean class="mypackage.MyMessageConverter" 
      p:delegate-ref="jacksonConverter"> 
     </bean> 
    </mvc:message-converters> 
</mvc:annotation-driven> 

La idea es proporcionar su propio HttpMessageConverter que los delegados al convertidor Jackson proporcionado.

public class MyMessageConverter implements HttpMessageConverter<Object> { 
// setters and delegating overrides ommitted for brevity 
@Override 
    public void write(Object t, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, 
      HttpMessageNotWritableException { 
// t is whatever your @ResponseBody annotated methods return 
     MyPojoWrapper response = new MyPojoWrapper(t); 

     delegate.write(response, contentType, outputMessage); 
    } 
} 

De esta manera todos sus POJOs se envuelven con alguna otra JSON que proporcione allí.

Para excepciones, la solución propuesta por ericacm es la forma más sencilla de hacerlo (recuerde anotar el tipo de devolución 'BadStatus' con @ResponseBody).

Una advertencia: su BadStatus json-serializado también pasa por MyMessageConverter, por lo que querrá probar el tipo de objeto en el método de "escritura" modificado, o hacer que MyPojoWrapper lo maneje.