コンテンツタイプ 'application / x-www-form-urlencoded; charset = UTF-8'は@RequestBodyMultiValueMapではサポートされていません


100

Spring @ Controllerでx-www-form-urlencodedの問題に対する回答に基づく

私は以下の@Controllerメソッドを書きました

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

以下のエラーで失敗するリクエスト

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

[追記:ジャージーははるかに友好的でしたが、ここでの実際的な制限のため、現在は使用できませんでした]


@RequestBodyにconsumes = {"application / x-www-form-urlencoded"}を追加しましたか?
shiladitya 2015年

1
どのようにリクエストを実行しましたか?(js、jquery、curl、または使用するものは何でも)のコードを追加します。
ニコライルセフ2015年

私は同じ問題を抱えています。私の場合、jquery ajaxを使用してデータを投稿し、データはJSON.stringify({"ordersToDownload":"00417002"}
Arashsoft 2015

これは私が使用するコードです:$.ajax({url:"/myurl", type:"POST", data: JSON.stringify({"someAttribute":"someData"}) })
Arashsoft 2015

回答:


130

問題は、application / x-www-form-urlencodedを使用すると、SpringがそれをRequestBodyとして理解しないことです。したがって、これを使用する場合は、@ RequestBodyアノテーションを削除する必要があります。

次に、次のことを試してください。

@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を削除したことに注意してください

回答コンテンツタイプapplication / x-www-form-urlencodedを使用したHttpPostリクエストがSpringで機能しない


ありがとうございました!問題を解決します。どうすれば明示的に削除するの application/x-www-form-urlencodedだろうか?
kholofelo Maloma 2017年

1
必要ありません@ kholofeloMaloma–
Douglas Ribeiro

1
なぜこれが注釈なしで機能するのか疑問に思った場合、Springは注釈なしの引数を@ModelAttribute, even though this behaviour is (sadly) not documented. And @ModelAttributeがx-www-form-urlencodedを理解しているかのように処理しているようです
cranphin 2010

public ResponseEntity <?> getToken(MultiValueMap paramMap)IllegalArgumentException:引数タイプの不一致
withoutOne 2010

情報をありがとう!初心者として、Springがペイロードを解析してオブジェクトにバインドするこの少し奇妙な動作の背後にある理由は何ですか?
hafan 9620

66

これで、メソッドパラメータにマークを付けるだけで@RequestParam、自動的に機能するようになりました。

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

19

リクエストにヘッダーを追加して、コンテンツタイプをapplication / jsonに設定します

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

このようにして、春はコンテンツを解析する方法を知っています。


コマンドにAcceptヘッダーを追加する必要がある場合もあります: 'curl -vk -H "Accept:application / json" -H "Content-Type:application / json"'など
razvanone 2017年

1
この設定をHTMLフォームに追加する方法を説明していただけますか?
-Banna18年

9

春5に

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

    // import org.springframework.util.MultiValueMap;

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

ええ、マッピングにconsumer = MediaType.APPLICATION_FORM_URLENCODED_VALUEを含めると、より多くのポイントに値します。ありがとうございました!@RequestParamシームはリクエストからMultiValueMapを拾うために今必要とする
NemanjaT

3

@RequestBody注釈を削除するだけで問題が解決します(Spring Boot 2でテスト済み)。

@RestController
public class MyController {

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

2

私はこのStackOverflowの回答で代替案について書きました。

そこで私はコードで説明しながら、段階的に書きました。簡単な方法:

最初:オブジェクトを書く

2番目:AbstractHttpMessageConverterを拡張するモデルをマッピングするためのコンバーターを作成します

3番目:configureMessageConvertersメソッドをオーバーライドするWebMvcConfigurer.classを実装するこのコンバーターを使用するように春に伝えます

4番目で最後:コントローラー内のマッピングでこの実装設定を使用すると、オブジェクトの前に消費= MediaType.APPLICATION_FORM_URLENCODED_VALUEと@RequestBodyが表示されます。

スプリングブーツ2を使用しています。


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

そのように私のために働く


0

スプリングのコンバーターでサポートをオンにしてみることができます

@EnableWebMvc
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        // add converter suport Content-Type: 'application/x-www-form-urlencoded'
        converters.stream()
                .filter(AllEncompassingFormHttpMessageConverter.class::isInstance)
                .map(AllEncompassingFormHttpMessageConverter.class::cast)
                .findFirst()
                .ifPresent(converter -> converter.addSupportedMediaTypes(MediaType.APPLICATION_FORM_URLENCODED_VALUE));
    }

}


0

@RequestBody MultiValueMap paramMap

ここで@RequestBodyアノテーションを削除します

@RequestMapping(value = "/signin",method = RequestMethod.POST)
public String createAccount(@RequestBody LogingData user){
    logingService.save(user);
    return "login";
}




@RequestMapping(value = "/signin",method = RequestMethod.POST)
public String createAccount( LogingData user){
    logingService.save(user);
    return "login";
} 

そのように


このコードは問題を解決する方法と理由の説明含めて質問を解決するかもしれませんが、投稿の品質を向上させるのに本当に役立ち、おそらくより多くの賛成票をもたらすでしょう。あなたは今尋ねている人だけでなく、将来読者のために質問に答えていることを忘れないでください。回答を編集して説明を追加し、適用される制限と前提条件を示してください。
Yunnosch
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.