[英]RestTemplate::exchange() - com.fasterxml.jackson.core.JsonParseException: Unexpected character ('<' (code 60))
Getting the following exception while executing a GET against RestTemplate::exchange().对 RestTemplate::exchange() 执行 GET 时出现以下异常。 It's a pretty simple public endpoint.
这是一个非常简单的公共端点。 I have included the controller and the DTO.
我已经包含了 controller 和 DTO。 The exception notes 'content type [text/html]' - I have read in other articles that this may be related to error response in XML rather than a response JSON.
异常说明“内容类型 [text/html]” - 我在其他文章中读到这可能与 XML 中的错误响应有关,而不是与响应 JSON 有关。 I have looked a little deeper into exception with no success... again a pretty simple GET endpoint??
我对异常进行了更深入的研究,但没有成功……又是一个非常简单的 GET 端点?? Any help is appreciated.
任何帮助表示赞赏。
Public Endpoint公共端点
http://catfact.ninja/fact
Exception例外
2022-01-07 11:18:40.896 ERROR 22564 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in
context with path [] threw exception [Request processing failed; nested exception
is org.springframework.web.client.RestClientException: Error while extracting response
for type [class com.example.demo.CatDTO] and content type [text/html]; nested exception
is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected character ('<' (code 60)): expected a valid value (JSON String, Number,
Array, Object or token 'null', 'true' or 'false'); nested exception
is com.fasterxml.jackson.core.JsonParseException: Unexpected character ('<' (code 60)):
expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
at [Source: (PushbackInputStream); line: 1, column: 2]] with root cause
DTO Class DTO Class
public class CatDTO {
public String fact;
public int length;
}
Controller Class Controller Class
package com.example.demo;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.*;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@RestController
public class CatWebServiceController {
@Autowired
RestTemplate restTemplate;
String url = "http://catfact.ninja/fact";
@RequestMapping(value = "/cat")
public ResponseEntity<CatDTO> getCatFact() throws IOException {
System.out.println("Inside: CatWebServiceController::getCatFact()");
CatDTO catDTO;
String urlTemplate = UriComponentsBuilder.fromHttpUrl(url)
.encode()
.toUriString();
// Just a little test
ObjectMapper mapper = new ObjectMapper();
File f = new File("C:\\macgowan\\project\\test\\demo\\response.json");
CatDTO catDTO2 = mapper.readValue(f, CatDTO.class);
// Create the headers
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>(headers);
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);
ResponseEntity<CatDTO> r = null;
try
{
r = restTemplate.exchange(urlTemplate,
HttpMethod.GET,
entity,
CatDTO.class);
System.out.println("Inside: It worked");
}
catch (HttpClientErrorException exc)
{
String errorMessage = exc.getResponseBodyAsString();
System.out.println("Inside: HttpClientErrorException");
}
catch (Exception exc)
{
String errorMessage = exc.getMessage();
System.out.println("Inside: Exception");
}
return r;
}
}
Spring Init Spring 初始化
package com.example.demo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class DemoApplication
{
public static void main(String[] args)
{
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
}
Try https://catfact.ninja/fact instead of http://catfact.ninja/fact尝试https://catfact.ninja/fact而不是http://catfact.ninja/fact
What you are receiving is literally:你收到的字面意思是:
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.20.1</center>
</body>
</html>
so you where right that your error is related to a response in XML所以你正确地认为你的错误与 XML 中的响应有关
to quickly find out, you can intercept the response:要快速找出,您可以截取响应:
restTemplate.getInterceptors().add((httpRequest, bytes, clientHttpRequestExecution) -> {
ClientHttpResponse response=clientHttpRequestExecution.execute(httpRequest, bytes);
String text = new String(response.getBody().readAllBytes(), StandardCharsets.UTF_8);
System.out.println(text);
return response;
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.