İçerik türü 'application / x-www-form-urlencoded; charset = UTF-8' @RequestBody MultiValueMap için desteklenmez


94

Spring @Controller ile x-www-form-urlencoded ile ilgili sorunun cevabına göre

Aşağıdaki @Controller yöntemini yazdım

@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");
            }
    }

aşağıdaki hatayla başarısız olan istek

{
  "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"
}

[Not: Jersey çok daha arkadaş canlısıydı, ancak buradaki pratik kısıtlamalar göz önüne alındığında artık kullanamazdı]


@RequestBody'e tüketilenler = {"application / x-www-form-urlencoded"} eklediniz mi?
— shiladitya

1
Talebi nasıl yerine getirdin? (js, jquery, curl veya ne kullanırsanız kullanın) kodunu ekleyin.
— Nikolay Rusev

Bende de aynı sorun var. Benim durumumda verileri göndermek için jquery ajax kullanıyorum ve verilerJSON.stringify({"ordersToDownload":"00417002"}
— Arashsoft

$.ajax({url:"/myurl", type:"POST", data: JSON.stringify({"someAttribute":"someData"}) })
— Kullandığım

Yanıtlar:


126

Sorun şu ki, application / x-www-form-urlencoded'i kullandığımızda , Spring bunu bir RequestBody olarak anlamıyor. Yani, eğer bunu kullanmak istiyorsak @RequestBody ek açıklamasını kaldırmalıyız .

Ardından şunları deneyin:

@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;
}

@RequestBody ek açıklamasının kaldırıldığını unutmayın

cevap : İçerik türü uygulamasıyla Http Gönderi isteği / x-www-form-urlencoded İlkbaharda çalışmıyor


Teşekkür ederim! Sorunu çözer. Şimdi merak ediyorum nasıl açıkça kaldırırız application/x-www-form-urlencoded?
— kholofelo Maloma

1
gerekli değil @kholofeloMaloma
— Douglas Ribeiro

Bunun neden herhangi bir açıklama olmadan çalıştığını merak eden biri varsa, görünen o ki Spring herhangi bir açıklamasız argümanı sanki @ModelAttribute, even though this behaviour is (sadly) not documented. And @ModelAttribute x-www-form-urlencoded
— anlıyormuş gibi ele alıyor

public ResponseEntity <?> getToken (MultiValueMap paramMap) IllegalArgumentException: bağımsız değişken türü uyuşmazlığı
— withoutOne

Bilgi için teşekkürler! Bir acemi olarak, Spring'in yükü ayrıştırıp nesneye bağlamasının bu küçük tuhaf davranışının ardında yatan nedenin ne olduğunu merak ediyorum.
— hafan96

66

Görünüşe göre artık method parametresini ile işaretleyebilirsiniz @RequestParamve bu işi sizin için yapacak.

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

18

İçerik türünü application / json olarak ayarlamak için isteğinize bir başlık ekleyin

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

bu şekilde bahar, içeriği nasıl ayrıştıracağını bilir.


Komutunuza bir Kabul başlığı da eklemeniz gerekebilir: 'curl -vk -H "Kabul Et: application / json" -H "İçerik Türü: uygulama / json"' vb.
— razvanone

1
bu ayarı HTML formuma nasıl ekleyeceğimi açıklar mısınız?
— Usame Al-Banna

8

İlkbaharda 5

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

    // import org.springframework.util.MultiValueMap;

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

Evet, haritalamaya tüketici = MediaType.APPLICATION_FORM_URLENCODED_VALUE dahil edildiğinde, daha fazla puanı hak ediyorsunuz efendim! teşekkür ederim! @RequestParam dikişleri istekten MultiValueMap'i almak için şimdi gerekli olacak
— NemanjaT

2

@RequestBodyEk açıklamanın kaldırılması sorunu çözer (Spring Boot 2'de test edilmiştir):

@RestController
public class MyController {

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

1

Bu StackOverflow cevabında bir alternatif hakkında yazdım .

Orada adım adım kodla açıklayarak yazdım. Kısa yol:

İlk olarak : bir nesne yazın

İkinci olarak : AbstractHttpMessageConverter'ı genişleten modeli eşlemek için bir dönüştürücü oluşturun

Üçüncüsü : spring'e, configureMessageConverters yöntemini geçersiz kılan bir WebMvcConfigurer.class uygulayarak bu dönüştürücüyü kullanmasını söyleyin

Dördüncü ve son: denetleyicinizin içindeki eşlemede bu uygulama ayarını kullanarak, nesnenizin önünde tüketir = MediaType.APPLICATION_FORM_URLENCODED_VALUE ve @RequestBody.

Yaylı önyükleme kullanıyorum 2.


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

Bu benim için çalışıyor

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.