2011-10-11 29 views
5

Tôi đang sử dụng Spring 3.0.6 và tôi có một bộ điều khiển duy nhất để tải tệp lên máy chủ. Tôi đang sử dụng một tập lệnh để tải lên bằng cách sử dụng XmlHttpRequest cho các trình duyệt có hỗ trợ nó trong khi phần còn lại của trình duyệt gửi biểu mẫu nhiều phần (ẩn). Tuy nhiên vấn đề đặt ra là khi một mẫu được gửi nó sẽ gửi các tiêu đề sau đây:Spring MVC, buộc phản hồi JSON theo yêu cầu đơn giản

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

Tôi hình dung rằng do tiêu đề này Controller được đánh dấu bằng @ResponseBody thư trả lời với câu trả lời được chuyển đổi sang XML thay vì JSON. Có cách nào để giải quyết vấn đề này mà không cần yêu cầu gửi biểu mẫu không?

Trả lời

8

Bạn có thể buộc JSON sử dụng @RequestMapping(produces = "application/json"). Tôi không nhớ nếu điều này có sẵn trong 3.0 nhưng nó có sẵn trong 3.1 và 3.2 cho chắc chắn.

Như những người khác đã lưu ý, Jackson cần phải ở trên đường dẫn lớp của bạn.

+0

Điều này có vẻ tốt, tuy nhiên như bạn đã nói tôi không biết nếu nó có thể áp dụng cho Spring 3.0 – nvrs

+0

trong phần bổ sung này, bạn cần reqeust sẽ có Accept header, như thế này Chấp nhận: "application/json; charset = utf-8", vì vậy mvc spring sẽ biết trình chuyển đổi nào sẽ sử dụng để xây dựng phản hồi chính xác. – lukass77

1

Nếu bạn muốn có phản hồi JSON, bạn có thể dễ dàng thực hiện điều đó bằng cách có Jackson JARs trên đường dẫn lớp của bạn. Spring sẽ tự động chọn chúng trên đó và chuyển đổi @ResponseBody thành JSON.

+1

Nhưng tôi làm, tôi đang sử dụng Jackson. Phương thức tương tự khi nó trả lời một yêu cầu có chấp nhận: header/application json gửi nó như JSON. Nhưng có vẻ như Spring MVC trả lời với XML khi nó vắng mặt – nvrs

0

tôi đã làm cho nó hoạt động bằng cách loại bỏ khỏi @ResponseBody và thay vào đó làm bằng tay việc chuyển đổi (luôn luôn sử dụng Jackson), ví dụ:

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

Có ai biết cách khác? Tôi đã cố gắng thiết lập một ContentNegotiatingViewResolver nhưng tôi không muốn phá vỡ bất kỳ bộ điều khiển khác bằng cách gán tất cả hmtl để json. Ngoài ra, tôi đã cố gắng làm điều đó cho phương pháp này chỉ thông qua chế độ xem tùy chỉnh nhưng khi tôi thiết lập chế độ xem jsonview và sử dụng BeanNameViewResolver mặc dù phản hồi được chuyển đổi thành JSON một cách chính xác, máy chủ sẽ ném một ngoại lệ HttpRequestMethodNotSupportedException:, với phương thức Yêu cầu 'POST' không được hỗ trợ và đặt trạng thái thành 404.

2

Cảm ơn bạn! Tôi đã có chính xác cùng một vấn đề và bài viết của bạn giải quyết vấn đề của tôi.

Trên UI Tôi đang sử dụng JQuery với tập tin này upload plugin: https://github.com/blueimp/jQuery-File-Upload/wiki

Dưới đây là phương pháp hoàn thành của tôi (trừ logic 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(); 
    } 

} 
Các vấn đề liên quan