2014-07-13 30 views
11

我是新的Spring集成,并在我的项目需求的春天集成http模块中工作。我正在将来自出站网关的请求作为http客户端发送。 我试图发起一个请求到服务器和服务器应该返回我的消息有效载荷与我的设置值。我正在将对象转换为使用发送到服务器的JSON 我正在向客户端(HttpClientDemo)发送到服务器端的入站网关的请求,如下所示。为此,我将我的对象转换为JSON,然后转换为JSON字符串到客户端的对象,在那里执行一些简单的操作并将其发送回客户端(HttpClientDemo),但在此之前,我收到了异常HttpMessageConverter如下:无法提取响应:找不到适合的响应类型的HttpMessageConverter

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的出站的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> 

Web.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的config.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; 

     } 

} 

FFSampleRequestHttp.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; 
    } 
    } 

FFSampleResponseHttp.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 [[email protected]31a3e2] 
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. 

我已经使用弹簧一体化基本示例代码以供参考。 请提供您的意见。我也尝试通过使用JSON的配置文件中的spring对象映射器来对象转换,但同时我也遇到了HttpMessageConverter的模拟器问题。 请帮助我的宝贵意见/建议,并让我知道,如果我们有任何限制春天集成HTTP对象映射器。


嗨Artem, 感谢您的回复。我仍然面临着下面提到的一些挑战。根据您的建议,我已在配置文件中进行了更改。但在使用Jackson2JsonObjectMapper时遇到问题,需要您的进一步帮助。请找到下面的问题描述。

我已经对我的文件进行了更改,现在的文件如下所示: My Servlet-Config。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; 

    } 

我可以调用我的服务方法issueResponse从客户端出现在服务器端,但是当这个进一步处理时:

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 

我已经验证了在调试时,在响应的有效载荷体在通过我的服务方法漫游成功后,json对象中的Jackson2JsonObjectMapper.fromJson(...)的参数变为空白。我无法理解我在哪里犯这个错误。请提供您的帮助/输入。 再次让我知道如果我再次失去了我的配置文件中的东西。非常感谢您的支持。

回答

4

既然你返回到客户端只是String及其content type == 'text/plain',就没有任何机会了默认转换器,以确定如何转换String应对FFSampleResponseHttp对象。

简单的方法来解决它:

  • <int-http:outbound-gateway>
  • 删除expected-response-type添加到replyChannel1<json-to-object-transformer>

否则,你应该写自己的HttpMessageConverter的字符串转换为相应的对象。

要使其与MappingJackson2HttpMessageConverter(默认转换器之一)和expected-response-type一起使用,您应该发送您的回复content type = 'application/json'

如果有需要,只需在您的<service-activator>之后以及在发送回复给<int-http:inbound-gateway>之前添加<header-enricher>即可。

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

UPDATE

确定。由于您将服务器更改为返回FfSampleResponseHttp对象作为HTTP响应,而不是String,只需在发送HTTP响应之前添加contentType = 'application/json'标头,然后MappingJackson2HttpMessageConverter将为您执行这些操作 - 您的对象将被转换为JSON并带有正确的contentType标头。

从客户端你应该回到expected-response-type="com.mycompany.MyChannel.model.FFSampleResponseHttp"MappingJackson2HttpMessageConverter应该再次为你做的东西。

当然,您应该从<int-http:outbound-gateway>之后删除<json-to-object-transformer>消息流。

+0

阿尔乔姆嗨,我仍然面临着一些问题,我已经加入我的servlet-config.xml和http-outbound-config.xml在对我的问题进行更改之后,仅供您审核。善意地检验变化并让我知道你的意见。 –

+0

根据您的更改添加更新。 –

+0

嗨Artem,它为我工作:)非常感谢你的帮助和支持.. :) –

-1
public class Application { 

    private static List<HttpMessageConverter<?>> getMessageConverters() { 
     List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>(); 
     converters.add(new MappingJacksonHttpMessageConverter()); 
     return converters; 
    } 

    public static void main(String[] args) { 
     RestTemplate restTemplate = new RestTemplate(); 

     restTemplate.setMessageConverters(getMessageConverters()); 
     HttpHeaders headers = new HttpHeaders(); 
     headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); 
     HttpEntity<String> entity = new HttpEntity<String>(headers); 
     //Page page = restTemplate.getForObject("http://graph.facebook.com/pivotalsoftware", Page.class); 

     ResponseEntity<Page> response = 
        restTemplate.exchange("http://graph.facebook.com/skbh86", HttpMethod.GET, entity, Page.class, "1"); 
     Page page = response.getBody(); 
     System.out.println("Name: " + page.getId()); 
     System.out.println("About: " + page.getFirst_name()); 
     System.out.println("Phone: " + page.getLast_name()); 
     System.out.println("Website: " + page.getMiddle_name()); 
     System.out.println("Website: " + page.getName()); 
    } 
} 
+0

格式化代码,并尝试解释你已经改变,使其工作。 – BabyDuck

4

正如阿尔乔姆比兰说,这个问题occures因为MappingJackson2HttpMessageConverter支持响应与应用/ JSON仅限内容类型。如果你不能改变服务器代码,但可以改变客户端代码(我有这样的情况),您可以更改Content-Type头与拦截器:

restTemplate.getInterceptors().add((request, body, execution) -> { 
      ClientHttpResponse response = execution.execute(request,body); 
      response.getHeaders().setContentType(MediaType.APPLICATION_JSON); 
      return response; 
     }); 
相关问题