2011-10-11 19 views
5

Używam Spring 3.0.6 i mam jeden kontroler do przesyłania plików na serwer. Używam skryptu do przesłania przy pomocy XmlHttpRequest dla przeglądarek, które go obsługują, podczas gdy reszta przeglądarek przesyła (ukryty) formularz wieloczęściowy. Jednak problemem jest to, że gdy formularz jest składany wysyła następujący nagłówek:Spring MVC, wymuś odpowiedź JSON w zwykłym żądaniu

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

I postać, która ze względu na ten cel kontroler, który jest oznaczony @ResponseBody odpowiedzi z odpowiedzi zostały przekształcone do formatu XML zamiast JSON. Czy istnieje sposób na obejście tego bez zhakowania żądania przesłania formularza?

Odpowiedz

8

można wymusić za pomocą JSON @RequestMapping(produces = "application/json"). Nie pamiętam, czy jest to dostępne w wersji 3.0, ale na pewno jest dostępne w wersji 3.1 i 3.2.

Jak inni zauważyli, Jackson musi być w swojej klasie.

+0

To wygląda dobrze, jednak, jak powiedziałeś, nie wiem czy to dotyczy Spring 3.0 – nvrs

+0

w dodatku do tego potrzebujesz, aby żądanie miało nagłówek Accept, tak jak to Zaakceptuj: "application/json; charset = utf-8", więc spring mvc będzie wiedział, którego konwertera użyć do zbudowania poprawnej odpowiedzi. – lukass77

1

Jeśli chcesz uzyskać odpowiedź JSON, możesz łatwo to zrobić, mając na swojej ścieżce klasę Jackson JARs. Spring automatycznie odbierze je i zamieni Twój @ResponseBody na JSON.

+1

Ale robię, używam Jackson. Ta sama metoda, gdy odpowiada na żądanie z akceptacją: application/json header wysyła go jako JSON. Wydaje się jednak, że Spring MVC odpowiada za pomocą XML, gdy jest nieobecny. – nvrs

0

Zrobiłem to działa poprzez pozbycie się @ResponseBody i zamiast robić ręcznie konwersję (zawsze przy użyciu Jackson), tj

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

Czy ktoś zna inny sposób? Próbowałem skonfigurować ContentNegotiatingViewResolver, ale nie chcę łamać żadnych innych kontrolerów, przypisując wszystkie hmtl do json. Ponadto próbowałem zrobić to dla tej metody tylko za pomocą niestandardowego parametru viewresolver, ale po skonfigurowaniu jsonview i użyciu BeanNameViewResolver, chociaż odpowiedź jest poprawnie przekonwertowana na JSON, serwer generuje wyjątek HttpRequestMethodNotSupportedException:, a metoda żądania "POST" nie jest obsługiwana i ustawiana status do 404.

2

Dziękujemy! Miałem dokładnie ten sam problem i twój post rozwiązał mój problem.

Na interfejsie używam jQuery z tej wtyczki Prześlij plik: https://github.com/blueimp/jQuery-File-Upload/wiki

Oto moja metoda zakończone (minus logika 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(); 
    } 

} 
Powiązane problemy