2013-05-08 31 views
8

Tôi đang cố gắng tìm ra lý do tại sao tôi không thể nhận được yêu cầu từ cuộc gọi jQuery.ajax khi phương pháp xử lý mùa xuân @Controller bao gồm chú thích @RequestBody. Hãy xem xét những điều sau đây:Spring @MVC và chú thích @RequestBody với dữ liệu x-www-form-urlencoded?

HTML/JavaScript:

<form id="foo" action="/baz"> 
    <input name="bar"> 
</form> 

<script> 
    $(function() { 
    var $fooForm = $('#foo'); 

    $fooForm.on('submit', function(evt) { 
     evt.preventDefault(); 

     $.ajax({ 
     url: $fooForm.action, 
     data: $fooForm.serialize(), 
     dataType: 'json', 
     type: 'POST', 
     success: function(data) { console.log(data); } 
     }); 
    }); 
    }); 
</script> 

Java:

@RequestMapping(
    value = "/baz", 
    method = RequestMethod.POST, 
    consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, 
    produces = MediatType.APPLICATION_JSON_VALUE 
) 
public @ResponseBody SearchResults[] jqueryPostHandler(
    @RequestBody FormDataObject formData) 
{ 
    return this.searchService.find(formData); 
} 

trên sẽ thất bại với các @RequestBody chú thích hiện tại và trả về một lỗi 415 (không phải ngoại lệ sẽ được tạo ra). Nhưng nếu chú thích @RequestBody bị xóa (tức là chữ ký tham số chỉ là FormDataObject formData) thì phương thức sẽ được gọi và JSON sẽ được trả về JavaScript.

Tại sao lại xảy ra trường hợp này? Yêu cầu POST bao gồm dữ liệu trong phần nội dung của yêu cầu. Không nên chú thích xử lý yêu cầu như vậy?

Tôi nhận thấy rằng tôi có thể thay đổi loại nội dung được gửi bởi JavaScript thành application/json và thuộc tính consumes thành MediaType.APPLICATION_JSON_VALUE để chú thích hoạt động chính xác. Nhưng tại sao nó không hoạt động với một yêu cầu biểu mẫu bình thường?

Lưu ý: Tôi đang sử dụng Spring 3.1.4.

+0

http://matthewsalvatore.blogspot.com.br/2013 /08/spring-framework-working-with-x-www.html – Allenaz

Trả lời

7

Bạn đã thử đăng nhập vào 'org.springframework.web' để tìm hiểu lý do cho mã trạng thái trả về chưa? Nên có một ngoại lệ được nâng lên và ghi lại trước khi nó được dịch sang 415.

Ngoài ra nếu gửi dữ liệu biểu mẫu, tại sao không chỉ bỏ qua @RequestBody. Sau đó, bạn sẽ sử dụng ràng buộc dữ liệu (tức là @ModelAttribute) sẽ áp dụng các tham số yêu cầu Servlet cho các trường đối tượng. Điều này là thích hợp hơn khi sử dụng FormHttpMessageConverter.

+0

Bật ghi nhật ký cho thấy rằng với chú thích '@ RequestBody' tại chỗ nó _does_ ánh xạ tới phương thức đúng, nhưng nó ném "org.springframework.web.HttpMediaTypeNotSupportedException: Loại nội dung 'application/x-www-form-urlencoded; charset = UTF-8' không được hỗ trợ". –

+0

Từ hiểu biết hạn chế của tôi, chú thích '@ RequestBody' ngụ ý rằng dữ liệu được xử lý sẽ nằm trong phần nội dung của yêu cầu. Điều này thông báo cho trình biên dịch _and_ người đọc mã. Vì vậy, để nó làm cho mã mơ hồ. Đó là lý do tại sao tôi muốn biết tại sao điều này lại thất bại. –

6

Khi số Spring Docs of @RequestBody cho biết, nội dung yêu cầu sẽ được chuyển đổi thành đối tượng của bạn theo số HttpMessageConverter.

Có 4 HttpMessageConverters mặc định:

Để chuyển đổi dạng mã hóa url, là ajax.serialize() tạo, đó là công việc của FormHttpMessageConverter. Vì bạn có ngoại lệ HttpMediaTypeNotSupportedException, tôi đoán rằng bạn không định cấu hình FormHttpMessageConverter. Kiểm tra tập tin cấu hình mùa xuân của bạn, đây là một ví dụ:

< bean class ="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" > 
    < property name= "messageConverters" > 
     < list> 
      < ref bean= "mappingJacksonHttpMessageConverter" /> 
      < ref bean= "stringHttpMessageConverter" /> 
      <!-- Do you have this converter ? --> 
      < ref bean= "formHttpMessageConverter" /> 
     </ list> 
    </ property> 
</ bean> 
+0

Ở trên không có tác dụng đối với tôi, ngay cả khi tôi đã thêm tất cả các trình chuyển đổi. Tôi đã phải sử dụng bộ chuyển đổi tùy chỉnh tại http://stackoverflow.com/a/31083802/471213 để làm cho nó hoạt động –

+0

@ usr-local-ΕΨΗΕΛΩΝ là vấn đề của bạn giống như câu hỏi này? câu trả lời của tôi là cho câu hỏi này, và nếu câu hỏi của bạn là khác nhau, hoặc có lẽ bạn nên hỏi một câu hỏi mới để giải thích thêm chi tiết. – Qianyue

+0

Không phải cùng một vấn đề chính xác: Tôi gặp lỗi 406 khi gửi biểu mẫu và thành công khi gửi JSON. Tuy nhiên, trước khi tôi gỡ rối với mã từ Spring, tôi không hiểu rằng thực thể yêu cầu ** phải ** thực hiện một cách ngẫu nhiên 'MultiValueMap' để làm việc với' FormHttpMessageConverter'. Vì vậy, * bây giờ * Tôi bắt đầu nghĩ rằng một trong hai 'FormDataObject' của OP thực hiện giao diện đó hoặc người nào khác tôi gặp vấn đề tương tự như OP nhưng thêm rằng công cụ chuyển đổi đó không hoạt động. Và bằng cách tôi đang sử dụng Spring 4.2 –

-2

Vấn đề là khi chúng ta sử dụng application/x-www-form-urlencoded, mùa xuân không hiểu nó như là một RequestBody.Do đó, nếu chúng tôi muốn sử dụng số này, chúng tôi phải xóa chú thích @RequestBody.

Sau đó, hãy thử như sau:

@RequestMapping(
     value = "/baz", 
     method = RequestMethod.POST, 
     consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, 
     produces = MediatType.APPLICATION_JSON_VALUE 
) 
public @ResponseBody SearchResults[] jqueryPostHandler(
     FormDataObject formData) 
{ 
    return this.searchService.find(formData); 
} 

Lưu ý rằng loại bỏ các chú thích @RequestBody

câu trả lời: Http Post request with content type application/x-www-form-urlencoded not working in Spring

+1

OP đã đề cập đến điều đó. Câu hỏi của anh ta là tại sao. –

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