2011-10-11 16 views
5

Estoy usando Spring 3.0.6 y tengo un solo controlador para cargar archivos en el servidor. Estoy usando un script para cargar usando XmlHttpRequest para los navegadores que lo soportan, mientras que el resto de los navegadores envían un formulario de varias partes (oculto). El problema sin embargo es que cuando se envía un formulario que envía el siguiente encabezado:Spring MVC, force JSON response in plain request

Accept text/html, application/xhtml+xml, */* 

Calculo que debido a esta cabecera el controlador que está marcado con @ResponseBody responde con la respuesta ha convertido a XML en lugar de JSON. ¿Hay alguna forma de evitar esto sin hackear la solicitud de envío del formulario?

Respuesta

8

puede forzar el uso de JSON @RequestMapping(produces = "application/json"). No recuerdo si esto está disponible en 3.0 pero está disponible en 3.1 y 3.2 seguro.

Como han notado otros, Jackson necesita estar en su classpath.

+0

Esto se ve bien, sin embargo, como dijiste, no sé si es aplicable a Spring 3.0 – nvrs

+0

Además de esto, necesitas que el requisito tenga el encabezado Accept, como este Acepte: "application/json; charset = utf-8", para que spring mvc sepa qué convertidor usar para generar la respuesta correcta. – lukass77

1

Si desea una respuesta JSON, puede lograrlo fácilmente teniendo el Jackson JARs en su classpath. Spring los detectará automáticamente cuando estén allí y convertirá su @ResponseBody en JSON.

+1

Pero lo hago, estoy usando Jackson. El mismo método cuando responde a una solicitud con accept: application/json header lo envía como JSON. Pero parece que Spring MVC responde con XML cuando está ausente – nvrs

0

me hizo trabajar por deshacerse de @ResponseBody y en lugar de hacerlo manualmente la conversión (siempre usando Jackson), es decir

Response r = new Response(); 
    ObjectMapper mapper = new ObjectMapper(); 
    JsonGenerator generator = mapper.getJsonFactory().createJsonGenerator(response.getOutputStream(), JsonEncoding.UTF8); 
    try { 
     File f = uploadService.getAjaxUploadedFile(request); 
     r.setData(f.getName()); 
    } catch (Exception e) { 
     logger.info(e.getMessage()); 
     r = new Response(new ResponseError(e.getMessage(), "")); 
    } 
    mapper.writeValue(generator, r); 
    generator.flush(); 

¿Alguien sabe de otra manera? Intenté configurar un ContentNegotiatingViewResolver, pero no quiero romper ningún otro controlador asignando todos los hmtl a json. Además, traté de hacerlo para este método solo a través de un viewresolver personalizado, pero cuando configuro un jsonview y uso BeanNameViewResolver aunque la respuesta se convierte correctamente a JSON, el servidor lanza una excepción HttpRequestMethodNotSupportedException:, con el método de solicitud 'POST' no compatible y configurado estado a 404.

2

¡Gracias! Estaba teniendo exactamente el mismo problema y su publicación resolvió mi problema.

En la interfaz de usuario que estoy usando jQuery con este archivo plugin de carga: https://github.com/blueimp/jQuery-File-Upload/wiki

Aquí está mi método completado (menos la lógica de negocio):

@RequestMapping(value = "/upload", method = RequestMethod.POST) 
public void handleUpload(@RequestParam("fileToUpload") CommonsMultipartFile uploadFile, ServletResponse response){ 

    List<UploadStatus> status = new ArrayList<UploadStatus>(); 
    UploadStatus uploadStatus = new UploadStatus(); 
    status.add(uploadStatus); 

    if(uploadFile == null || StringUtils.isBlank(uploadFile.getOriginalFilename())){ 
     uploadStatus.setMessage(new Message(MessageType.important, "File name must be specified.")); 
    }else{ 
     uploadStatus.setName(uploadFile.getOriginalFilename()); 
     uploadStatus.setSize(uploadFile.getSize()); 
    } 
    ObjectMapper mapper = new ObjectMapper(); 
    try { 
     JsonGenerator generator = mapper.getJsonFactory().createJsonGenerator(response.getOutputStream(), JsonEncoding.UTF8); 
     mapper.writeValue(generator, status); 
     generator.flush(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

}