当前位置: 首页 > 知识库问答 >
问题:

无法提取响应:未找到适合响应类型的HttpMessageConverter

蒋鹏鹍
2023-03-14

我是新的Spring集成和工作在Spring集成超文本传输协议模块为我的项目要求。我从出站网关作为超文本传输协议客户端发送请求。我试图向服务器发起一个请求,服务器应该用我的设置值返回消息负载。我正在将对象转换为JSON,用于发送到服务器我正在从客户端(HttpClientDemo)向服务器端的入站网关发送请求。为此,我将我的对象转换成JSON,然后将JSON字符串转换为客户端的对象,在那里执行一些简单的操作,并将其发送回客户端(HttpClientDemo),但在此之前,我得到了以下与HttpMessageConzer相关的异常:

Exception in thread "main" org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class com.mycompany.MyChannel.model.FFSampleResponseHttp] and content type [text/plain;charset=UTF-8]
    at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:108)
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:784)
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:769)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:549)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:517)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:462)
    at org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler.handleRequestMessage(HttpRequestExecutingMessageHandler.java:421)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:170)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78)
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:101)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97)
    at org.springframework.integration.channel.AbstractSubscribablMyChannel.doSend(AbstractSubscribablMyChannel.java:77)
    at org.springframework.integration.channel.AbstractMessagMyChannel.send(AbstractMessagMyChannel.java:255)
    at org.springframework.integration.channel.AbstractMessagMyChannel.send(AbstractMessagMyChannel.java:223)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:114)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:44)
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:93)

请查看以下相关代码:

客户端代码:HttpClientDemo.java

public class HttpClientDemo {

    private static Logger logger = Logger.getLogger(HttpClientDemo.class);
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("/META-INF/spring/integration/http-outbound-config.xml");
RequestGateway requestGateway = context.getBean("requestGateway", RequestGateway.class);        
        FFSampleRequestHttp FFSampleRequesthttp = new FFSampleRequestHttp();
        FFSampleRequesthttp.setMyChannelID("1");
        FFSampleRequesthttp.setMyNumber("88");
        FFSampleRequesthttp.setReferenceID("9I");
        FFSampleRequesthttp.setTemplateType(1);
        FFSampleRequesthttp.setTimestamp("today");
        FFSampleResponseHttp  reply = requestGateway.FFSampleResponsegatway(FFSampleRequesthttp);
            logger.info("Replied with: " + reply);
    }

}

我的请求网关如下:RequestGateway。JAVA

public interface RequestGateway {


    FFSampleResponseHttp FFSampleResponsegatway(FFSampleRequestHttp request);

}

http-outbound-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:int="http://www.springframework.org/schema/integration"
    xmlns:int-http="http://www.springframework.org/schema/integration/http"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
        http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http.xsd">

    <int:gateway id="requestGateway" 
                 service-interface="com.mycompany.MyChannel.Common.RequestGateway"
                 default-request-channel="requestChannel"/>

    <int:channel id="requestChannel"/>
    <int:channel id="requestChannel1"/>


<!--    com.mycompany.MyChannel.model.FFSampleResponseHttp -->

    <int-http:outbound-gateway request-channel="requestChannel1" reply-channel="replyChannel1" url="http://localhost:8080/MyChannel_prj-1.0.0.BUILD-SNAPSHOT/receiveGateway"  http-method="POST"  extract-request-payload="true" expected-response-type="com.mycompany.MyChannel.model.FFSampleResponseHttp"/>

   <int:object-to-json-transformer  input-channel="requestChannel" output-channel="requestChannel1" content-type="application/json"  result-type="STRING"/>



   <bean id="FFSampleRequestHttp" class="com.mycompany.MyChannel.model.FFSampleRequestHttp"></bean>


</beans>

网状物xml

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">


<servlet>
    <servlet-name>MyChannel-http</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/servlet-config.xml</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>MyChannel-http</servlet-name>
    <url-pattern>/receiveGateway</url-pattern>
   </servlet-mapping>


    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

</web-app>

servlet配置。xml

    <int:channel id="receivMyChannel"/>

<int-http:inbound-gateway request-channel="receivMyChannel" path="/receiveGateway" supported-methods="POST"/>

    <int:service-activator input-channel="receivMyChannel">
        <bean class="com.mycompany.MyChannel.serviceImpl.FFSampleHttpImpl">
        <constructor-arg ref = "FFSampleRequestHttp"></constructor-arg>
        </bean>
        </int:service-activator>


     <bean id="FFSampleRequestHttp" class="com.mycompany.MyChannel.model.FFSampleRequestHttp"></bean>
     <bean id="FFSampleResponseHttp" class="com.mycompany.MyChannel.model.FFSampleResponseHttp"></bean>

    </beans> 



public class FFSampleHttpImpl{

    private static org.apache.log4j.Logger log = Logger
            .getLogger(FFSampleImpl.class);

    @Autowired
    FFSampleRequestHttp request;
    public FFSampleHttpImpl() {
    }

    public FFSampleHttpImpl(FFSampleRequestHttp request) {
        super();
        this.request = request;
    }





    public String issueResponseFor(String str) throws JsonParseException, JsonMappingException, IOException {

        ObjectMapper mapper = new ObjectMapper();

        FFSampleRequestHttp FFSampleRequestHttp = mapper.readValue(new String(str), FFSampleRequestHttp.class);

        FFSampleRequestHttp.setReferenceID("Hi My Number");

        String  strs = new String();

        strs = mapper.writeValueAsString(FFSampleRequestHttp);

            return strs;

        }

}

FFSampleDemestHttp.java

public class FFSampleRequestHttp {
    protected String MyNumber;  
    protected String referenceID;   
    protected String myChannelID;
    protected String timestamp;
    protected int templateType;
    public String getMyNumber() {
        return MyNumber;
    }
    public void setMyNumber(String MyNumber) {
        this.MyNumber = MyNumber;
    }
    public String getReferenceID() {
        return referenceID;
    }
    public void setReferenceID(String referenceID) {
        this.referenceID = referenceID;
    }
    public String getMyChannelID() {
        return myChannelID;
    }
    public void setMyChannelID(String myChannelID) {
        this.myChannelID = myChannelID;
    }
    public String getTimestamp() {
        return timestamp;
    }
    public void setTimestamp(String timestamp) {
        this.timestamp = timestamp;
    }
    public int getTemplateType() {
        return templateType;
    }
    public void setTemplateType(int templateType) {
        this.templateType = templateType;
    }
    }

FFSamplerResponseHttp。JAVA

public class FFSampleResponseHttp {
    protected String MyNumber;
    protected String referenceID;
    protected String myChannelID;
    protected String timestamp;
    protected int templateType;

    public String getMyNumber() {
        return MyNumber;
    }
    public void setMyNumber(String MyNumber) {
        this.MyNumber = MyNumber;
    }
    public String getReferenceID() {
        return referenceID;
    }
    public void setReferenceID(String referenceID) {
        this.referenceID = referenceID;
    }
    public String getMyChannelID() {
        return myChannelID;
    }
    public void setMyChannelID(String myChannelID) {
        this.myChannelID = myChannelID;
    }
    public String getTimestamp() {
        return timestamp;
    }
    public void setTimestamp(String timestamp) {
        this.timestamp = timestamp;
    }
    public int getTemplateType() {
        return templateType;
    }
    public void setTemplateType(int templateType) {
        this.templateType = templateType;
    }
    }

运行上述代码时,出现以下错误:

16:55:46.843 [main] DEBUG o.s.web.client.RestTemplate - Writing [{"MyNumber":"88","referenceID":"9I","myChannelID":"1","timestamp":"today","templateType":1}] as "text/plain;charset=UTF-8" using [org.springframework.http.converter.StringHttpMessageConverter@7d31a3e2]
16:55:46.988 [main] DEBUG o.s.web.client.RestTemplate - POST request for "http://localhost:8080/MyChannel_prj-1.0.0.BUILD-SNAPSHOT/receiveGateway" resulted in 200 (OK)
Exception in thread "main" org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class com.mycompany.MyChannel.model.FFSampleResponseHttp] and content type [text/plain;charset=UTF-8]
    at org.springframework.web.client.HttpMessageConverterExtractor. 

我使用了spring集成基本示例代码作为参考。请提供您的意见。我还尝试在配置文件中使用带有JSON-to-object-transformer的spring对象映射器,但是我也发现了HttpMessageConverter的类似问题。请帮助我提供您宝贵的意见/建议,并告诉我spring integration http object mapper是否有任何限制。

嗨,阿泰姆,谢谢你的回复。我仍然面临以下提到的一些挑战。我已经按照您的建议对配置文件进行了更改。但在使用Jackson2JsonObjectMapper时面临问题,需要您进一步的帮助。请查看以下问题描述。

我已经对我的文件进行了更改,现在文件如下:我的Servlet配置。xml文件内容如下:

<int:channel id="channel1" /> 
<int:channel id="channel2" /> 
<int:channel id="channel3" /> 
<int-http:inbound-gateway request-channel="channel1" supported-methods="POST" path="/receiveGateway" /> 
- <int:service-activator input-channel="channel2"> 
- <bean class="com.myCompany.myChannel.serviceImpl.FFSampleHttpImpl"> 
<constructor-arg ref="ffSampleRequestHttp" /> 
</bean> 
</int:service-activator> 

<int:json-to-object-transformer input-channel="channel1" output-channel="channel2" type="com.myCompany.myChannel.model.FFSampleRequestHttp" object-mapper="jackson2JsonObjectMapper" /> 

<bean id="jackson2JsonObjectMapper" class="org.springframework.integration.support.json.Jackson2JsonObjectMapper" /> 
<bean id="ffSampleRequestHttp" class="com.myCompany.myChannel.model.FFSampleRequestHttp" /> 
<bean id="ffSampleResponseHttp" class="com.myCompany.myChannel.model.FFSampleResponseHttp" /> 
</beans>

外部绑定文件配置(负责向服务器发送消息的文件):

<int:gateway id="requestGateway" service-interface="com.myCompany.myChannel.Common.RequestGateway" default-request-channel="requestChannel" /> 
  <int:channel id="requestChannel" /> 
  <int:channel id="requestChannel1" /> 
  <int:object-to-json-transformer input-channel="requestChannel" output-channel="requestChannel1" content-type="application/json" /> 
  <int-http:outbound-gateway request-channel="requestChannel1" reply-channel="channel4" url="http://localhost:8080/myChannel_prj-1.0.0.BUILD-SNAPSHOT/http/receiveGateway" http-method="POST" /> 
  <bean id="FFSampleRequestHttp" class="com.myCompany.myChannel.model.FFSampleRequestHttp" /> 
  <int:json-to-object-transformer input-channel="channel4" output-channel="requestChannel" type="com.myCompany.myChannel.model.FFSampleResponseHttp" object-mapper="jackson2JsonObjectMapper" /> 
  <bean id="jackson2JsonObjectMapper" class="org.springframework.integration.support.json.Jackson2JsonObjectMapper" /> 
  </beans>

我的impl类方法如下所示:

public  FfSampleResponseHttp issueResponseFor(FfSampleRequestHttp request) {

        FfSampleResponseHttp ffSampleResponse2 = new FfSampleResponseHttp();

        ffSampleResponse2.setCifNumber("Yappi I am in the method");
        log.info("issueResponseFor(FfSampleRequesthttp request)");

        return ffSampleResponse2;

    }

我可以从客户端调用我的服务方法IssuereResponsefor present in in server side,但在进一步处理时:

Caused by: java.lang.IllegalArgumentException: 'json' argument must be an instance of: [class java.lang.String, class [B, class java.io.File, class java.net.URL, class java.io.InputStream, class java.io.Reader]
       at org.springframework.integration.support.json.Jackson2JsonObjectMapper.fromJson(Jackson2JsonObjectMapper.java:93)
       at org.springframework.integration.support.json.Jackson2JsonObjectMapper.fromJson(Jackson2JsonObjectMapper.java:44)
       at org.springframework.integration.support.json.AbstractJacksonJsonObjectMapper.fromJson(AbstractJacksonJsonObjectMapper.java:55)
       at org.springframework.integration.json.JsonToObjectTransformer.doTransform(JsonToObjectTransformer.java:78)
       at org.springframework.integration.transformer.AbstractTransformer.transform(AbstractTransformer.java:33)
       ... 54 more

我在调试时验证了响应时的有效负载主体在Jackson2JsonObjectMapper参数中的json对象中为空。在通过我的服务方法成功漫游后使用fromJson(…)。我不明白我在哪里犯了错误。请提供您的帮助/意见。如果我的配置文件中再次丢失某些内容,请再次通知我。非常感谢您的支持。

共有3个答案

舒博雅
2023-03-14

这里有一个简单的解决方案

尝试添加此依赖项

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.8.3</version>
</dependency>
段干麒
2023-03-14

由于您只返回客户机String及其内容类型=='text/plain',因此默认转换器无法确定如何将String响应转换为FFSampleResponseHttp对象。

解决此问题的简单方法是:

否则,您应该编写自己的HttpMessageConverter,将字符串转换为适当的对象。

要使它与MappingJackson2HttpMessageConzer(默认转换器之一)和您的预期响应类型一起工作,您应该使用Content type='Application/json'发送回复。

如果需要,只需添加

所以,选择哪种解决方案取决于您,但您的当前状态不起作用,因为与默认配置不一致。

更新

好啊由于您将服务器更改为将FfSampleResponseHttp对象作为HTTP响应而不是字符串返回,在发送HTTP响应之前,只需添加contentType='application/json'标题,而MappingJackson2HttpMessageConverter将为您完成任务-您的对象将被转换为json,并具有正确的contentType标题。

从客户端,您应该回到预期响应类型="com.mycompany.MyChannel.model.FFSampleResseHttp"MappingJackson2HttpMessageConzer应该再次为您做这些事情。

当然你应该删除

拓拔耀
2023-03-14

正如Artem Bilan所说,出现这个问题是因为MappingJackson2HttpMessageConverter只支持应用程序/json内容类型的响应。如果您不能更改服务器代码,但可以更改客户端代码(我遇到过这种情况),则可以使用拦截器更改内容类型标头:

restTemplate.getInterceptors().add((request, body, execution) -> {
            ClientHttpResponse response = execution.execute(request,body);
            response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
            return response;
        });
 类似资料:
  • 我正在尝试使用spring for Android从REST服务中检索一些数据。但是我遇到了问题。我也在使用Robospice——因此有一种类似这样的方法: 不幸的是,这不起作用。我将引发以下异常: 现在,基于我的谷歌搜索,我觉得我需要添加一个消息转换器。我只是不确定我需要哪个消息转换器,或者在哪里添加它?

  • 我有以下几点建议: 当我对它执行cucumber测试时,我得到以下异常: 我有一些其他的测试和其他具有相同注释的POJO,它们工作起来没有任何问题。我真的一点也不知道出了什么问题。 感谢任何建议!

  • 我试图让一个Spring CloudNetflixFaignes客户端通过HTTP获取一点JSON并将其转换为对象。我一直得到这个错误,而不是: 组织。springframework。网状物客户RestClientException:无法提取响应:未找到响应类型[class io.urig.checkout.Book]和内容类型[application/json;charset=UTF-8]的合适

  • 我正在写一个Springmvc应用程序(Spring新手),它必须调用Rest服务。我有其余的服务部署在我的VM(weblogic 10.3.6在Linux)和我写的应用程序是在我的本地笔记本电脑weblogic(10.3.6在Windows 8.1)。 当我尝试调用rest服务时,restservice应用程序的请求正常,但响应失败,并显示以下消息 我正在初始化控制器中的其余客户端 在实际的客户

  • 当通过Rest Api发布请求时,我抛出 内容类型:应用程序/json 当我尝试编写代码时,我使用以下代码 org.springframework.web.client.RestClientException:无法提取响应:没有找到合适的HttpMessageConverter响应类型[... FileUpload响应DTO]和内容类型[text/html]给出一个错误。如何转换?

  • 使用curl命令: 我收到一个JSON响应: 我把响应保存在一个txt文件里然后用jackson解析一切正常 我假设我应该使用RestTemplate得到相同的结果,但事实并非如此 我得到了一个错误 我尝试设置contentType: 但后来我发现了一个编译错误 我还尝试在Jackson消息转换器中添加一个 但是后来我得到了这个错误: 我还尝试添加了这个类 但是我得到了错误: