need some help with jackson2 and springMvc.
Issue: when adding MappingJackson2HttpMessageConverter jsons fail to parse (previously they did parse) with error below.
I have following @Controller
method in code:
@RequestMapping(value = "/process", method = RequestMethod.POST, produces = {MediaType.APPLICATION_JSON_VALUE}) public @ResponseBody <T extends ApiRequest> ApiResponse process(HttpServletRequest httpRequest, @RequestBody String requestJson) {... }
And it have been working just fine until I’ve decided to add MappingJackson2HttpMessageConverter()
into converters. Like this:
@Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { ObjectMapper mapper = new ObjectMapper(); mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); mapper.registerModule(new JavaTimeModule()); mapper.registerModule(new Hibernate5Module()); converters.add(new MappingJackson2HttpMessageConverter(mapper)); }
but after I do so, my requests stop to work with the following error in log:
2020-06-05 12:40:01.518 WARN [qtp1892075175-21] (DefaultHandlerExceptionResolver.java:419) - Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse err or: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang. String` out of START_OBJECT token at [Source: (PushbackInputStream); line: 1, column: 1]
can’t get why.
I know that i’m still able to get body from servletInputStream
, but don’t want do so.
Hoping that maybe smb could give some clarity on such issue.
Thanks a lot!
I use Spring 5, jackson2.
I’ve been asked about some additional logs, here they are (DEBUG level), but there are no errors or stacktraces, don’t know whether they are helpful:
2020-06-05 14:08:33.731DEBUG [qtp1557520822-17] (HttpChannel.java:643) - REQUEST for //dev-vend:9990/api/v1/process on HttpChannelOverHttp@5283ae73{r=1,c=false,a=IDLE,uri=//dev-vend:9990/api/v1/process} POST //dev-vend:9990/api/v1/process HTTP/1.1 Host: dev-vend:9990 User-Agent: curl/7.54.0 Content-Type: application/json Accept: application/json X-AID: 77702 Content-Length: 91 2020-06-05 14:08:33.731DEBUG [qtp1557520822-17] (HttpConnection.java:359) - HttpConnection@1a50894c[p=HttpParser{s=CONTENT,0 of 91},g=HttpGenerator@3249a9a4{s=START}]=>HttpChannelOverHttp@5283ae73{r=1,c=false,a=IDLE,uri=//dev-vend:9990/api/v1/process}<-SocketChannelEndPoint@78d4ac8e{/172.16.21.40:62214<->/172.16.12.33:9990,OPEN,fill=-,flush=-,to=16/30000}{io=0/0,kio=0,kro=1}->HttpConnection@1a50894c[p=HttpParser{s=CONTENT,0 of 91},g=HttpGenerator@3249a9a4{s=START}]=>HttpChannelOverHttp@5283ae73{r=1,c=false,a=IDLE,uri=//dev-vend:9990/api/v1/process} parsed true HttpParser{s=CONTENT,0 of 91} 2020-06-05 14:08:33.731DEBUG [qtp1557520822-17] (HttpChannel.java:302) - HttpChannelOverHttp@5283ae73{r=1,c=false,a=IDLE,uri=//dev-vend:9990/api/v1/process} handle //dev-vend:9990/api/v1/process 2020-06-05 14:08:33.731DEBUG [qtp1557520822-17] (HttpChannelState.java:217) - handling HttpChannelState@630d22c8{s=IDLE a=NOT_ASYNC i=true r=IDLE w=false} 2020-06-05 14:08:33.732DEBUG [qtp1557520822-17] (HttpChannel.java:315) - HttpChannelOverHttp@5283ae73{r=1,c=false,a=DISPATCHED,uri=//dev-vend:9990/api/v1/process} action DISPATCH 2020-06-05 14:08:33.733DEBUG [qtp1557520822-17] (Server.java:519) - REQUEST POST /api/v1/process on HttpChannelOverHttp@5283ae73{r=1,c=false,a=DISPATCHED,uri=//dev-vend:9990/api/v1/process} 2020-06-05 14:08:33.733DEBUG [qtp1557520822-17] (ContextHandler.java:1076) - scope null||/api/v1/process @ o.s.b.w.e.j.JettyEmbeddedWebAppContext@5e3a577a{/,[file:///tmp/jetty-docbase.28728569537940407.9990/],AVAILABLE} 2020-06-05 14:08:33.733DEBUG [qtp1557520822-17] (ContextHandler.java:1153) - context=||/api/v1/process @ o.s.b.w.e.j.JettyEmbeddedWebAppContext@5e3a577a{/,[file:///tmp/jetty-docbase.28728569537940407.9990/],AVAILABLE} 2020-06-05 14:08:33.734DEBUG [qtp1557520822-17] (SessionHandler.java:1559) - sessionHandler=org.eclipse.jetty.server.session.SessionHandler110517298==dftMaxIdleSec=1800 2020-06-05 14:08:33.734DEBUG [qtp1557520822-17] (SessionHandler.java:1560) - session=null 2020-06-05 14:08:33.738DEBUG [qtp1557520822-17] (ServletHandler.java:465) - servlet |/api/v1/process|null -> dispatcherServlet@7ef5559e==org.springframework.web.servlet.DispatcherServlet,jsp=null,order=-1,inst=true 2020-06-05 14:08:33.745DEBUG [qtp1557520822-17] (ServletHandler.java:513) - chain=characterEncodingFilter->hiddenHttpMethodFilter->httpPutFormContentFilter->requestContextFilter->springSecurityFilterChain->httpTraceFilter->webMvcMetricsFilter->Jetty_WebSocketUpgradeFilter->dispatcherServlet@7ef5559e==org.springframework.web.servlet.DispatcherServlet,jsp=null,order=-1,inst=true 2020-06-05 14:08:33.750DEBUG [qtp1557520822-17] (ServletHandler.java:1618) - call filter characterEncodingFilter 2020-06-05 14:08:33.752DEBUG [qtp1557520822-17] (ServletHandler.java:1618) - call filter hiddenHttpMethodFilter 2020-06-05 14:08:33.752DEBUG [qtp1557520822-17] (ServletHandler.java:1618) - call filter httpPutFormContentFilter 2020-06-05 14:08:33.752DEBUG [qtp1557520822-17] (ServletHandler.java:1618) - call filter requestContextFilter 2020-06-05 14:08:33.754DEBUG [qtp1557520822-17] (ServletHandler.java:1618) - call filter springSecurityFilterChain 2020-06-05 14:08:33.760DEBUG [qtp1557520822-17] (FilterChainProxy.java:328) - /api/v1/process at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter' 2020-06-05 14:08:33.760DEBUG [qtp1557520822-17] (FilterChainProxy.java:328) - /api/v1/process at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter' 2020-06-05 14:08:33.761DEBUG [qtp1557520822-17] (HttpSessionSecurityContextRepository.java:174) - No HttpSession currently exists 2020-06-05 14:08:33.761DEBUG [qtp1557520822-17] (HttpSessionSecurityContextRepository.java:116) - No SecurityContext was available from the HttpSession: null. A new one will be created. 2020-06-05 14:08:33.767DEBUG [qtp1557520822-17] (FilterChainProxy.java:328) - /api/v1/process at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter' 2020-06-05 14:08:33.767DEBUG [qtp1557520822-17] (FilterChainProxy.java:328) - /api/v1/process at position 4 of 12 in additional filter chain; firing Filter: 'LogoutFilter' 2020-06-05 14:08:33.767DEBUG [qtp1557520822-17] (OrRequestMatcher.java:65) - Trying to match using Ant [pattern='/logout', GET] 2020-06-05 14:08:33.768DEBUG [qtp1557520822-17] (AntPathRequestMatcher.java:137) - Request 'POST /api/v1/process' doesn't match 'GET /logout 2020-06-05 14:08:33.768DEBUG [qtp1557520822-17] (OrRequestMatcher.java:65) - Trying to match using Ant [pattern='/logout', POST] 2020-06-05 14:08:33.768DEBUG [qtp1557520822-17] (AntPathRequestMatcher.java:157) - Checking match of request : '/api/v1/process'; against '/logout' 2020-06-05 14:08:33.768DEBUG [qtp1557520822-17] (OrRequestMatcher.java:65) - Trying to match using Ant [pattern='/logout', PUT] 2020-06-05 14:08:33.768DEBUG [qtp1557520822-17] (AntPathRequestMatcher.java:137) - Request 'POST /api/v1/process' doesn't match 'PUT /logout 2020-06-05 14:08:33.768DEBUG [qtp1557520822-17] (OrRequestMatcher.java:65) - Trying to match using Ant [pattern='/logout', DELETE] 2020-06-05 14:08:33.769DEBUG [qtp1557520822-17] (AntPathRequestMatcher.java:137) - Request 'POST /api/v1/process' doesn't match 'DELETE /logout 2020-06-05 14:08:33.769DEBUG [qtp1557520822-17] (OrRequestMatcher.java:72) - No matches found 2020-06-05 14:08:33.769DEBUG [qtp1557520822-17] (FilterChainProxy.java:328) - /api/v1/process at position 5 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter' 2020-06-05 14:08:33.769DEBUG [qtp1557520822-17] (AntPathRequestMatcher.java:157) - Checking match of request : '/api/v1/process'; against '/login' 2020-06-05 14:08:33.769DEBUG [qtp1557520822-17] (FilterChainProxy.java:328) - /api/v1/process at position 6 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter' 2020-06-05 14:08:33.769DEBUG [qtp1557520822-17] (FilterChainProxy.java:328) - /api/v1/process at position 7 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter' 2020-06-05 14:08:33.775DEBUG [qtp1557520822-17] (FilterChainProxy.java:328) - /api/v1/process at position 8 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter' 2020-06-05 14:08:33.776DEBUG [qtp1557520822-17] (AnonymousAuthenticationFilter.java:100) - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@4a762148: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 172.16.21.40; SessionId: null; Granted Authorities: ROLE_ANONYMOUS' 2020-06-05 14:08:33.776DEBUG [qtp1557520822-17] (FilterChainProxy.java:328) - /api/v1/process at position 9 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter' 2020-06-05 14:08:33.776DEBUG [qtp1557520822-17] (FilterChainProxy.java:328) - /api/v1/process at position 10 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter' 2020-06-05 14:08:33.776DEBUG [qtp1557520822-17] (FilterChainProxy.java:328) - /api/v1/process at position 11 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor' 2020-06-05 14:08:33.777DEBUG [qtp1557520822-17] (OrRequestMatcher.java:65) - Trying to match using Ant [pattern='/logout', GET] 2020-06-05 14:08:33.777DEBUG [qtp1557520822-17] (AntPathRequestMatcher.java:137) - Request 'POST /api/v1/process' doesn't match 'GET /logout 2020-06-05 14:08:33.778DEBUG [qtp1557520822-17] (OrRequestMatcher.java:65) - Trying to match using Ant [pattern='/logout', POST] 2020-06-05 14:08:33.778DEBUG [qtp1557520822-17] (AntPathRequestMatcher.java:157) - Checking match of request : '/api/v1/process'; against '/logout' 2020-06-05 14:08:33.778DEBUG [qtp1557520822-17] (OrRequestMatcher.java:65) - Trying to match using Ant [pattern='/logout', PUT] 2020-06-05 14:08:33.778DEBUG [qtp1557520822-17] (AntPathRequestMatcher.java:137) - Request 'POST /api/v1/process' doesn't match 'PUT /logout 2020-06-05 14:08:33.778DEBUG [qtp1557520822-17] (OrRequestMatcher.java:65) - Trying to match using Ant [pattern='/logout', DELETE] 2020-06-05 14:08:33.779DEBUG [qtp1557520822-17] (AntPathRequestMatcher.java:137) - Request 'POST /api/v1/process' doesn't match 'DELETE /logout 2020-06-05 14:08:33.779DEBUG [qtp1557520822-17] (OrRequestMatcher.java:72) - No matches found 2020-06-05 14:08:33.779DEBUG [qtp1557520822-17] (AntPathRequestMatcher.java:157) - Checking match of request : '/api/v1/process'; against '/login*' 2020-06-05 14:08:33.779DEBUG [qtp1557520822-17] (AntPathRequestMatcher.java:157) - Checking match of request : '/api/v1/process'; against '/api/**' 2020-06-05 14:08:33.779DEBUG [qtp1557520822-17] (AbstractSecurityInterceptor.java:219) - Secure object: FilterInvocation: URL: /api/v1/process; Attributes: [permitAll] 2020-06-05 14:08:33.779DEBUG [qtp1557520822-17] (AbstractSecurityInterceptor.java:348) - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@4a762148: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 172.16.21.40; SessionId: null; Granted Authorities: ROLE_ANONYMOUS 2020-06-05 14:08:33.790DEBUG [qtp1557520822-17] (AffirmativeBased.java:66) - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@2e99f07b, returned: 1 2020-06-05 14:08:33.791DEBUG [qtp1557520822-17] (AbstractSecurityInterceptor.java:243) - Authorization successful 2020-06-05 14:08:33.791DEBUG [qtp1557520822-17] (AbstractSecurityInterceptor.java:256) - RunAsManager did not change Authentication object 2020-06-05 14:08:33.794DEBUG [qtp1557520822-17] (FilterChainProxy.java:328) - /api/v1/process at position 12 of 12 in additional filter chain; firing Filter: 'FilterChainProxy' 2020-06-05 14:08:33.794DEBUG [qtp1557520822-17] (AntPathRequestMatcher.java:157) - Checking match of request : '/api/v1/process'; against '/controller/**' 2020-06-05 14:08:33.795DEBUG [qtp1557520822-17] (FilterChainProxy.java:202) - /api/v1/process has no matching filters 2020-06-05 14:08:33.795DEBUG [qtp1557520822-17] (FilterChainProxy.java:313) - /api/v1/process reached end of additional filter chain; proceeding with original chain 2020-06-05 14:08:33.795DEBUG [qtp1557520822-17] (ServletHandler.java:1618) - call filter httpTraceFilter 2020-06-05 14:08:33.802DEBUG [qtp1557520822-17] (ServletHandler.java:1618) - call filter webMvcMetricsFilter 2020-06-05 14:08:33.808DEBUG [qtp1557520822-17] (DefaultSingletonBeanRegistry.java:213) - Creating shared instance of singleton bean 'mvcHandlerMappingIntrospector' 2020-06-05 14:08:33.821DEBUG [qtp1557520822-17] (AbstractHandlerMethodMapping.java:313) - Looking up handler method for path /api/v1/process 2020-06-05 14:08:33.828DEBUG [qtp1557520822-17] (AbstractHandlerMethodMapping.java:323) - Did not find handler method for [/api/v1/process] 2020-06-05 14:08:33.828DEBUG [qtp1557520822-17] (AbstractHandlerMethodMapping.java:313) - Looking up handler method for path /api/v1/process 2020-06-05 14:08:33.829DEBUG [qtp1557520822-17] (AbstractHandlerMethodMapping.java:323) - Did not find handler method for [/api/v1/process] 2020-06-05 14:08:33.829DEBUG [qtp1557520822-17] (AbstractHandlerMethodMapping.java:313) - Looking up handler method for path /api/v1/process 2020-06-05 14:08:33.830DEBUG [qtp1557520822-17] (AbstractHandlerMethodMapping.java:320) - Returning handler method [public <T> ru.cwt.micro.api.model.res.ApiResponse ru.cwt.micro.api.controller.ApiController.process(javax.servlet.http.HttpServletRequest,java.lang.String)] 2020-06-05 14:08:33.836DEBUG [qtp1557520822-17] (ServletHandler.java:1618) - call filter Jetty_WebSocketUpgradeFilter 2020-06-05 14:08:33.837DEBUG [qtp1557520822-17] (ServletHandler.java:1649) - call servlet dispatcherServlet@7ef5559e==org.springframework.web.servlet.DispatcherServlet,jsp=null,order=-1,inst=true 2020-06-05 14:08:33.838DEBUG [qtp1557520822-17] (DispatcherServlet.java:891) - DispatcherServlet with name 'dispatcherServlet' processing POST request for [/api/v1/process] 2020-06-05 14:08:33.844DEBUG [qtp1557520822-17] (AbstractHandlerMethodMapping.java:313) - Looking up handler method for path /api/v1/process 2020-06-05 14:08:33.849DEBUG [qtp1557520822-17] (AbstractHandlerMethodMapping.java:323) - Did not find handler method for [/api/v1/process] 2020-06-05 14:08:33.849DEBUG [qtp1557520822-17] (AbstractHandlerMethodMapping.java:313) - Looking up handler method for path /api/v1/process 2020-06-05 14:08:33.849DEBUG [qtp1557520822-17] (AbstractHandlerMethodMapping.java:323) - Did not find handler method for [/api/v1/process] 2020-06-05 14:08:33.849DEBUG [qtp1557520822-17] (AbstractHandlerMethodMapping.java:313) - Looking up handler method for path /api/v1/process 2020-06-05 14:08:33.850DEBUG [qtp1557520822-17] (AbstractHandlerMethodMapping.java:320) - Returning handler method [public <T> ru.cwt.micro.api.model.res.ApiResponse ru.cwt.micro.api.controller.ApiController.process(javax.servlet.http.HttpServletRequest,java.lang.String)] 2020-06-05 14:08:33.850DEBUG [qtp1557520822-17] (OpenEntityManagerInViewInterceptor.java:88) - Opening JPA EntityManager in OpenEntityManagerInViewInterceptor 2020-06-05 14:08:33.888DEBUG [qtp1557520822-17] (HttpConnection.java:354) - HttpConnection@1a50894c[p=HttpParser{s=CONTENT,0 of 91},g=HttpGenerator@3249a9a4{s=START}]=>HttpChannelOverHttp@5283ae73{r=1,c=false,a=DISPATCHED,uri=//dev-vend:9990/api/v1/process}<-SocketChannelEndPoint@78d4ac8e{/172.16.21.40:62214<->/172.16.12.33:9990,OPEN,fill=-,flush=-,to=173/30000}{io=0/0,kio=0,kro=1}->HttpConnection@1a50894c[p=HttpParser{s=CONTENT,0 of 91},g=HttpGenerator@3249a9a4{s=START}]=>HttpChannelOverHttp@5283ae73{r=1,c=false,a=DISPATCHED,uri=//dev-vend:9990/api/v1/process} parse HeapByteBuffer@58ee971e[p=171,l=262,c=8192,r=91]={POST /api/v1/proc...-Length: 91rnrn<<<{n "uuid":"164...hment-result"n}>>>x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00...x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00} {} 2020-06-05 14:08:33.889DEBUG [qtp1557520822-17] (HttpParser.java:1342) - parseNext s=CONTENT HeapByteBuffer@58ee971e[p=171,l=262,c=8192,r=91]={POST /api/v1/proc...-Length: 91rnrn<<<{n "uuid":"164...hment-result"n}>>>x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00...x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00} 2020-06-05 14:08:33.889DEBUG [qtp1557520822-17] (HttpChannel.java:651) - HttpChannelOverHttp@5283ae73{r=1,c=false,a=DISPATCHED,uri=//dev-vend:9990/api/v1/process} onContent Content@89a4d20{HeapByteBufferR@68f81b03[p=171,l=262,c=8192,r=91]={POST /api/v1/proc...-Length: 91rnrn<<<{n "uuid":"164...hment-result"n}>>>x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00...x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00}} 2020-06-05 14:08:33.894DEBUG [qtp1557520822-17] (HttpInput.java:607) - HttpInputOverHTTP@5f89ed3[c=0,q=0,[0]=null,s=STREAM] addContent Content@89a4d20{HeapByteBufferR@68f81b03[p=171,l=262,c=8192,r=91]={POST /api/v1/proc...-Length: 91rnrn<<<{n "uuid":"164...hment-result"n}>>>x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00...x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00}} 2020-06-05 14:08:33.894DEBUG [qtp1557520822-17] (HttpParser.java:1685) - CONTENT --> END 2020-06-05 14:08:33.895DEBUG [qtp1557520822-17] (HttpChannel.java:659) - HttpChannelOverHttp@5283ae73{r=1,c=false,a=DISPATCHED,uri=//dev-vend:9990/api/v1/process} onContentComplete 2020-06-05 14:08:33.895DEBUG [qtp1557520822-17] (HttpChannel.java:675) - HttpChannelOverHttp@5283ae73{r=1,c=false,a=DISPATCHED,uri=//dev-vend:9990/api/v1/process} onRequestComplete 2020-06-05 14:08:33.895DEBUG [qtp1557520822-17] (HttpInput.java:607) - HttpInputOverHTTP@5f89ed3[c=0,q=1,[0]=EOF,s=STREAM] addContent EOF 2020-06-05 14:08:33.898DEBUG [qtp1557520822-17] (HttpConnection.java:359) - HttpConnection@1a50894c[p=HttpParser{s=END,91 of 91},g=HttpGenerator@3249a9a4{s=START}]=>HttpChannelOverHttp@5283ae73{r=1,c=false,a=DISPATCHED,uri=//dev-vend:9990/api/v1/process}<-SocketChannelEndPoint@78d4ac8e{/172.16.21.40:62214<->/172.16.12.33:9990,OPEN,fill=-,flush=-,to=181/30000}{io=0/0,kio=0,kro=1}->HttpConnection@1a50894c[p=HttpParser{s=END,91 of 91},g=HttpGenerator@3249a9a4{s=START}]=>HttpChannelOverHttp@5283ae73{r=1,c=false,a=DISPATCHED,uri=//dev-vend:9990/api/v1/process} parsed false HttpParser{s=END,91 of 91} 2020-06-05 14:08:33.898DEBUG [qtp1557520822-17] (HttpInput.java:297) - HttpInputOverHTTP@5f89ed3[c=1,q=1,[0]=EOF,s=STREAM] read 1 from Content@89a4d20{HeapByteBufferR@68f81b03[p=172,l=262,c=8192,r=90]={POST /api/v1/proc...Length: 91rnrn{<<<n "uuid":"164b...hment-result"n}>>>x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00...x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00}} 2020-06-05 14:08:33.899DEBUG [qtp1557520822-17] (AbstractMessageConverterMethodArgumentResolver.java:201) - Read [class java.lang.String] as "application/json;charset=UTF-8" with [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@394253a] 2020-06-05 14:08:33.906DEBUG [qtp1557520822-17] (HttpInput.java:297) - HttpInputOverHTTP@5f89ed3[c=91,q=1,[0]=EOF,s=STREAM] read 90 from Content@89a4d20{HeapByteBufferR@68f81b03[p=262,l=262,c=8192,r=0]={POST /api/v1/proc...hment-result"n}<<<>>>x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00...x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00}} 2020-06-05 14:08:33.906DEBUG [qtp1557520822-17] (HttpConnection.java:203) - releaseRequestBuffer HttpConnection@1a50894c[p=HttpParser{s=END,91 of 91},g=HttpGenerator@3249a9a4{s=START}]=>HttpChannelOverHttp@5283ae73{r=1,c=false,a=DISPATCHED,uri=//dev-vend:9990/api/v1/process}<-SocketChannelEndPoint@78d4ac8e{/172.16.21.40:62214<->/172.16.12.33:9990,OPEN,fill=-,flush=-,to=191/30000}{io=0/0,kio=0,kro=1}->HttpConnection@1a50894c[p=HttpParser{s=END,91 of 91},g=HttpGenerator@3249a9a4{s=START}]=>HttpChannelOverHttp@5283ae73{r=1,c=false,a=DISPATCHED,uri=//dev-vend:9990/api/v1/process} 2020-06-05 14:08:33.917DEBUG [qtp1557520822-17] (InvocableHandlerMethod.java:173) - Could not resolve parameter [1] in public <T> ru.cwt.micro.api.model.res.ApiResponse ru.cwt.micro.api.controller.ApiController.process(javax.servlet.http.HttpServletRequest,java.lang.String): JSON parse error: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token at [Source: (PushbackInputStream); line: 1, column: 1] 2020-06-05 14:08:33.918DEBUG [qtp1557520822-17] (AbstractHandlerExceptionResolver.java:137) - Resolving exception from handler [public <T> ru.cwt.micro.api.model.res.ApiResponse ru.cwt.micro.api.controller.ApiController.process(javax.servlet.http.HttpServletRequest,java.lang.String)]: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token at [Source: (PushbackInputStream); line: 1, column: 1] 2020-06-05 14:08:33.919DEBUG [qtp1557520822-17] (AbstractHandlerExceptionResolver.java:137) - Resolving exception from handler [public <T> ru.cwt.micro.api.model.res.ApiResponse ru.cwt.micro.api.controller.ApiController.process(javax.servlet.http.HttpServletRequest,java.lang.String)]: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token at [Source: (PushbackInputStream); line: 1, column: 1] 2020-06-05 14:08:33.920DEBUG [qtp1557520822-17] (AbstractHandlerExceptionResolver.java:137) - Resolving exception from handler [public <T> ru.cwt.micro.api.model.res.ApiResponse ru.cwt.micro.api.controller.ApiController.process(javax.servlet.http.HttpServletRequest,java.lang.String)]: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token at [Source: (PushbackInputStream); line: 1, column: 1] 2020-06-05 14:08:33.920 WARN [qtp1557520822-17] (DefaultHandlerExceptionResolver.java:419) - Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token
Advertisement
Answer
When you use configureMessageConverters
and add to the List<HttpMessageConverter<?>>
, you’re telling Spring MVC that the instances you add are the only HttpMessageConverter
s you’ll need. As a result, it won’t add the defaults that it maintains. The javadoc states
Configure the
HttpMessageConverters
to use for reading or writing to the body of the request or response. If no converters are added, a default list of converters is registered.Note that adding converters to the list, turns off default converter registration. To simply add a converter without impacting default registration, consider using the method
extendMessageConverters(java.util.List)
instead.
One of those defaults is a StringHttpMessageConverter
which can essentially parse any request body content type into a String
. Since you overwrote the list, it won’t be registered and Spring MVC won’t be able to populate your @RequestBody
annotated String
parameter.
As suggested in the Javadoc, you can either use extendMessageConverters(java.util.List)
to add your custom MappingJackson2HttpMessageConverter
(although you’ll probably want to replace the existing default MappingJackson2HttpMessageConverter
instance) or you can add a StringHttpMessageConverter
to your list yourself.