2015-06-18 20 views
8

Tôi đang học cách xây dựng các dịch vụ web RESTful bằng cách sử dụng Spring 4 và một điều tôi không rõ ràng là trong @RequestMapping. Tôi đã xem các ví dụ trong đó một ví dụ sử dụng headers = "Accept=application/xml" và các ví dụ khác sử dụng tiêu thụ (hoặc sản xuất) = "application/xml".Mùa xuân 4 @RequestMapping - tiêu thụ vs tiêu đề?

Ví dụ, trong lớp @RestController riêng tôi, tôi có chức năng này ...

// POST 
@RequestMapping(method = RequestMethod.POST, headers = "Accept=application/xml") 
public User create(@RequestBody User user) { 
    LOG.info("User = " + user.toString()); 
return userService.create(user); 
} 

sự khác biệt giữa việc sử dụng headers = "Accept=application/xml" so với sử dụng tiêu thụ = "application/xml"? Hoặc thậm chí sử dụng headers = "content-type=application/xml" là gì?

Ai đó có thể giải thích sự khác biệt giữa các tiêu đề và tiêu thụ/sản xuất và khi nào mỗi mục được sử dụng?

Trả lời

1

Khi javadoc của HeadersRequestCondition (mà xử lý các giá trị được cung cấp trong headers thuộc tính của một chú thích @RequestMapping) khẳng định

Expressions truyền cho constructor với những cái tên tiêu đề 'Accept' hoặc 'Content-Type' là làm ngơ. Xem ConsumesRequestConditionProducesRequestCondition cho những người đó.

Vì vậy, không sử dụng các tiêu đề đó trong headers. Sử dụng các thuộc tính producesconsumes cho AcceptContent-Type.

Để biết cách sử dụng chúng, tài liệu cung cấp ví dụ: for consumesfor produces.

+0

Tôi không nghĩ rằng nó bị bỏ qua, không có gì về nó trong tài liệu chính thức. Hơn nữa nó hoạt động. Dù sao, sử dụng sản xuất và tiêu thụ là thích hợp hơn. –

+0

@VadimKirilchuk Chúng bị bỏ qua trong 'HeadersRequestCondition'. Xem mã nguồn, [tại đây] (https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition /HeadersRequestCondition.java#L65). Tuy nhiên, những giá trị tương tự cũng được chuyển đến 'ProducesRequestCondition' và' ConsumesRequestCondition' khi xây dựng một 'RequestMappingInfo' cho' RequestMappingHandlerMapping'. Xem [tại đây] (http://stackoverflow.com/questions/34138501/java-illegalstateexception-on-http-response#34138501). –

+0

@VadimKirilchuk Ngoài ra, báo giá trong câu trả lời là từ javadoc. –

23

NGẮN ĐÁP
Trong ví dụ bạn có ở trên, sử dụng headers = "Accept=application/xml" hoặc produces = "application/xml" sẽ cả hai đáp ứng cho khách hàng theo cùng một cách ví dụ: gửi một phản ứng cho khách hàng với đại diện XML.

ĐÁP CÒN
i. Tiêu đề
Đối với dịch vụ web RESTful, ứng dụng khách (ví dụ: trình duyệt của bạn) gửi yêu cầu (ví dụ: GET, POST, v.v.) đến máy chủ và máy chủ sẽ gửi phản hồi. Đây là một giao dịch HTTP. Cả yêu cầu và đáp ứng đều có các trường tiêu đề HTTP ("tiêu đề"), xác định các tham số hoạt động của giao dịch HTTP (tôi sẽ tham khảo tiêu đề cho yêu cầu của khách hàng là "tiêu đề yêu cầu", và các tiêu đề khác với phản hồi của máy chủ " tiêu đề ").

Là một phần của yêu cầu trình duyệt của bạn gửi đến máy chủ, có tiêu đề yêu cầu khác nhau và một số ví dụ bao gồm Accept, Connection, Content-Length vv và mỗi một trong các tiêu đề có chức năng riêng của họ (xem danh sách đầy đủ các tiêu đề ở đây: https://en.wikipedia.org/wiki/List_of_HTTP_header_fields).

Sử dụng ví dụ mã của bạn, nếu một khách hàng thực hiện một yêu cầu POST, Spring sẽ kiểm tra các tiêu đề yêu cầu (s) và nếu nó tìm thấy một tiêu đề Accept với một giá trị của application/xml, nó sẽ lập bản đồ các yêu cầu đến create phương pháp mà bạn có ở trên (và trong trường hợp của bạn, máy chủ sẽ trả về một biểu diễn phản hồi XML cho máy khách).

Hãy để tôi sửa đổi các yếu tố headers trong các mã mà bạn cung cấp:

@RequestMapping(method = RequestMethod.POST, headers = "Connection=keep-alive") 
public User create(@RequestBody User user) { 
... 
} 

Thông báo các yếu tố headers bây giờ có một giá trị của Connection=keep-alive. Nếu khách hàng thực hiện yêu cầu POST, Spring sẽ kiểm tra (các) tiêu đề yêu cầu và nếu nó tìm tiêu đề Connection với giá trị keep-alive, nó sẽ ánh xạ yêu cầu của khách hàng đó đến phương thức create ở trên.

ii. Sản xuất và Tiêu thụ
Nếu bạn sử dụng produces="application/xml" cho phương pháp create, điều này có nghĩa là một yêu cầu khách hàng chỉ được ánh xạ tới các phương pháp create nếu Accept tiêu đề của khách hàng phù hợp với application/xml. Về cơ bản, đây là khách hàng nói, "Này máy chủ, tôi thích chấp nhận câu trả lời của bạn trong biểu diễn XML, vì vậy hãy gửi câu trả lời của bạn cho tôi trong XML". Có hiệu quả, các produces="application/xml" cũng là máy chủ nói, "Hey khách hàng, tôi chỉ có thể sản xuất phản ứng cho bạn trong XML đại diện, vì vậy tôi sẽ gửi cho bạn định dạng đó". Link to Spring documentation reference.

Nếu bạn sử dụng consumes="application/xml" cho phương pháp create, điều này có nghĩa là một yêu cầu khách hàng chỉ được ánh xạ tới các phương pháp create nếu Content-Type tiêu đề của khách hàng phù hợp với application/xml (header Content-Type yêu cầu mô tả các đại diện theo yêu cầu khách hàng đang đến trong). Điều này về cơ bản là máy chủ nói, "Hey khách hàng, tôi chỉ có thể tiêu thụ các yêu cầu trong biểu diễn XML, do đó, gửi định dạng đó cho tôi".

TÓM TẮT
Yếu tố headers trong @RequestMapping chú thích có thể mất tiêu đề yêu cầu khác nhau (Accept, Connection, Cache-Control vv), nhưng các yếu tố produces là chỉ quan tâm đến tiêu đề Accept yêu cầu và các yếu tố consumes là chỉ quan tâm với tiêu đề yêu cầu Content-Type.

+1

Câu trả lời này phải được đánh dấu là câu trả lời chấp nhận. bằng cách cảm ơn Alex cho câu trả lời chi tiết và thông tin. –

+0

Bất kỳ ý tưởng nào tại sao [điều này không hoạt động] (http://stackoverflow.com/questions/42044639/file-upload-wont-work)? – displayname