JSONのRestTemplateを介したPOSTリクエスト


126

私は問題を解決する方法の例を見つけられなかったので、あなたに助けを求めたいと思います。JSONでRestTemplateオブジェクトを使用してPOSTリクエストを送信することはできません

私が得るたびに:

org.springframework.web.client.HttpClientErrorException:415 Unsupported Media Type

RestTemplateを次のように使用します。

...
restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> list = new ArrayList<HttpMessageConverter<?>>();
list.add(new MappingJacksonHttpMessageConverter());
restTemplate.setMessageConverters(list);
...
Payment payment= new Payment("Aa4bhs");
Payment res = restTemplate.postForObject("http://localhost:8080/aurest/rest/payment", payment, Payment.class);

私のせいは何ですか?


1
@troyfolger URLは無効になりました
Noremac

おかげで-このリンクはこの執筆の時点で機能しています:spring.io/guides/gs/sumption-rest
troyfolger

上記の特定のOP問題に対処するには、おそらく適切なコンテンツタイプのHTTPヘッダーが欠落しています。以下のmorganw09devからの回答を参照してください。
troyfolger

これらの問題は、主にサーバーAPI構成に関連しています。スタンドアロンクライアント(Postmanなど)を使用してサーバーAPIをテストし、同じヘッダーをリクエストに複製します。少なくとも私の場合、それはトリックをしました。
Linus

1
@Johnny B、これが回答済みの場合は回答にマークを付けてください
Vishal

回答:


161

このテクニックは私にとってうまくいきました:

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

HttpEntity<String> entity = new HttpEntity<String>(requestJson, headers);
ResponseEntity<String> response = restTemplate.put(url, entity);

これが役に立てば幸い


3
httpリクエストの結果を返す行を説明してください
gstackoverflow

私にとって、ヘッダーを指定する必要はありませんでした。単一のパラメーターを受け取るHttpEntityを使用しました。
Constantino Cronemberger、

24
メソッド.put()void
メンバーサウンド2018年

4
postForEntity(url, entity, String.class)代わりに作品を使用するput(url, entity)
Janac Meena

1
@ Kanu、requestJsonは有効なJSON文字列か何かですか?
Deva

95

RESTエンドポイントをデバッグしようとしたときに、この問題に遭遇しました。以下は、SpringのRestTemplateクラスを使用して、使用したPOSTリクエストを作成する基本的な例です。動作しているバージョンを取得するために、さまざまな場所のコードをつなぎ合わせるのにかなり長い時間がかかりました。

RestTemplate restTemplate = new RestTemplate();

String url = "endpoint url";
String requestJson = "{\"queriedQuestion\":\"Is there pain in your hand?\"}";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers);
String answer = restTemplate.postForObject(url, entity, String.class);
System.out.println(answer);

私の残りのエンドポイントがフィールド名の周りに必要な二重引用符を使用していた特定のJSONパーサーなので、requestJson文字列で二重引用符をエスケープしました。



Springはメッセージコンバーターを使用して、Restful APIとRestTemplateで行ったように、Javaオブジェクトをjsonに自動的に変換できますか?
秋の

1
メディアタイプをAPPLICATION_JSONに設定することが、問題を解決するための鍵です。
ピートT

HttpEntity <String>エンティティ= new HttpEntity <String>(requestJson、headers);を使用して問題を解決しました。この行
Ved Prakash

76

以下のように、JSONObjectsでRESTテンプレートを使用しています。

// create request body
JSONObject request = new JSONObject();
request.put("username", name);
request.put("password", password);

// set headers
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(request.toString(), headers);

// send request and parse result
ResponseEntity<String> loginResponse = restTemplate
  .exchange(urlString, HttpMethod.POST, entity, String.class);
if (loginResponse.getStatusCode() == HttpStatus.OK) {
  JSONObject userJson = new JSONObject(loginResponse.getBody());
} else if (loginResponse.getStatusCode() == HttpStatus.UNAUTHORIZED) {
  // nono... bad credentials
}

ありがとう-JSONObject toStringメソッドは私にとって有用でした。これは、JSONStringを正確に取得するのに役立ちました。
Simon

1
このための上記のコードを開発する方法:curl -vvv -X POST " localhost:8080 / SillyService_SRC / oauth /… "?
Pra_A

@MikaelLepistöサーバー側でjsonからこれらのパラメーターを取得するにはどうすればよいですか?
KJEjava48 2017

@ KJEjava48どういう意味かわかりません...これは応答のサーバー側コードです。json応答を解析する方法を考えている場合、それは使用しているフレームワークに依存します。
ミカエル・レピスト2017

@MikaelLepistöJavaで応答を受信する方法を含め、他の端でjson応答を解析する方法を意味しますか??一方の端(つまり、サーバー側)のコードのみを投稿しました。
KJEjava48 2017

13

指定されているように、ここで私はあなたが追加する必要があると思うmessageConverterために MappingJacksonHttpMessageConverter


9

Spring 3.0を使用している場合、org.springframework.web.client.HttpClientErrorException:415 Unsupported Media Type exception を回避する簡単な方法は、クラスパスにjackson jarファイルを含め、mvc:annotation-drivenconfig要素を使用することです。ここで指定されたとおり

mvc-ajaxアプリがの特別な設定なしで機能する理由を理解しようと、髪を引っ張っていましたMappingJacksonHttpMessageConverter。上記でリンクした記事をよく読んだ場合:

裏では、Spring MVCはHttpMessageConverterに委任してシリアル化を実行します。この場合、Spring MVCは、Jackson JSONプロセッサー上に構築されたMappingJacksonHttpMessageConverterを呼び出します。クラスパスにJacksonが存在する状態でmvc:annotation-driven構成要素を使用すると、この実装は自動的有効になります。


7

「415 Unsupported Media Type」エラーは、サーバーがPOSTリクエストを受け入れないことを示しています。あなたのリクエストは絶対に問題ありません、それは間違って設定されているサーバーです。

MappingJacksonHttpMessageConverterリクエストのcontent-typeヘッダーが自動的にに設定されapplication/jsonます。サーバーがそれを拒否していると思います。サーバーの設定についてはまだ何も教えていないので、アドバイスはできません。


7

私はこのようにしていて、うまくいきます。

HttpHeaders headers = createHttpHeaders(map);
public HttpHeaders createHttpHeaders(Map<String, String> map)
{   
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    for (Entry<String, String> entry : map.entrySet()) {
        headers.add(entry.getKey(),entry.getValue());
    }
    return headers;
}

//ここにヘッダーを渡します

 String requestJson = "{ // Construct your JSON here }";
logger.info("Request JSON ="+requestJson);
HttpEntity<String> entity = new HttpEntity<String>(requestJson, headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
logger.info("Result - status ("+ response.getStatusCode() + ") has body: " + response.hasBody());
logger.info("Response ="+response.getBody());

お役に立てれば


4

この問題が発生し、クライアントでSpringのRestTemplateを使用し、サーバーでSpring Webを使用しています。どちらのAPIもエラー報告が非常に貧弱で、開発が非常に困難です。

あらゆる種類の実験を何時間も試みた後、問題が、予期されたリストの代わりにPOST本体のnull参照を渡すことによって引き起こされていることがわかりました。RestTemplateはnullオブジェクトからcontent-typeを決定できないと思いますが、それについて不満はありません。正しいヘッダーを追加した後、サービスメソッドを入力する前に、Springで別のサーバー側の例外を取得し始めました。

修正は、nullの代わりにクライアントから空のリストを渡すことでした。null以外のオブジェクトにはデフォルトのcontent-typeが使用されるため、ヘッダーは必要ありません。


3

このコードは私のために働いています。

RestTemplate restTemplate = new RestTemplate();
Payment payment = new Payment("Aa4bhs");
MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();
map.add("payment", payment);
HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<MultiValueMap<String, Object>>(map, headerObject);

Payment res = restTemplate.postForObject(url, httpEntity, Payment.class);

私は非常に似たアプローチを使用していますが、うまくいきませんでした。何らかの理由で、あなたの「マップ」に相当するものがjsonに変換されていないか、アウトバウンドボディとして含まれていません。つまり、ターゲットサービスはペイロードを認識しません。
アブデル2018

2

応答を処理したくない場合

private RestTemplate restTemplate = new RestTemplate();
restTemplate.postForObject(serviceURL, request, Void.class);

プロセスへの対応が必要な場合

String result = restTemplate.postForObject(url, entity, String.class);

0

私にとって、このセットアップでエラーが発生しました:

AndroidAnnotations Spring Android RestTemplate Module そして...

GsonHttpMessageConverter

Androidアノテーションには、POSTパラメーターなしでリクエストを生成するように変換されているため、いくつかの問題があります。単純にパラメータでnew Object()解決しました。


0

なぜあなたが必要以上に一生懸命働くのですか?postForEntity単純なMapオブジェクトを入力として受け入れます。以下は、Springで特定のRESTエンドポイントのテストを作成するときにうまく機能します。私はそれがSpringでJSON POSTリクエストを行う最も簡単な方法だと思います:

@Test
public void shouldLoginSuccessfully() {
  // 'restTemplate' below has been @Autowired prior to this
  Map map = new HashMap<String, String>();
  map.put("username", "bob123");
  map.put("password", "myP@ssw0rd");
  ResponseEntity<Void> resp = restTemplate.postForEntity(
      "http://localhost:8000/login",
      map,
      Void.class);
  assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
}

0

自分でJSONをマッピングしたくない場合は、次のように行うことができます。

RestTemplate restTemplate = new RestTemplate();
restTemplate.setMessageConverters(Arrays.asList(new MappingJackson2HttpMessageConverter()));
ResponseEntity<String> result = restTemplate.postForEntity(uri, yourObject, String.class);

0

私は春のブーツで次のように試しました:

ParameterizedTypeReference<Map<String, Object>> typeRef = new ParameterizedTypeReference<Map<String, Object>>() {};
public Map<String, Object> processResponse(String urlendpoint)
{
    try{
    
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        //reqobj
        JSONObject request = new JSONObject();
        request.put("username", name);
        //Or Hashmap 
        Map<String, Object> reqbody =  new HashMap<>();
        reqbody.put("username",username);
        Gson gson = new Gson();//mvn plugin to convert map to String
        HttpEntity<String> entity = new HttpEntity<>( gson.toJson(reqbody), headers);
        ResponseEntity<Map<String, Object>> response = resttemplate.exchange(urlendpoint, HttpMethod.POST, entity, typeRef);//example of post req with json as request payload
        if(Integer.parseInt(response.getStatusCode().toString()) == HttpURLConnection.HTTP_OK)
        {
            Map<String, Object>  responsedetails = response.getBody();
            System.out.println(responsedetails);//whole json response as map object
            return responsedetails;
        }
    } catch (Exception e) {
        // TODO: handle exception
        System.err.println(e);
    }
    return null;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.