为什么int-http:outbound-gateway的JSON有效负载会给出400 Bad Request?

时间:2015-05-05 05:15:50

标签: json rest http jackson spring-integration

为什么int-http:outbound-gateway的JSON有效负载会给出400 Bad Request?

以下请求在Chrome Rest客户端上正常工作,inObjgateway中指定了3个标头,Obj的JSON值

public class Obj {
    @JsonProperty("phone")
    private String phoneNo;
    @JsonProperty("orderNumber")
    private String orderNmb;
}

应用程序上下文代码片段

<int:gateway id="inObjGateway" service-interface="com.XXX.xx.IObjGateway"
                 default-request-channel="smsHttpRequestChannel" default-reply-timeout="10000">
        <int:default-header name="content-Type" value="application/json" />
        <int:default-header name="authorization" value="someWE6JHRhcGwzc0MwZDNCcsome"/>
        <int:default-header name="accept" value="application/json" />
    </int:gateway>

    <int:payload-type-router input-channel="httpRequestChannel">
        <int:mapping type="com.xxx.xx.json.entity.Obj" channel="httpObjToJsonChannel"/>
    </int:payload-type-router>


    <int:channel id="httpRequestChannel"/>
    <int:channel id="httpOutChannel"/>
    <int:channel id="httpObjToJsonChannel"/>

    <int:object-to-json-transformer auto-startup="true" 
                                id="objectToJsonTxr" input-channel="httpObjToJsonChannel"
                                output-channel="smsHttpOutChannel"/>

    <bean id="httpRequestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
        <property name="connectTimeout" value="${connectionTimeout}"/>
        <property name="readTimeout" value="${connectionTimeout}"/>
    </bean> 

    <bean id="jackson2http" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>

    <int-http:outbound-gateway request-channel="httpOutChannel" encode-uri="false"
                               url="http://www.someurl.com/something"
                               http-method="POST" auto-startup="true" request-factory="httpRequestFactory" 
                               reply-channel="loggingChannel" message-converters="jackson2http" 
                               reply-timeout="10000"  />

显示从对象到JSON 的正确转换后的详细日志中的下一行 - :

Writing [{"phoneNo":"1617xxxxxxx","orderNmb":"2073xxxxx"}] as "application/json"

详细日志

org.springframework.beans.factory.support.DefaultListableBeanFactory : Returning cached instance of singleton bean 'integrationEvaluationContext'
    org.springframework.integration.router.PayloadTypeRouter : (inner bean)#53c8bb96 received message: GenericMessage [payload=com.xxxx.json.entity.Obj@235a8276, headers={timestamp=1430802166667, id=f3c3577d-bf44-b54d-b5e6-6b3f88a5746b, content-Type=application/json, accept=application/json, authorization=someWE6JHRhcGwzc0MwZDNCcsome}]
    org.springframework.beans.factory.support.DefaultListableBeanFactory : Returning cached instance of singleton bean 'ObjHttpObjToJsonChannel'
    org.springframework.integration.transformer.MessageTransformingHandler : org.springframework.integration.transformer.MessageTransformingHandler#0 received message: GenericMessage [payload=com.xxxx.json.entity.Obj@235a8276, headers={timestamp=1430802166667, id=f3c3577d-bf44-b54d-b5e6-6b3f88a5746b, content-Type=application/json, accept=application/json, authorization=someWE6JHRhcGwzc0MwZDNCcsome}]
    org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler : org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler#2 received message: GenericMessage [payload={"phoneNo":"16173313826","orderNmb":"2070000383","firstName":"A"}, headers={timestamp=1430802166759, id=7584cee1-8392-c71c-75f4-026d423e26c2, json__TypeId__=class com.xxxx.json.entity.Obj, content-Type=application/json, accept=application/json, authorization=someWE6JHRhcGwzc0MwZDNCcsome, contentType=application/json}]
    org.springframework.integration.http.support.DefaultHttpHeaderMapper : outboundHeaderNames=[Accept, Accept-Charset, Accept-Encoding, Accept-Language, Accept-Ranges, Authorization, Cache-Control, Connection, Content-Length, Content-Type, Cookie, Date, Expect, From, Host, If-Match, If-Modified-Since, If-None-Match, If-Range, If-Unmodified-Since, Max-Forwards, Pragma, Proxy-Authorization, Range, Referer, TE, Upgrade, User-Agent, Via, Warning]
    org.springframework.integration.http.support.DefaultHttpHeaderMapper : headerName=[timestamp] WILL NOT be mapped
    org.springframework.integration.http.support.DefaultHttpHeaderMapper : headerName=[id] WILL NOT be mapped
    org.springframework.integration.http.support.DefaultHttpHeaderMapper : headerName=[json__typeid__] WILL NOT be mapped
    org.springframework.integration.http.support.DefaultHttpHeaderMapper : headerName=[content-type] WILL be mapped, matched pattern=content-type
    org.springframework.integration.http.support.DefaultHttpHeaderMapper : setting headerName=[content-Type], value=application/json
    org.springframework.integration.http.support.DefaultHttpHeaderMapper : headerName=[accept] WILL be mapped, matched pattern=accept
    org.springframework.integration.http.support.DefaultHttpHeaderMapper : setting headerName=[accept], value=application/json
    org.springframework.integration.http.support.DefaultHttpHeaderMapper : headerName=[authorization] WILL be mapped, matched pattern=authorization
    org.springframework.integration.http.support.DefaultHttpHeaderMapper : setting headerName=[authorization], value=someWE6JHRhcGwzc0MwZDNCcsome
    org.springframework.integration.http.support.DefaultHttpHeaderMapper : headerName=[contenttype] WILL be mapped, matched pattern=contenttype
    org.springframework.integration.http.support.DefaultHttpHeaderMapper : setting headerName=[contentType], value=application/json
    org.springframework.web.client.RestTemplate : Created POST request for "http://www.someurl.com/something"
    org.springframework.web.client.RestTemplate : Writing [{"phoneNo":"1617xxxxxxx","orderNmb":"2073xxxxx"}] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@774490f3]
    org.springframework.web.client.RestTemplate : POST request for "http://www.someurl.com/something" resulted in 400 (Bad Request); invoking error handler
    org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver : Resolving exception from handler [public org.springframework.web.servlet.ModelAndView com.xxxx.page.controller.ObjController.sendObj(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,javax.servlet.http.HttpSession) throws com.xxxx.utils.exception.SomePageException]: org.springframework.web.client.HttpClientErrorException: 400 Bad Request
    org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver : Resolving exception from handler [public org.springframework.web.servlet.ModelAndView com.xxxx.page.controller.ObjController.sendObj(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,javax.servlet.http.HttpSession) throws com.xxxx.utils.exception.SomePageException]: org.springframework.web.client.HttpClientErrorException: 400 Bad Request
    org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver : Resolving exception from handler [public org.springframework.web.servlet.ModelAndView com.xxxx.page.controller.ObjController.sendObj(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,javax.servlet.http.HttpSession) throws com.xxxx.utils.exception.SomePageException]: org.springframework.web.client.HttpClientErrorException: 400 Bad Request
    org.springframework.web.servlet.handler.SimpleMappingExceptionResolver : Resolving exception from handler [public org.springframework.web.servlet.ModelAndView com.xxxx.page.controller.ObjController.sendObj(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,javax.servlet.http.HttpSession) throws com.xxxx.utils.exception.SomePageException]: org.springframework.web.client.HttpClientErrorException: 400 Bad Request
    org.springframework.web.servlet.handler.SimpleMappingExceptionResolver : Resolving to view 'error' for exception of type [org.springframework.web.client.HttpClientErrorException], based on exception mapping [java.lang.Exception]
    org.springframework.web.servlet.handler.SimpleMappingExceptionResolver : Exposing Exception as model attribute 'exception'
    org.springframework.web.servlet.DispatcherServlet : Handler execution resulted in exception - forwarding to resolved error view: ModelAndView: reference to view with name 'error'; model is {exception=org.springframework.web.client.HttpClientErrorException: 400 Bad Request}
    org.springframework.web.client.HttpClientErrorException: 400 Bad Request
        at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
        at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:588)
        at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:546)
        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:422)
        at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:99)
        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.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:277)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:239)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
        at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:95)
        at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:248)
        at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:171)
        at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:119)
        at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:105)
        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.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:277)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:239)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
        at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:95)
        at org.springframework.integration.router.AbstractMessageRouter.handleMessageInternal(AbstractMessageRouter.java:164)
        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.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:277)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:239)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
        at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:95)
        at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:133)
        at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:125)
        at org.springframework.integration.gateway.MessagingGatewaySupport.send(MessagingGatewaySupport.java:302)
        at org.springframework.integration.gateway.GatewayProxyFactoryBean.invokeGatewayMethod(GatewayProxyFactoryBean.java:417)
        at org.springframework.integration.gateway.GatewayProxyFactoryBean.doInvoke(GatewayProxyFactoryBean.java:374)
        at org.springframework.integration.gateway.GatewayProxyFactoryBean.invoke(GatewayProxyFactoryBean.java:365)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
        at com.sun.proxy.$Proxy102.sendObj(Unknown Source)
        at com.xxxx.page.controller.ObjController.sendObj(ObjController.java:59)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
        at java.lang.Thread.run(Thread.java:662)

与我观察到的Wireshark数据包跟踪差异如下所示。

Postman Rest Client的工作请求跟踪!

 No.     Time           Source                Destination           Protocol Length Info
  16733 484.996811000  10.1.XX.XXX           192.XX.XX.XXX         HTTP     1126   POST /chapi/v1/some HTTP/1.1 HTTP/1.1  (application/json)

Frame 16733: 1126 bytes on wire (9008 bits), 1126 bytes captured (9008 bits) on interface 1
Ethernet II, Src: HewlettP_2d:4e:49 (a0:2b:xx:xx:xx:49), Dst: Cisco_ff:fc:04 (00:08:xx:xx:fx:04)
Internet Protocol Version 4, Src: 10.1.XX.XXX (10.1.XX.XXX), Dst: 192.XX.XX.XXX (192.XX.XX.XXX)
Transmission Control Protocol, Src Port: 60374 (60374), Dst Port: 80 (80), Seq: 2921, Ack: 1, Len: 1072
[3 Reassembled TCP Segments (3992 bytes): #16728(1460), #16729(1460), #16733(1072)]
    [Frame: 16728, payload: 0-1459 (1460 bytes)]
    [Frame: 16729, payload: 1460-2919 (1460 bytes)]
    [Frame: 16733, payload: 2920-3991 (1072 bytes)]
    [Segment count: 3]
    [Reassembled TCP length: 3992]
    [Reassembled TCP Data: 504f5354202f6d6f62696c6553657276696365732f737470...]
Hypertext Transfer Protocol
    POST /chapi/v1/some HTTP/1.1\r\n
    Host: something.com\r\n
    Connection: keep-alive\r\n
    Content-Length: 94\r\n
    Accept: application/json\r\n
    Cache-Control: no-cache\r\n
    Origin: chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm\r\n
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36\r\n
    Authorization: someWE6JHRhcGwzc0MwZDNCcsome\r\n
    Content-Type: application/json\r\n
    Accept-Encoding: gzip, deflate\r\n
    Accept-Language: en-US,en;q=0.8\r\n
     [truncated]Cookie: _br_mzv=eyIxIjozLCIyIjox
    \r\n
    [Full request URI: http://www.something.com//chapi/v1/some ]
    [HTTP request 1/1]
    [Response in frame: 16746]
JavaScript Object Notation: application/json
    Object
        Member Key: "phone"
            String value: 1617xxxXXXX
        Member Key: "orderNumber"
            String value: 12xxXXXXX
        Member Key: "application"
            String value: orderPickup

根据上述代码配置请求不在Application中工作!

   No.     Time           Source                Destination           Protocol Length Info
      89769 2664.453624000 10.1.XX.XXX           192.XX.XX.XXX         HTTP     491    POST /chapi/v1/some HTTP/1.1  (application/json)

    Frame 89769: 491 bytes on wire (3928 bits), 491 bytes captured (3928 bits) on interface 1
    Ethernet II, Src: HewlettP_xx:xx:49 (a0:2b:xx:xx:xx:49), Dst: Cisco_ff:fc:04 (00:08:xx:xx:fx:04)
    Internet Protocol Version 4, Src: 10.1.XX.XXX (10.1.XX.XXX), Dst: 192.XX.XX.XXX (192.XX.XX.XXX)
    Transmission Control Protocol, Src Port: 60618 (60618), Dst Port: 80 (80), Seq: 1, Ack: 1, Len: 437
    Hypertext Transfer Protocol
        POST /chapi/v1/some HTTP/1.1\r\n
        Accept: application/json\r\n
        authorization: someWE6JHRhcGwzc0MwZDNCcsome\r\n
        Content-Type: application/json\r\n
        Content-Length: 91\r\n
        Host: something.com\r\n
        Connection: Keep-Alive\r\n
        User-Agent: Apache-HttpClient/4.3.6 (java 1.5)\r\n
        Accept-Encoding: gzip,deflate\r\n
        \r\n
        [Full request URI: http://www.something.com/chapi/v1/some]
        [HTTP request 1/1]
        [Response in frame: 89778]
    JavaScript Object Notation: application/json
    Line-based text data: application/json
        "{\"phoneNo\":\"1617xxxXXXX\",\"orderNmb\":\"207xxXXXX\",\"application\":\"orderPickup\"}"

任何指示赞赏!

1 个答案:

答案 0 :(得分:1)

这样的问题太笼统了;你需要提供更多细节。

这要求您使用一些基本的调试技巧。

第1步:查看服务器端日志,看看它在抱怨什么。

如果这不能产生解决方案,

第2步:比较“好”和“坏”请求的网络监视器跟踪,并找出它们之间的不同之处。如果您看到有什么不同,并且无法弄清楚如何配置网关来复制“好”请求,那么请回到这里,然后回答具体的问题。

您可以使用Wireshark或eclipse TCP / IP Monitor等获取网络跟踪。

修改

从跟踪中可以看出,您正在进行两次JSON转换。

删除object-to-json-transformer,然后让出站网关进行转换。