In a Spring Boot app, using Spring Cloud OpenFeign, I'm about to read an endpoint for a Talend server but just noticed this isn't valid JSON (missing double quotes around the word transactions):
{
transactions: [
"some-uuid",
"another-one-uuid",
"and-so-on-uuid"
]
}
My model class:
#Data
#SuperBuilder
#NoArgsConstructor
#JsonInclude(JsonInclude.Include.ALWAYS)
public class Transactions {
private List<String> transactions;
}
My service/client class:
#Service
#FeignClient(value = "nativeTalend", url = "http://talend-server:8180/talendmdm/services/rest/")
public interface TalendNativeAPI {
#GetMapping(path = "transactions", produces = MediaType.APPLICATION_JSON_VALUE)
Transactions transactions();
}
Note: it needs the "produces" in the #GetMapping annotation because otherwise the server answers with a 500 HTTP error...
Here is the OpenFeign log:
[TalendNativeAPI#transactions] ---> GET http://talend-server:8180/talendmdm/services/rest/transactions HTTP/1.1
[TalendNativeAPI#transactions] Accept: application/json
[TalendNativeAPI#transactions] Authorization: Basic ==xxx==xxx==xxx==
[TalendNativeAPI#transactions] ---> END HTTP (0-byte body)
[TalendNativeAPI#transactions] <--- HTTP/1.1 200 (282ms)
[TalendNativeAPI#transactions] cache-control: no-cache
[TalendNativeAPI#transactions] content-type: application/json;charset=UTF-8
[TalendNativeAPI#transactions] date: Sun, 27 Sep 2020 13:54:50 GMT
[TalendNativeAPI#transactions] expires: Thu, 01 Jan 1970 00:00:00 GMT
[TalendNativeAPI#transactions] pragma: No-cache
[TalendNativeAPI#transactions] set-cookie: JSESSIONID=XXX_XXX_XXX; Path=/talendmdm; HttpOnly
[TalendNativeAPI#transactions] transfer-encoding: chunked
[TalendNativeAPI#transactions] x-content-type-options: nosniff
[TalendNativeAPI#transactions] x-frame-options: DENY
[TalendNativeAPI#transactions] x-xss-protection: 1; mode=block
[TalendNativeAPI#transactions] <--- END HTTP (17-byte body)
and the exception stacktrace (I run this through a unit test):
feign.codec.DecodeException: Error while extracting response for type [class my.company.app.Transactions] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected character ('t' (code 116)): was expecting double-quote to start field name; nested exception is com.fasterxml.jackson.core.JsonParseException: Unexpected character ('t' (code 116)): was expecting double-quote to start field name
at [Source: (ByteArrayInputStream); line: 1, column: 3]
at feign.SynchronousMethodHandler.decode(SynchronousMethodHandler.java:180)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:140)
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78)
at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)
at com.sun.proxy.$Proxy147.transactions(Unknown Source)
at my.company.app.TalendIntegrationTest.test_noTransactions(TalendIntegrationTest.java:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
Caused by: org.springframework.web.client.RestClientException: Error while extracting response for type [class my.company.app.Transactions] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected character ('t' (code 116)): was expecting double-quote to start field name; nested exception is com.fasterxml.jackson.core.JsonParseException: Unexpected character ('t' (code 116)): was expecting double-quote to start field name
at [Source: (ByteArrayInputStream); line: 1, column: 3]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:117)
at org.springframework.cloud.openfeign.support.SpringDecoder.decode(SpringDecoder.java:59)
at org.springframework.cloud.openfeign.support.ResponseEntityDecoder.decode(ResponseEntityDecoder.java:62)
at feign.optionals.OptionalDecoder.decode(OptionalDecoder.java:36)
at feign.SynchronousMethodHandler.decode(SynchronousMethodHandler.java:176)
... 36 more
Caused by: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected character ('t' (code 116)): was expecting double-quote to start field name; nested exception is com.fasterxml.jackson.core.JsonParseException: Unexpected character ('t' (code 116)): was expecting double-quote to start field name
at [Source: (ByteArrayInputStream); line: 1, column: 3]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:245)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:227)
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:102)
... 40 more
Caused by: com.fasterxml.jackson.core.JsonParseException: Unexpected character ('t' (code 116)): was expecting double-quote to start field name
at [Source: (ByteArrayInputStream); line: 1, column: 3]
at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1804)
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:693)
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportUnexpectedChar(ParserMinimalBase.java:591)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._handleOddName(UTF8StreamJsonParser.java:1996)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._parseName(UTF8StreamJsonParser.java:1647)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextToken(UTF8StreamJsonParser.java:733)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:155)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4014)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3085)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:239)
... 42 more
How can I configure/"fix" Jackson to make it still read this falsy JSON from this specific endpoint (with the whole context of Spring Boot + Spring Cloud OpenFeign + Jackson auto-declared bean (by Spring)?
Thanks.
The ALLOW_UNQUOTED_FIELD_NAMES feature should do the trick:
public class Unquote {
public static void main(String[] args) throws Exception {
ObjectMapper om = new ObjectMapper()
.configure(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
JsonNode tree = om.readTree("{transactions:[\"some.uuid\"]}".getBytes());
System.out.println(tree);
}
}
This answer explains how to do this in the Spring context:
Configuring ObjectMapper in Spring
I am newbie in implementing SpringBoot+RestfulWebservice.In my project, exceptions are handled globally using #ControllerAdvice and Custom class is created to set the error code and error message in String format.We are passing the error object to HTTPResponse and returing the response.But I am wondering how the errormessages are converted in JSON format as , we are not explicitly using any httpMessageConverter.
- Is Spring Boot internally do the conversion?
Please help me in understanding the behavior. Give me some insights,though you feel like its basic question.
Basically Spring Boot defaults to JSON for all the things when you don't provide specifics around content-type negotiation.
As per the spring boot documentation on error handling here using #ControllerAdvice defaults to producing JSON formatted errors. From the docs:
You can also define a class annotated with #ControllerAdvice to customize the JSON document to return for a particular controller and/or exception type, as shown in the following example:
This page on mkyong.com has a good write up about how to customise the ControllerAdvice error handling.
As an example of JSON usage, this very bare bones controller will do its best to render any POJO as JSON (note if you just provide a primitive like a long it will simply return the primitive in text, but set the content-type as application/json)
#RequestMapping("api/time")
#RestController
public class TestApi {
#GetMapping
public Map<String, Long> time(){
Map<String, Long> res = new HashMap<String, Long>();
res.put("time_in_nanos", System.nanoTime());
return res;
}
}
example:
$ curl -v http://localhost:8080/api/time
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /api/time HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Tue, 04 Feb 2020 04:18:35 GMT
<
* Connection #0 to host localhost left intact
{"time_in_nanos":47078744054692}
That's for default requests (ie no Accept header, or Accept: */*), if you specify application/xml or something else it typically wont work:
$ curl -v http://localhost:8080/api/time --header 'Accept: application/xml'
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /api/time HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: application/xml
>
< HTTP/1.1 406
< Content-Length: 0
< Date: Tue, 04 Feb 2020 04:17:38 GMT
<
* Connection #0 to host localhost left intact
* Closing connection 0
By default springboot registers the following HttpMessageConverters on startup :
ByteArrayHttpMessageConverter – converts byte arrays
StringHttpMessageConverter – converts Strings
ResourceHttpMessageConverter – converts org.springframework.core.io.Resource for any type of octet stream
SourceHttpMessageConverter – converts javax.xml.transform.Source
FormHttpMessageConverter – converts form data to/from a MultiValueMap<String, String>.
Jaxb2RootElementHttpMessageConverter – converts Java objects to/from XML (added only if JAXB2 is present on the classpath)
MappingJackson2HttpMessageConverter – converts JSON (added only if Jackson 2 is present on the classpath)
MappingJacksonHttpMessageConverter – converts JSON (added only if Jackson is present on the classpath)
AtomFeedHttpMessageConverter – converts Atom feeds (added only if Rome is present on the classpath)
RssChannelHttpMessageConverter – converts RSS feeds (added only if Rome is present on the classpath)
So, if you are returning an object from your controller advice , spring will automatically by default call the Jackson converter to convert the object into a valid Json response.
Basically springboot checks the MIME type to decide which implementation of HttpMessageConverter to use.Also, it will depend on the "Accept" header to decide the type of data that the caller is expecting.If it's a request thatis received springboot will use the "Content-type" header to decide the type of data that is send.
I have a C# application that return a Json status when I call "http://host:port/app-status".
The response looks like:
{
"prtg":
{
"result": [
{
"channel": "DDS - ZDM - Konsistenzprüfung",
"value": "3",
"valuelookup": "prtg.RCLookup.DDS_ZDM_Check.BitField"
},
{
"channel": "ZDM DB Verbindungsversuche",
"value": "0",
"valuelookup": "prtg.RCLookup.Default.DB.Connect.Retry"
}
]
}
}
Then i have on zabbix server an item which type is http agent.
The request works fine. But I get this error:
Preprocessing failed for: HTTP/1.1 200 Ok..Content-Length: 361..Content-Type: application/json..Server: Grapevine/4.1.1.0 M...
1. Failed: cannot extract value from json by path ".prtg.result[0].value": cannot parse as a valid JSON object: invalid object format, expected opening character '{' or '[' at: 'HTTP/1.1 200 Ok
Content-Length: 361
Content-Type: application/json
Server: Grapevine/4.1.1.0 Microsoft-HTTPAPI/2.0
Date: Fri, 12 Apr 2019 14:19:12
In the preprocessing tab I have set a processing step with JsonPath.
The JsonPath is: .prtg.result[0].value
What is wrong?
Can help me everybody?
from error message it seems that you are trying to parse response from server inclusive headers which is wrong - you need to parse as JSON only data which is sent back (exclusive headers)
Why is JSON payload for int-http:outbound-gateway give 400 Bad Request?
Below request works fine on Chrome Rest Client with 3 headers specified in inObjgateway and JSON value of Obj
public class Obj {
#JsonProperty("phone")
private String phoneNo;
#JsonProperty("orderNumber")
private String orderNmb;
}
Application Context Code Snippet is
<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" />
Below line in detailed logs after show correct conversion from Object to JSON-:
Writing [{"phoneNo":"1617xxxxxxx","orderNmb":"2073xxxxx"}] as "application/json"
Detailed logs
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)
The Wireshark packet trace difference from what I observed is as below.
Working request trace from 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
Request not working from Application as per above code configuration !
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\"}"
Any pointers appreciated!
Questions like this are too general; you need to provide more details.
This requires you to use some basic debugging skills.
Step 1: Look at the server side logs to see what it is complaining about.
If that doesn't yield the solution,
Step 2: Compare a network monitor trace of the "good" and "bad" requests and figure out what's different between them. If you see what's different and can't figure out how to configure the gateway to replicate the "good" request then come back here with that specific question.
You can get a network trace with Wireshark or the eclipse TCP/IP Monitor, etc.
EDIT:
As you can see from the trace, you are doing two JSON conversions.
Remove the object-to-json-transformer and just let the outbound gateway do the conversion.
So I've got an arduino uno with a CC3000 shield attached and I want to push data to my Xively account:
https://xively.com/develop/yS4XfViIIEEkB94MJ4zs
However I get this error when I connect:
Connected!
Request DHCP
api.xively.com -> 64.94.18.120
Data Lengthz
PUT /v2/feeds/97346308.json HTTP/1.1
Host: api.xively.com
X-ApiKey:mykey
Content-Length: z
Connection: close
{"version":"1.0.0","datastreams" : [ {"id" : "Longitude","current_value" : ""},{"id" : "Latitude","current_value" : ""}]}
Connected to Xively server.
--------------------------------------
HTTP/1.1 411 Length Required
Date: Fri, 08 Aug 2014 13:19:33 GMT
Content-Type: text/html
Content-Length: 181
Connection: close
<html>
<head><title>411 Length Required</title></head>
<body bgcolor="white">
<center><h1>411 Length Required</h1></center>
<hr><center>nginx/1.1.19</center>
</body>
</html>
I understand that error 411 is a call for content length but I've alread declared this in my header and I still get this error.
Any help would be greatly appreciated :)
The Content-Length value must be a sequence of digits. What you sent is a letter, so the server complained that it didn't get your header in the correct format.
Instead of:
Content-Length: z
Use:
Content-Length: 0
If you are actually including data in the body of your request, the length should be the number of octets in the encoded body.