Curlコマンドの使用:
curl -u 591bf65f50057469f10b5fd9:0cf17f9b03d056ds0e11e48497e506a2 https://backend.tdk.com/api/devicetypes/59147fd79e93s12e61499ffe/messages
JSON応答を取得しています:
{"data":[{"device":"18SE62","time":1494516023,"data":"3235","snr":"36.72",...
応答をtxtファイルに保存し、jacksonを使用して解析します。すべて問題ありません
ObjectMapper mapper = new ObjectMapper();
File f = new File(getClass().getResource
("/result.json").getFile());
MessageList messageList = mapper.readValue(f, MessageList.class);
restTemplateを使用しても同じ結果が得られるはずですが、そうではありません
RestTemplate restTemplate = new RestTemplate();
MessageList messageList =
restTemplate.getForObject("http://592693f43c87815f9b8145e9:[email protected]/api/devicetypes/591570373c87894b4eece34d/messages", MessageList.class);
代わりにエラーが発生しました
Exception in thread "main" org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class com.tdk.domain.backend.MessageList] and content type [text/html;charset=iso-8859-1]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.Java:109)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.Java:655)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.Java:613)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.Java:287)
at com.tdk.controllers.restful.client.RestTemplateExample.main(RestTemplateExample.Java:27)
ContentTypeを設定しようとしました:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
MessageList messageList =
restTemplate.getForObject(url, entity, MessageList.class);
しかし、その後、コンパイルエラーが発生しました
The method getForObject(String, Class<T>, Object...) in the type RestTemplate is not applicable for the arguments (String, HttpEntity<String>,
Class<MessageList>)
また、Jackson Messageコンバーターを追加しようとしました
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
//Add the Jackson Message converter
messageConverters.add(new MappingJackson2HttpMessageConverter());
//Add the message converters to the restTemplate
restTemplate.setMessageConverters(messageConverters);
MessageList messageList =
restTemplate.getForObject(url, MessageList.class);
しかし、私はこのエラーを受け取りました:
Exception in thread "main" org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class com.tdk.domain.backend.MessageList] and content type [text/html;charset=iso-8859-1]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.Java:109)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.Java:655)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.Java:613)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.Java:287)
at com.tdk.controllers.restful.client.RestTemplateExample.main(RestTemplateExample.Java:51)
クラスを追加してみました
@Configuration
@EnableWebMvc
public class MvcConf extends WebMvcConfigurationSupport {
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(converter());
addDefaultHttpMessageConverters(converters);
}
@Bean
MappingJackson2HttpMessageConverter converter() {
MappingJackson2HttpMessageConverter converter
= new MappingJackson2HttpMessageConverter();
return converter;
}
}
しかし、私はエラーを得ました:
org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class com.tdk.domain.backend.MessageList] and content type [text/html;charset=iso-8859-1]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.Java:109)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.Java:655)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.Java:613)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.Java:287)
ここでの主な問題は、コンテンツタイプ[text/html; charset = iso-8859-1]サービスから受信したものですが、実際のコンテンツタイプはapplication/json; charset = iso -8859-1
これを克服するために、カスタムメッセージコンバーターを導入できます。あらゆる種類の応答に対して登録します(つまり、応答コンテンツタイプヘッダーを無視します)。ちょうどこのような
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
//Add the Jackson Message converter
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
// Note: here we are making this converter to process any kind of response,
// not only application/*json, which is the default behaviour
converter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL));
messageConverters.add(converter);
restTemplate.setMessageConverters(messageConverters);
私は非常によく似た問題を抱えていましたが、それは非常に簡単なことがわかりました。コードがすべてcompiled正しくコンパイルされていても、JSONの自動マジックコンバーターは含まれていませんでしたが、私のクライアントにはJackson依存関係が含まれていませんでした。 このRestTemplate関連のソリューションを参照してください。
要するに、pom.xmlにJackson依存関係を追加しましたが、うまくいきました。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.1</version>
</dependency>
受け入れられた答えはOPの元の問題を解決しましたが、Google検索でこの質問を見つけるほとんどの人は(統計的に言えば)まったく同じ問題を起こす可能性があります HttpMessageConverter found例外。
内部で起こることは、MappingJackson2HttpMessageConverter
がcanRead()
メソッドで発生する例外を飲み込むことです。これは、ペイロードがjsonデコードに適しているかどうかを自動検出することになっています。例外は、基本的にを通信する単純なブール値の戻り値に置き換えられます。申し訳ありませんが、このメッセージをデコードする方法がわかりません上位API(RestClient
)。他のすべてのコンバーターのcanRead()メソッドがfalseを返した後にのみ、no適切なHttpMessageConverter found例外が上位APIによってスローされ、真の問題を完全に覆い隠します。
根本的な原因を見つけていない人(あなたと私など、しかしOPは見つけられない)の場合、この問題をトラブルシューティングする方法は、onMappingJackson2HttpMessageConverter.canRead()
にデバッガブレークポイントを配置し、例外で一般的なブレークポイントを有効にすることです。続行をクリックします。次の例外は真の根本原因です。
私の特定のエラーは、Beanの1つが適切な逆シリアル化アノテーションが欠落しているインターフェースを参照したことでした。
@ Ilya Dyoshinによる上記の応答がまだ取得されない場合は、応答を文字列オブジェクトに取得してみてください。
(私の考えでは、エラーはIlyaのコードスニペットによって解決されたと考えられ、取得された応答はサーバーからの失敗(エラー)でした。)
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.add(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded");
ResponseEntity<String> st = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
ResponseObject DTO(Json)へのキャスト
Gson g = new Gson();
DTO dto = g.fromJson(st.getBody(), DTO.class);
私の場合、@ Ilya Dyoshinのソリューションは機能しませんでした。メディアタイプ「*」は許可されませんでした。 MockRestServiceServerの初期化中に、この方法でrestTemplateに新しいコンバーターを追加することにより、このエラーを修正します。
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter =
new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(
Arrays.asList(
MediaType.APPLICATION_JSON,
MediaType.APPLICATION_OCTET_STREAM));
restTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter);
mockServer = MockRestServiceServer.createServer(restTemplate);
(technicalkeedaという名前のブログでYashwant Chavanが提案したソリューションに基づく)
JNジェルボー
私の場合、ランタイムクラスパスにjackson-core、jackson-annotations、およびjackson-databind jarがないことが原因でした。予想されるような通常のClassNothFoundExceptionではなく、元の質問で言及されたエラーで文句を言いました。
GET要求を行う前に、独自のコンバーターを作成して実装する必要があります。
RestTemplate restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL));
messageConverters.add(converter);
restTemplate.setMessageConverters(messageConverters);
その他の可能な解決策:restTemplate.getForObjectの結果をプライベートクラスインスタンス(作業クラス内で定義)にマップしようとしました。それは機能しませんでしたが、オブジェクトをそれ自身のファイル内でパブリックに定義すると、正しく機能しました。