Loại nội dung 'application / x-www-form-urlencoded; charset = UTF-8' không được hỗ trợ cho @RequestBody MultiValueMap


94

Dựa trên câu trả lời cho vấn đề với x-www-form-urlencoded với Spring @Controller

Tôi đã viết phương thức @Controller bên dưới

@RequestMapping(value = "/{email}/authenticate", method = RequestMethod.POST
            , produces = {"application/json", "application/xml"}
            ,  consumes = {"application/x-www-form-urlencoded"}
    )
     public
        @ResponseBody
        Representation authenticate(@PathVariable("email") String anEmailAddress,
                                    @RequestBody MultiValueMap paramMap)
                throws Exception {


            if(paramMap == null || paramMap.get("password") == null) {
                throw new IllegalArgumentException("Password not provided");
            }
    }

yêu cầu không thành công với lỗi dưới đây

{
  "timestamp": 1447911866786,
  "status": 415,
  "error": "Unsupported Media Type",
  "exception": "org.springframework.web.HttpMediaTypeNotSupportedException",
  "message": "Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported",
  "path": "/users/usermail%40gmail.com/authenticate"
}

[Tái bút: Jersey thân thiện hơn nhiều, nhưng không thể sử dụng nó bây giờ do những hạn chế thực tế ở đây]


Bạn đã thêm tiêu thụ = {"application / x-www-form-urlencoded"} trong @RequestBody không?
shiladitya

1
Bạn đã thực hiện yêu cầu như thế nào? thêm mã của (js, jquery, curl hoặc bất cứ thứ gì bạn sử dụng).
Nikolay Rusev

Tôi có cùng một vấn đề. Trong trường hợp của tôi, tôi sử dụng jquery ajax để đăng dữ liệu và dữ liệu làJSON.stringify({"ordersToDownload":"00417002"}
Arashsoft 23/12/15

Đây là mã tôi sử dụng:$.ajax({url:"/myurl", type:"POST", data: JSON.stringify({"someAttribute":"someData"}) })
Arashsoft

Kiểm tra câu trả lời của tôi ra nhập mô tả liên kết ở đây
Eshiett Oto-obong

Câu trả lời:


126

Vấn đề là khi chúng ta sử dụng application / x-www-form-urlencoded , Spring không hiểu nó là RequestBody. Vì vậy, nếu chúng ta muốn sử dụng nó, chúng ta phải loại bỏ chú thích @RequestBody .

Sau đó, hãy thử những cách sau:

@RequestMapping(value = "/{email}/authenticate", method = RequestMethod.POST,
        consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, 
        produces = {MediaType.APPLICATION_ATOM_XML_VALUE, MediaType.APPLICATION_JSON_VALUE})
public @ResponseBody  Representation authenticate(@PathVariable("email") String anEmailAddress, MultiValueMap paramMap) throws Exception {
   if(paramMap == null && paramMap.get("password") == null) {
        throw new IllegalArgumentException("Password not provided");
    }
    return null;
}

Lưu ý rằng đã xóa chú thích @RequestBody

answer : Http Đăng yêu cầu với ứng dụng loại nội dung / x-www-form-urlencoded không hoạt động trong Spring


Cảm ơn bạn! Giải quyết vấn đề. Bây giờ tôi tự hỏi làm thế nào để chúng tôi loại bỏ rõ ràng application/x-www-form-urlencoded?
kholofelo Maloma

1
nó không phải là cần thiết @kholofeloMaloma
Douglas Ribeiro

Nếu có ai thắc mắc tại sao điều này hoạt động mà không có bất kỳ chú thích nào, thì có vẻ như Spring xử lý mọi đối số không có chú thích như thể họ có @ModelAttribute, even though this behaviour is (sadly) not documented. And @ModelAttribute hiểu x-www-form-urlencoded
cranphin

public ResponseEntity <?> getToken (MultiValueMap paramMap) IllegalArgumentException: loại đối số không khớp
cóOne

Cảm ơn bạn về thông tin! Là một người mới, tôi đang tự hỏi lý do đằng sau hành vi kỳ lạ nhỏ này để Spring phân tích cú pháp tải trọng và liên kết nó với đối tượng là gì?
hafan96

66

Có vẻ như bây giờ bạn chỉ có thể đánh dấu tham số phương thức bằng @RequestParamvà nó sẽ thực hiện công việc cho bạn.

@PostMapping( "some/request/path" )
public void someControllerMethod( @RequestParam Map<String, String> body ) {
  //work with Map
}

18

Thêm tiêu đề vào yêu cầu của bạn để đặt loại nội dung cho ứng dụng / json

curl -H 'Content-Type: application/json' -s -XPOST http://your.domain.com/ -d YOUR_JSON_BODY

theo cách này, mùa xuân biết cách phân tích cú pháp nội dung.


Bạn cũng có thể cần thêm tiêu đề Chấp nhận vào lệnh của mình: 'curl -vk -H "Chấp nhận: ứng dụng / json" -H "Nội dung-Loại: ứng dụng / json"', v.v.
razvanone

1
bạn có thể giải thích cách thêm cài đặt này vào biểu mẫu HTML của tôi không?
Osama Al-Banna

8

Vào mùa xuân 5

@PostMapping( "some/request/path" )
public void someControllerMethod( @RequestParam MultiValueMap body ) {

    // import org.springframework.util.MultiValueMap;

    String datax = (String) body .getFirst("datax");
}

Vâng, với việc bao gồm người tiêu dùng = MediaType.APPLICATION_FORM_URLENCODED_VALUE trong ánh xạ, bạn xứng đáng nhận được nhiều điểm hơn thưa ông! cảm ơn bạn! Vỉa @RequestParam được yêu cầu bây giờ cho chọn lên MultiValueMap từ yêu cầu
NemanjaT

2

Chỉ cần xóa @RequestBodychú thích sẽ giải quyết được vấn đề (được thử nghiệm trên Spring Boot 2):

@RestController
public class MyController {

    @PostMapping
    public void method(@Valid RequestDto dto) {
       // method body ...
    }
}

1

Tôi đã viết về một giải pháp thay thế trong câu trả lời StackOverflow này .

Ở đó tôi đã viết từng bước, giải thích bằng mã. Con đường ngắn:

Đầu tiên : viết một đối tượng

Thứ hai : tạo một bộ chuyển đổi để ánh xạ mô hình mở rộng AbstractHttpMessageConverter

Thứ ba : yêu cầu mùa xuân sử dụng bộ chuyển đổi này triển khai lớp WebMvcConfigurer. ghi đè phương thức configMessageConverters

Thứ tư và cuối cùng: sử dụng cài đặt triển khai này trong ánh xạ bên trong bộ điều khiển của bạn, tiêu thụ = MediaType.APPLICATION_FORM_URLENCODED_VALUE và @RequestBody ở phía trước đối tượng của bạn.

Tôi đang sử dụng khởi động lò xo 2.


0
@PostMapping(path = "/my/endpoint", consumes = { MediaType.APPLICATION_FORM_URLENCODED_VALUE })
public ResponseEntity<Void> handleBrowserSubmissions(MyDTO dto) throws Exception {
    ...
}

Cách đó phù hợp với tôi

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.