java之SpringBoot消费REST源,HttpMessageConverter报错
我是网络编程的初学者。我很感兴趣,因为有很多视频游戏 API 可以作为 URL 使用。
我遵循了本指南并使其与 springboot 和 maven 一起工作,( https://spring.io/guides/gs/consuming-rest/ )
现在我正在尝试换掉他们的 URL 并添加一个来自视频游戏的 URL ( http://services.runescape.com/m=itemdb_rs/api/catalogue/detail.json?item=21787 )
以下代码会产生以下错误:
@SpringBootApplication
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String args[]) {
SpringApplication.run(Application.class);
}
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
builder.additionalMessageConverters(new FakeConverter());
return builder.build();
}
@Bean
public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
return args -> {
Quote quote = restTemplate.getForObject(
"http://services.runescape.com/m=itemdb_rs/api/catalogue/detail.json?item=21787", Quote.class);
//"http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
log.info(quote.toString());
};
}
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:801) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:782) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:769) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1185) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1174) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at hello.Application.main(Application.java:25) [classes/:na]
Caused by: org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class hello.Quote] and content type [text/html;charset=ISO-8859-1]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:109) ~[spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:622) ~[spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:580) ~[spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:287) ~[spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at hello.Application.lambda$0(Application.java:37) [classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:798) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
... 6 common frames omitted
听起来 Spring RestTemplate 不支持 URL 链接“[text/html;charset=ISO-8859-1]”返回的格式。这让我觉得很奇怪,因为该字符集是 Java 字符集类中的默认值,并且转到 URL,文本看起来像普通文本。
我尝试手动添加 StringHttpMessageConverter,但没有成功。
我想也许代码无法识别它所说的“text/html”部分,所以我制作了一个包装 StringHttpMessageConverter 的“FakeConverter”,详情如下:
public class FakeConverter implements HttpMessageConverter{
private StringHttpMessageConverter converter;
ArrayList<MediaType> list = new ArrayList();
public FakeConverter() {
converter = new StringHttpMessageConverter(Charset.forName("ISO-8859-1"));
}
@Override
public boolean canRead(Class arg0, MediaType arg1) {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean canWrite(Class arg0, MediaType arg1) {
// TODO Auto-generated method stub
return true;
}
@Override
public List getSupportedMediaTypes() {
// TODO Auto-generated method stub
list.add(new MediaType("*", "text/html", Charset.forName("ISO-8859-1")));
//list.add(new MediaType("text/html", "*", Charset.forName("ISO-8859-1")));
//list.add(new MediaType("*", "*", Charset.forName("ISO-8859-1")));
return list;
}
@Override
public Object read(Class arg0, HttpInputMessage arg1) throws IOException, HttpMessageNotReadableException {
// TODO Auto-generated method stub
return converter.read(arg0, arg1);
}
@Override
public void write(Object arg0, MediaType arg1, HttpOutputMessage arg2)
throws IOException, HttpMessageNotWritableException {
// TODO Auto-generated method stub
converter.write((String)arg0, arg1, arg2);
}
}
我让 canRead/canWrite 始终为 true 以尝试强制它读取 URL,我尝试了所有这些不同的 MediaTypes 以查看是否可以让程序支持我的 URL。我在这里的另一篇文章中读到“*”在 MediaType 类中用作通配符,所以我很惊讶地看到双通配符尝试失败。
现在我迷路了,我认为阅读链接会更容易。
请提供您的任何见解,并提出您需要的任何澄清问题以提供更好的答案。
谢谢
请您参考如下方法:
从 Spring 的角度来看,注册到 RestTemplate 的 HttpMessageConverter 实例都不能将 text/html 内容转换为 Quote 对象。感兴趣的方法是 HttpMessageConverter#canRead(Class, MediaType) .以上所有的实现都返回false,包括GsonHttpMessageConverter、MappingJackson2MessageConverter等。
由于没有 HttpMessageConverter 可以读取您的 HTTP 响应,因此处理失败并出现异常。
如果可以修改服务器响应,修改为设置Content-type为application/json
如果您不能修改服务器响应,则需要编写并注册您自己的 HttpMessageConverter(它可以扩展 Spring 类,请参阅 AbstractGenericHttpMessageConverter 及其子类)来读取和转换文本/html。
或者,您可以尝试向 GsonHttpMessageConverter 添加对其他媒体类型的支持,
public class GsonHttpMessageConverterDemo extends GsonHttpMessageConverter {
public GsonHttpMessageConverterDemo () {
List<MediaType> types = Arrays.asList(
new MediaType("text", "html", DEFAULT_CHARSET),
new MediaType("application", "json", DEFAULT_CHARSET),
new MediaType("application", "*+json", DEFAULT_CHARSET)
);
super.setSupportedMediaTypes(types);
}
}
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。