2012-10-11 43 views
95

Estoy usando el $.getJSON() de jQuery para hacer llamadas asíncronas a mi backend Spring MVC simple. La mayoría de los métodos de controlador de primavera siguiente aspecto:¿Qué devolver si el método del controlador Spring MVC no devuelve el valor?

@RequestMapping(value = "/someURL", method = RequestMethod.POST) 
public @ResponseBody SomePOJO getSomeData(@ModelAttribute Widget widget, 
    @RequestParam("type") String type) { 
    return someDAO.getSomeData(widget, type); 
} 

tengo cosas establecido de manera que cada controlador devuelve el @ResponseBody como JSON, que es lo que espera el lado del cliente.

¿Pero qué sucede cuando se supone que una solicitud no devuelve ningún contenido al lado del cliente? ¿Puedo tener:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST) 
public @ResponseBody void updateDataThatDoesntRequireClientToBeNotified(...) { 
    ... 
} 

Si no es así, ¿cuál es la sintaxis adecuada para usar aquí? ¡Gracias por adelantado!

+0

Supongo que si no devuelve nada, ¿no se devolverá ningún contenido? – arahant

+1

Creo que todavía devolvería un POJO de algún tipo, incluso si en la Versión 1 de su solución simplemente incluye un booleano "exitoso" o algo similar. Entonces tienes un patrón consistente en todos tus métodos AJAX, y algo que es más fácil de construir cuando resulta que * ¡debes * devolver algo! – millhouse

+0

Contrariamente a lo que sugieren las respuestas, lo que primero tenía en su segundo fragmento está perfectamente bien y es la forma correcta de manejar datos 'POST'. –

Respuesta

181

se puede volver vacío, entonces usted tiene que marcar el método con @ResponseStatus (valor = HttpStatus.OK) no es necesario @ responseBody

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST) 
@ResponseStatus(value = HttpStatus.OK) 
public void updateDataThatDoesntRequireClientToBeNotified(...) { 
    ... 
} 

Sólo conseguir métodos devuelven un código de estado 200 implícitamente, todos los otros, hay que hacer una de tres cosas:

  • retorno void y marcar con el método @ResponseStatus (valor = HttpStatus.OK)
  • devolver un objeto y marcarlo con @ResponseBody
  • devolver un HttpEntity ejemplo
+2

En caso de que se produzca una excepción de tiempo de ejecución entre ellos, se devolverá HTTP 500 y no 200. Por lo tanto, si falla el identificador de la interfaz, el mensaje de excepción/error se mostrará correctamente. –

+18

En realidad, no necesita establecer '@ ResponseStatus' y no debería. Simplemente tener '@ ResponseBody' en un controlador' void' es suficiente. –

+10

Creo que será mejor devolver un 204 Sin contenido en lugar de un 200 para los métodos de vacío – raspacorp

38

Simplemente puede devolver un ResponseEntity con el encabezado apropiado:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST) 
public ResponseEntity updateDataThatDoesntRequireClientToBeNotified(...){ 
.... 
return new ResponseEntity(HttpStatus.OK) 
} 
+0

En caso de que cualquiera se encuentre con el mismo problema que yo, esto no funcionó en una versión anterior de la primavera (4.1.1) Me daría 500 errores. Me actualicé a 4.2.0 y esto funciona genial – sauce

+0

Esa es mi forma preferida de devolver 200 vacíos también. Desde Spring 4.1, use el patrón de generador en su lugar: return ResponseEntity.ok(). Build(); – GreenTurtle

0

Pero a medida que el sistema crece en tamaño y funcionalidad ... creo que volver siempre a JSON no es una mala idea. Es más una cuestión de arquitectura/"diseño a gran escala".

Puede pensar en obtener siempre un JSON con dos campos conocidos: código y datos. Donde el código es un código numérico que especifica el éxito de la operación a realizar y los datos son datos adicionales relacionados con la operación/servicio solicitado.

Vamos, cuando utilizamos un servidor de back-end de un proveedor de servicios, cualquier servicio se puede verificar para ver si funcionó bien.

Así que me adhiero, para no dejar que el resorte lo administre, exponiendo las operaciones de retorno híbridas (Algunos datos de devolución no otros nada ...) ... instalados asegúrese de que su servidor expone una interfaz más homogénea. Es más simple al final del día.

2

No hay nada de malo en devolver un nulo @ResponseBody y debe para POST solicitudes.

Utilice los códigos de estado HTTP para definir los errores dentro de las rutinas del manejador de excepciones en su lugar, ya que otros mencionan el estado de éxito. Un método normal como el que tiene devolverá un código de respuesta de 200 que es lo que desea, cualquier controlador de excepción puede devolver un objeto de error y un código diferente (es decir, 500).

1

Sí, puede utilizar @ResponseBody con el tipo de retorno void:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST) 
@ResponseBody 
public void updateDataThatDoesntRequireClientToBeNotified(...) { 
    ... 
} 
+0

entonces, ¿cuál será el tipo de devolución ... es el código de estado HTTP? – spandey15

7

Puede volver objeto "ResponseEntity". El uso del objeto "ResponseEntity" es muy conveniente tanto en el momento de construir el objeto de respuesta (que contiene el cuerpo de respuesta y el código de estado HTTP) como al momento de obtener información del objeto de respuesta.

Métodos como getHeaders(), getBody(), getContentType(), getStatusCode() etc hacen que el trabajo de lectura del objeto ResponseEntity sea muy fácil.

Debe utilizar el objeto ResponseEntity con un código de estado http de 204 (Sin contenido), que es específicamente para especificar que la solicitud se ha procesado correctamente y que el cuerpo de la respuesta está intencionalmente en blanco. Usar códigos de estado apropiados para transmitir la información correcta es muy importante, especialmente si está haciendo una API que va a utilizar varias aplicaciones cliente.

+0

configuración '@ResponseStatus (HttpStatus.NO_CONTENT)' resuelto 'XML Parsing Error: no se encontró ningún elemento raíz' en el navegador – aliopi

0

Aquí es ejemplo de código lo que hice por un método asíncrono

@RequestMapping(value = "/import", method = RequestMethod.POST) 
@ResponseStatus(value = HttpStatus.OK) 
public void importDataFromFile(@RequestParam("file") MultipartFile file) 
{ 
    accountingSystemHandler.importData(file, assignChargeCodes); 
} 

No es necesario devolver cualquier cosa de su método de todo lo que necesita para utilizar esta anotación para que su método debe devolver bien en todos los casos

@ResponseStatus(value = HttpStatus.OK) 
Cuestiones relacionadas