2014-07-13 24 views
11

Tôi mới làm việc với tích hợp lò xo và làm việc trong mô-đun http hội nhập mùa xuân cho yêu cầu dự án của mình. Tôi đang gửi yêu cầu từ cổng thư đi dưới dạng ứng dụng khách http. Tôi đang cố bắt đầu yêu cầu tới máy chủ và máy chủ sẽ trả lại cho tôi tải trọng tin nhắn với các giá trị đã đặt của tôi. Tôi đang chuyển đổi đối tượng sang JSON bằng cách gửi tới máy chủ Tôi đang gửi yêu cầu đến cổng vào hiện tại ở phía máy chủ từ máy khách (HttpClientDemo) được hiển thị bên dưới. Với mục đích đó, tôi chuyển đổi đối tượng của mình thành JSON và sau đó chuyển đổi thành chuỗi JSON thành đối tượng ở phía máy khách, thực hiện một số thao tác đơn giản ở đó và gửi lại cho máy khách (HttpClientDemo) nhưng trước đó, tôi nhận được ngoại lệ liên quan đến HttpMessageConverter như sau:Không thể trích xuất phản hồi: không tìm thấy HttpMessageConverter phù hợp cho loại phản hồi

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) 

Hãy tìm mã liên quan dưới:

mã phía Chủ đầu tư: 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); 
    } 

} 

Yêu cầu của tôi gateway là như sau: RequestGateway.java

public interface RequestGateway { 


    FFSampleResponseHttp FFSampleResponsegatway(FFSampleRequestHttp request); 

} 

http-ngoài-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; 
    } 
    } 

Khi tôi chạy đoạn mã trên tôi nhận được lỗi sau:

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. 

Tôi đã sử dụng tích hợp mùa xuân cơ bản mẫu mã để tham khảo. Vui lòng cung cấp thông tin đầu vào của bạn. Tôi cũng đã thử bằng cách sử dụng trình ánh xạ đối tượng mùa xuân trong các tệp cấu hình với JSON để biến đối tượng nhưng sau đó tôi cũng nhận được các vấn đề về trình mô phỏng cho HttpMessageConverter. Hãy giúp tôi với các đầu vào/đề xuất có giá trị của bạn và cho tôi biết nếu chúng tôi có bất kỳ giới hạn nào với trình ánh xạ đối tượng mùa xuân http tích hợp.


Hi Artem, Cảm ơn câu trả lời của bạn. Tôi vẫn đang đối mặt với một số thách thức được đề cập dưới đây. Tôi đã thực hiện các thay đổi trong tệp cấu hình theo đề xuất của bạn. nhưng phải đối mặt với vấn đề khi sử dụng Jackson2JsonObjectMapper và cần thêm trợ giúp của bạn. Vui lòng tìm mô tả vấn đề bên dưới.

Tôi đã thực hiện các thay đổi trong tệp của mình và giờ đây các tệp như sau: Servlet-Config của tôi.nội dung tập tin xml như sau:

<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> 

Out bound tập tin cấu hình (file đó có trách nhiệm gửi thông điệp tới máy chủ):

<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> 

phương pháp lớp impl của tôi là như sau:

public FfSampleResponseHttp issueResponseFor(FfSampleRequestHttp request) { 

     FfSampleResponseHttp ffSampleResponse2 = new FfSampleResponseHttp(); 

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

     return ffSampleResponse2; 

    } 

Tôi có thể gọi cho vấn đề về phương thức dịch vụ của mìnhResponseĐối với mặt ở phía máy chủ từ máy khách nhưng khi xử lý thêm:

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 

Tôi đã xác minh trong khi gỡ lỗi rằng phần tải trọng trong khi phản hồi sẽ bị trống trong đối tượng json trong tham số của Jackson2JsonObjectMapper.fromJson (…) sau khi chuyển vùng qua phương thức dịch vụ của tôi thành công. Tôi không thể hiểu được tôi đang làm sai ở đâu. Vui lòng cung cấp trợ giúp/đầu vào của bạn. Một lần nữa cho tôi biết nếu tôi lại thiếu thứ gì đó trong tập tin cấu hình của mình. Cảm ơn bạn rất nhiều vì đã ủng hộ bạn.

Trả lời

4

Vì bạn quay lại máy khách chỉ Stringcontent type == 'text/plain', không có cơ hội nào cho trình chuyển đổi mặc định để xác định cách chuyển đổi đối tượng.

Cách đơn giản để sửa chữa nó:

  • loại bỏ expected-response-type từ <int-http:outbound-gateway>
  • thêm vào replyChannel1<json-to-object-transformer>

Nếu không, bạn nên viết riêng của bạn HttpMessageConverter để chuyển đổi String để các đối tượng thích hợp .

Để làm cho nó hoạt động với MappingJackson2HttpMessageConverter (một trong các trình chuyển đổi mặc định) và expected-response-type, bạn nên gửi câu trả lời của mình với content type = 'application/json'.

Nếu có nhu cầu, chỉ cần thêm <header-enricher> sau <service-activator> và trước khi gửi trả lời <int-http:inbound-gateway>.

Vì vậy, tùy thuộc vào bạn lựa chọn giải pháp nào, nhưng trạng thái hiện tại của bạn không hoạt động do không thống nhất với cấu hình mặc định.

CẬP NHẬT

OK. Vì bạn đã thay đổi máy chủ của mình để trả về đối tượng FfSampleResponseHttp làm phản hồi HTTP, không phải Chuỗi, chỉ cần thêm tiêu đề contentType = 'application/json' trước khi gửi phản hồi cho HTTP và MappingJackson2HttpMessageConverter sẽ thực hiện công cụ này cho bạn - đối tượng của bạn sẽ được chuyển thành JSON và với tiêu đề contentType chính xác.

Từ phía khách hàng, bạn nên quay lại expected-response-type="com.mycompany.MyChannel.model.FFSampleResponseHttp"MappingJackson2HttpMessageConverter sẽ thực hiện lại nội dung đó cho bạn.

Tất nhiên bạn nên xóa <json-to-object-transformer> khỏi luồng thông báo sau <int-http:outbound-gateway>.

+0

Hi Artem, tôi vẫn phải đối mặt với một số vấn đề và tôi đã thêm servlet-config.xml của tôi và http-outbound-config.xml sau khi thực hiện các thay đổi trong câu hỏi của tôi chỉ để bạn xem xét. vui lòng xác nhận các thay đổi và cho tôi biết ý kiến ​​của bạn. –

+0

Đã thêm cập nhật theo các thay đổi của bạn. –

+0

Hi Artem, Nó làm việc cho tôi :) Cảm ơn bạn rất nhiều vì đã giúp đỡ và hỗ trợ của bạn .. :) –

-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

Định dạng mã và cố gắng giải thích những gì bạn đã thay đổi để làm cho nó hoạt động. – BabyDuck

4

Như Artem Bilan nói, vấn đề này occures vì ​​MappingJackson2HttpMessageConverter hỗ trợ phản ứng với application/json chỉ loại nội dung. Nếu bạn không thể thay đổi mã máy chủ, nhưng có thể thay đổi mã khách hàng (tôi đã có trường hợp như vậy), bạn có thể thay đổi nội dung kiểu tiêu đề với đánh chặn:

restTemplate.getInterceptors().add((request, body, execution) -> { 
      ClientHttpResponse response = execution.execute(request,body); 
      response.getHeaders().setContentType(MediaType.APPLICATION_JSON); 
      return response; 
     }); 
Các vấn đề liên quan