Skip to content
Advertisement

SpringMVC, why ‘@RequestBody String body’ stops working after adding MappingJackson2HttpMessageConverter

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

Advertisement