Could not extract response: no suitable `HttpMessageConverter` found for response type [class wechat.xx] and content type [text/plain] 问题

这篇具有很好参考价值的文章主要介绍了Could not extract response: no suitable `HttpMessageConverter` found for response type [class wechat.xx] and content type [text/plain] 问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 问题复现

话不多说,先贴出问题代码:这里的GetUserInfoByAccessToken是我自定义的一个实体类。

GetUserInfoByAccessToken getUserInfoByAccessTokenString = restTemplate.getForObject(userInfoByAccessCodeURL, GetUserInfoByAccessToken.class);

异常信息:Could not extract response: no suitable HttpMessageConverter found for response type [class wechat.wxRes.GetUserInfoByAccessToken] and content type [text/plain],很明显这段异常的意思是在指定返回类型为GetUserInfoByAccessToken,并且服务端响应报文的content-type为text/plain的情况下找不到一个合适的HttpMessageConverter 来处理这种情况

2. 处理方法

这里举例两种处理请求

1.首先StringHttpMessageConverter这个处理器是可以处理content-type为text/plain的响应报文的。但阅读源码知道必须放回类型是String才可以使用它,所有我们需要改写下代码,将放回类型改为String。需要的时候可以利用JSON工具类将其转为你需要的类型。

GetUserInfoByAccessToken getUserInfoByAccessTokenString = restTemplate.getForObject(userInfoByAccessCodeURL, String.class);

需要注意的是使用StringHttpMessageConverter容易出现中文乱码的情况,因为它默认支持的字符集是ISO-8859-1,这种时候可以参考以下代码更改StringHttpMessageConverter的默认字符集,我这里将其改为utf-8了。

RestTemplate customRestTemplate = new RestTemplate();
List<HttpMessageConverter<?>> list = customRestTemplate.getMessageConverters();
for (HttpMessageConverter<?> httpMessageConverter : list) {
    if(httpMessageConverter instanceof StringHttpMessageConverter) {
       ((StringHttpMessageConverter) httpMessageConverter).setDefaultCharset(Charset.forName("utf-8"));
                break;
      }
 }

2.往restTemplate的转换器里再加一个支持JSON转换的转换器,比如MappingJackson2HttpMessageConverter

RestTemplate customRestTemplate = new RestTemplate();
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Arrays.asList(MediaType.TEXT_HTML,MediaType.TEXT_PLAIN));
restTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter);
GetUserInfoByAccessToken getUserInfoByAccessTokenString = restTemplate.getForObject(userInfoByAccessCodeURL, GetUserInfoByAccessToken.class);

Could not extract response: no suitable `HttpMessageConverter` found for response type [class wechat.xx] and content type [text/plain] 问题

3. 源码分析问题

3.1 关键代码extractData方法

extractData方法将接口请求拿到的响应报文拿来给HttpMessageConverter解析,这里会找到合适的解析器来解析响应报文,解析成我们指定的返回类型的数据,如果找不到或者处理出现异常就会抛出异常。

代码清单1-1 org.springframework.web.client.HttpMessageConverterExtractor#extractData
// 这里的入参是请求之后的响应体
public T extractData(ClientHttpResponse response) throws IOException {
    //创建一个名为responseWrapper的MessageBodyClientHttpResponseWrapper,用于包装响应对象response,方便操作响应数据。
	MessageBodyClientHttpResponseWrapper responseWrapper = new MessageBodyClientHttpResponseWrapper(response);
    // 检查响应是否有消息体,并且消息体不为空。如果不满足条件,则返回null。
	if (!responseWrapper.hasMessageBody() || responseWrapper.hasEmptyMessageBody()) {
		return null;
	}
    // 获取响应内容类型contentType。
	MediaType contentType = getContentType(responseWrapper);

	try {
        // 遍历已注册的HttpMessageConverter列表。
		for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
            // 对于实现了GenericHttpMessageConverter接口的转换器,检查是否可以读取responseType对应的类型,并且内容类型匹配。
			if (messageConverter instanceof GenericHttpMessageConverter) {
				GenericHttpMessageConverter<?> genericMessageConverter =
						(GenericHttpMessageConverter<?>) messageConverter;
				if (genericMessageConverter.canRead(this.responseType, null, contentType)) {
					if (logger.isDebugEnabled()) {
						ResolvableType resolvableType = ResolvableType.forType(this.responseType);
						logger.debug("Reading to [" + resolvableType + "]");
					}
					return (T) genericMessageConverter.read(this.responseType, null, responseWrapper);
				}
			}
            // 如果没有找到合适的GenericHttpMessageConverter,则检查是否指定了responseClass。
			if (this.responseClass != null) {
                // 如果指定了responseClass,则检查是否有转换器可以读取该类型,并且内容类型匹配。见相关代码`canRead`方法中的代码清单1-2
				if (messageConverter.canRead(this.responseClass, contentType)) {
					if (logger.isDebugEnabled()) {
						String className = this.responseClass.getName();
						logger.debug("Reading to [" + className + "] as \"" + contentType + "\"");
					}
                    // 如果匹配成功,使用该转换器读取响应数据,并返回结果。
					return (T) messageConverter.read((Class) this.responseClass, responseWrapper);
				}
			}
		}
	}
	catch (IOException | HttpMessageNotReadableException ex) {
		throw new RestClientException("Error while extracting response for type [" +
				this.responseType + "] and content type [" + contentType + "]", ex);
	}

	throw new UnknownContentTypeException(this.responseType, contentType,
			response.getRawStatusCode(), response.getStatusText(), response.getHeaders(),
			getResponseBody(response));
}

3.2 相关代码messageConverter.canRead(this.responseClass, contentType)方法

canRead(java.lang.Class, org.springframework.http.MediaType)方法判断当前的HttpMessageConverter是否可以读取响应报文ContentType为服务端指定的数据,并且内容和你指定的返回值类型匹配。

代码清单1-2 org.springframework.http.converter.AbstractHttpMessageConverter#canRead(java.lang.Class, org.springframework.http.MediaType)
// 判断`HttpMessageConverter`转换器是否可以读取该ContentType的数据,并且内容和你指定的返回值类型匹配
public boolean canRead(Class<?> clazz, @Nullable MediaType mediaType) {
    // supports判断HttpMessageConverter转换器是否支持你指定的返回类型,参考代码清单1-3。canRead
	return supports(clazz) && canRead(mediaType);
}

这是StringHttpMessageConverter的supports方法,可以看出他可以处理返回类型为String的数据。

代码清单1-3 org.springframework.http.converter.StringHttpMessageConverter#supports
public boolean supports(Class<?> clazz) {
	return String.class == clazz;
}

上面代码supports方法返回true会调用canRead(org.springframework.http.MediaType)方法,这段代码主要就是判断当前的HttpMessageConverter 是否可以处理content-type为服务端指定类型的响应报文,比如content-type为text/plain。

代码清单1-4 org.springframework.http.converter.AbstractHttpMessageConverter#canRead(org.springframework.http.MediaType)
protected boolean canRead(@Nullable MediaType mediaType) {
	if (mediaType == null) {
		return true;
	}
	for (MediaType supportedMediaType : getSupportedMediaTypes()) {
		if (supportedMediaType.includes(mediaType)) {
			return true;
		}
	}
	return false;
}

4.关键点截图

以下是我在调试中截取的一些图片。

这里可以看到响应体的contentType为text/plain,接下来就要找可以处理这种响应类型的HttpMessageConverter

Could not extract response: no suitable `HttpMessageConverter` found for response type [class wechat.xx] and content type [text/plain] 问题

这里可以看到已注册的HttpMessageConverter列表里面有九个元素,并且通过他们的supportedMediaTypes属性看到他们可以处理的contentType

Could not extract response: no suitable `HttpMessageConverter` found for response type [class wechat.xx] and content type [text/plain] 问题

首先判断HttpMessageConverter是否可以读取我们指定的返回类,这里我指定的是我自定义的一个返回类GetUserInfoByAccessToken.class

Could not extract response: no suitable `HttpMessageConverter` found for response type [class wechat.xx] and content type [text/plain] 问题

在这里是在判断当前HttpMessageConverter是否可以处理当前响content-type为text/plain的响应报文。

Could not extract response: no suitable `HttpMessageConverter` found for response type [class wechat.xx] and content type [text/plain] 问题文章来源地址https://www.toymoban.com/news/detail-624474.html

到了这里,关于Could not extract response: no suitable `HttpMessageConverter` found for response type [class wechat.xx] and content type [text/plain] 问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 互联网大厂技术-HTTP请求-Springboot整合Feign更优雅地实现Http服务调用 no suitable HttpMessageConverter found for response type

    目录 一、SpringBoot快速整合Feign 1.添加Pom依赖 2.启动类添加注解 3.引用Feign服务 二、为请求添加Header的3种方式 1.添加固定header 2.通过接口签名添加header 3.动态添加header 三、为请求添加超时配置 1.默认超时时间 3.超时异常 4.全局超时配置 5.为单个服务设置超时配置 四、为请求配

    2024年02月11日
    浏览(48)
  • Could not autowire. No beans of ‘DiscoveryClient‘ type found.

    一、导错了包 DiscoveryClient对应有两个包: org.springframework.cloud.client.discovery.DiscoveryClient; com.netflix.discovery.DiscoveryClient; 目前导入的包是: 改成第一个包,发现不再报红了。

    2024年02月11日
    浏览(36)
  • idea报错:Could not autowire. No beans of ‘UserService‘ type found.

    点个关注,必回关 翻译:无法自动连线。未找到“用户服务”类型的服务类。 当报错之后idea会提示错误,不过程序的编译和运行都是没有问题的(这个错误提示不会产生任何印象) 解决方案 解决方案1: Settings - Editor - Inspections - Spring - Spring Core - Code - Autowiring for Bean Class

    2024年02月11日
    浏览(39)
  • @Autowired报错Could not autowire. No beans of ‘XXX‘ type found

      IDEA中使用 @Autowired 报错 Could not autowire. No beans of \\\'XXX\\\' type found ,错误大致意思为:没有匹配到类型为XXX的bean。   个人觉得,注入 controller 的 service 虽然一般来说我们都是注入一个接口,但是该接口有实现类,并且使用 @Service 进行关联,所以注入类型应该也可以视为一

    2024年02月07日
    浏览(40)
  • idea报“Could not autowire. No beans of ‘UserMapper‘ type found. ”错解决办法

    idea具有检测功能,接口不能直接创建bean的,需要用动态代理技术来解决。 1.修改idea的配置 1.点击file,选择setting 2.搜索inspections,找到Spring 3.找到Spring子目录下的Springcore 4.在Springcore的子目录下找到code 5.把seyerity选项改成警告 2.修改代码 1,@Autowrited改为@Autowrited(required = false)

    2024年02月05日
    浏览(53)
  • 解决SpringBoot项目中的报错:Could not autowire,no beans of “XXX“ type found

    问题:找不到mapper注入的bean,如图   分析:注入mapper有两种方式:  第一种:在启动类中添加  @MapperScan        然后在mapper的类中添加  @Repository 注解 第二种方法:直接在各个mapper类中添加@Mapper注解,但是一定要注意导入正确的包,否则解决不了这个异常;  很多新手

    2024年02月08日
    浏览(44)
  • IDEA提示找不到Mapper接口:Could not autowire.No beans of ‘xxxMapper‘ type found

    我们可以看到,上面的红色警告在提示我们,找不到 xxxMaper 这个类型的 bean。 为啥呢? 因为 @Mapper 这个注解是 Mybatis 提供的,而 @Autowried 注解是 Spring 提供的,IDEA能理解 Spring 的上下文,但是却和 Mybatis 关联不上。而且我们可以根据 @Autowried 源码看到,默认情况下,@Autowri

    2024年02月08日
    浏览(37)
  • SpringBoot - 在IDEA中经常发现:Could not autowire. No beans of ‘xxx‘ type found的错误

    错误描述 在SPRINGBOOT的项目中,使用IDEA时经常会遇到Could not autowire. No beans of ‘xxxx’ type found的错误提示,但是程序的编译和运行都没有问题,这个错误提示并不影响项目的生产。 解决方案

    2024年02月15日
    浏览(43)
  • Qt创建控制台程序选择构建套件问题“No suitable kits found”

    QT 选择构建套件时出现问题: “No suitable kits found” = 没有找到合适的kits套件,在安装Qt Creator时没有安装MinGW,所以只需要进行安装即可。 3.1 选择安装目录下的“MaintenanceTool.exe”,双击计入组件安装界面。 3.2 点击“下一步” 3.3 选择“添加或移除组件”: 3.4 根据自己安装

    2024年02月11日
    浏览(33)
  • 已解决No suitable driver found for jdbc:mysql://localhost:3306/ 问题

    已解决No suitable driver found for jdbc:mysql://localhost:3306/ 问题 在学习java数据库连接池使用的时候遇到问题,无法连接到数据库,查看日志是\\\"No Suitable Driver Found For Jdbc\\\",但查看数据库连接配置没问题。 这个问题可把我愁坏了,要不问一下GPT?上。 问了一下GPT,得到的答案是这样的

    2024年02月07日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包