2011-10-11 3 views
5

J'utilise Spring 3.0.6 et j'ai un seul contrôleur pour le téléchargement de fichiers sur le serveur. J'utilise un script pour télécharger en utilisant XmlHttpRequest pour les navigateurs qui le supportent tandis que le reste des navigateurs soumettent un formulaire en plusieurs parties (caché). Le problème est cependant que lorsqu'un formulaire est soumis, il envoie l'en-tête suivant:Spring MVC, la force réponse JSON dans la demande plaine

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

Je figure que, en raison de cet en-tête du contrôleur qui est marqué par @ResponseBody réponses avec la réponse été converti en XML au lieu de JSON. Existe-t-il un moyen de contourner ce problème sans pirater la demande de soumission de formulaire?

Répondre

8

Vous pouvez forcer JSON en utilisant @RequestMapping(produces = "application/json"). Je ne me souviens pas si cela est disponible en 3.0 mais il est disponible en 3.1 et 3.2 à coup sûr.

Comme d'autres ont noté, Jackson doit être mis sur votre chemin de classe.

+0

Cela semble bon, mais comme vous l'avez dit, je ne sais pas si elle est applicable au printemps 3.0 – nvrs

+0

dans addtion à ce dont vous avez besoin que le reqeust aura tête Accept, comme celui-ci Acceptez: "application/json; charset = utf-8", de sorte que spring mvc saura quel convertisseur utiliser pour créer la bonne réponse. – lukass77

1

Si vous voulez une réponse JSON, vous pouvez facilement accomplir cela en ayant le Jackson JARs sur votre chemin de classe. Spring les récupèrera automatiquement et convertira votre @ResponseBody en JSON.

+1

Mais je fais, j'utilise Jackson. La même méthode quand il répond à une requête avec accept: l'en-tête application/json l'envoie en JSON. Mais il semble que Spring MVC répond avec XML quand il est absent – nvrs

0

je l'ai fait travailler en se débarrassant de @ResponseBody et au lieu de faire manuellement la conversion (toujours en utilisant Jackson), à savoir

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(); 

Est-ce que quelqu'un sait une autre façon? J'ai essayé de mettre en place un ContentNegotiatingViewResolver mais je ne veux pas casser d'autres contrôleurs en attribuant tous hmtl à JSON. En outre, j'ai essayé de le faire pour cette méthode que par un ViewResolver personnalisé mais quand je configurer un JSONView et utiliser BeanNameViewResolver bien que la réponse est converti correctement JSON le serveur lance une HttpRequestMethodNotSupportedException: exception, à la demande méthode « POST » pas pris en charge et ensemble statut à 404.

2

Merci! J'avais exactement le même problème et votre message a résolu mon problème.

Sur l'interface utilisateur que je utilise JQuery avec ce plugin de téléchargement de fichier: https://github.com/blueimp/jQuery-File-Upload/wiki

Voici ma méthode terminée (moins la logique biz):

@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(); 
    } 

} 
Questions connexes