İç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.