Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring PUT Request: Unsupported Media Type (Code: 415)

I have got a rather obscure issue which I am not able to figure out after days of debugging. The issue is one of our PUT REST API started throwing Unsupported Media type in production. Here is the definition of method:

@RequestMapping(value = "/v1/put/user/profile", method = RequestMethod.PUT)
    public String updateProfile(@RequestBody UserAndroid user, ModelMap model,
            HttpServletRequest request, HttpServletResponse response) {

    }

In the PUT request, we are just passing the mobile number as follows:

{ "mobile": "9999559848"}

Here is the UserAndroid entity:

https://gist.github.com/madhur/eb0d9d006f4e4da706d7

Now, the most surprising part. After tracing down the github commits, we traced down the error to this newly introduced field in User (not the UserAndroid. they are different but related) entity (https://gist.github.com/madhur/06bbcfe11c0e751ab4df) :

@OneToOne(mappedBy="user", fetch=FetchType.LAZY)
private FullContactDetails fullContactDetails;

If we remove this field, the API starts working fine. Can anyone enlighten me why is this happening?

Update: Here are the Spring MVC logs upon executing the request:

https://gist.github.com/madhur/ef357f614b18c6ed42cb

Using Spring 3.2.2. Yes, we have both gson-2.2.4.jar and jackson in classpath.

24 Mar 2015 20:15:14 > org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter - Opening JPA EntityManager in OpenEntityManagerInViewFilter
 24 Mar 2015 20:15:14 > org.springframework.transaction.support.TransactionSynchronizationManager - Bound value [org.springframework.orm.jpa.EntityManagerHolder@6427300a] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@47672d99] to thread [http-bio-8080-exec-3]
 24 Mar 2015 20:15:14 > org.springframework.web.servlet.DispatcherServlet - Bound request context to thread: org.apache.struts2.dispatcher.StrutsRequestWrapper@5927198c
 24 Mar 2015 20:15:14 > org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'mvc' processing PUT request for [/mobileapp/v1/put/user/profile.json]
 24 Mar 2015 20:15:14 > org.springframework.web.servlet.DispatcherServlet - Testing handler map [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping@3bf55f38] in DispatcherServlet with name 'mvc'
 24 Mar 2015 20:15:14 > org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Looking up handler method for path /mobileapp/v1/put/user/profile.json
 24 Mar 2015 20:15:14 > org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Found 1 matching mapping(s) for [/mobileapp/v1/put/user/profile.json] : [{[/mobileapp/v1/put/user/profile.*],methods=[PUT],params=[],headers=[],consumes=[],produces=[],custom=[]}]
 24 Mar 2015 20:15:14 > org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Returning handler method [public java.lang.String com.lsa.akosha.webservices.MobileAppServiceController.updateProfile(com.lsa.akosha.entity.UserAndroid,org.springframework.ui.ModelMap,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)]
 24 Mar 2015 20:15:14 > org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'mobileAppServiceController'
 24 Mar 2015 20:15:14 > org.springframework.web.servlet.DispatcherServlet - Testing handler adapter [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter@439ee876]
 24 Mar 2015 20:15:14 > org.springframework.transaction.support.TransactionSynchronizationManager - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@6427300a] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@47672d99] bound to thread [http-bio-8080-exec-3]
 24 Mar 2015 20:15:14 > org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy - Connecting to database for operation 'prepareStatement'
 24 Mar 2015 20:15:14 > org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy - Using existing database connection for operation 'isClosed'
 24 Mar 2015 20:15:14 > org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy - Using existing database connection for operation 'getAutoCommit'
 24 Mar 2015 20:15:14 > org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy - Using existing database connection for operation 'isClosed'
 24 Mar 2015 20:15:14 > org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy - Using existing database connection for operation 'getWarnings'
 24 Mar 2015 20:15:14 > org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy - Using existing database connection for operation 'clearWarnings'
 24 Mar 2015 20:15:14 > org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy - Using existing database connection for operation 'close'
 24 Mar 2015 20:15:14 > org.springframework.web.method.support.HandlerMethodArgumentResolverComposite - Testing if argument resolver [org.springframework.web.method.annotation.RequestParamMethodArgumentResolver@18d649bf] supports [class com.lsa.akosha.entity.UserAndroid]
 24 Mar 2015 20:15:14 > org.springframework.web.method.support.HandlerMethodArgumentResolverComposite - Testing if argument resolver [org.springframework.web.method.annotation.RequestParamMapMethodArgumentResolver@3d9c4ab3] supports [class com.lsa.akosha.entity.UserAndroid]
 24 Mar 2015 20:15:14 > org.springframework.web.method.support.HandlerMethodArgumentResolverComposite - Testing if argument resolver [org.springframework.web.servlet.mvc.method.annotation.PathVariableMethodArgumentResolver@5fec4d5e] supports [class com.lsa.akosha.entity.UserAndroid]
 24 Mar 2015 20:15:14 > org.springframework.web.method.support.HandlerMethodArgumentResolverComposite - Testing if argument resolver [org.springframework.web.servlet.mvc.method.annotation.PathVariableMapMethodArgumentResolver@7bd9d9bd] supports [class com.lsa.akosha.entity.UserAndroid]
 24 Mar 2015 20:15:14 > org.springframework.web.method.support.HandlerMethodArgumentResolverComposite - Testing if argument resolver [org.springframework.web.servlet.mvc.method.annotation.MatrixVariableMethodArgumentResolver@1b6646d1] supports [class com.lsa.akosha.entity.UserAndroid]
 24 Mar 2015 20:15:14 > org.springframework.web.method.support.HandlerMethodArgumentResolverComposite - Testing if argument resolver [org.springframework.web.servlet.mvc.method.annotation.MatrixVariableMapMethodArgumentResolver@426f839b] supports [class com.lsa.akosha.entity.UserAndroid]
 24 Mar 2015 20:15:14 > org.springframework.web.method.support.HandlerMethodArgumentResolverComposite - Testing if argument resolver [org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor@27295730] supports [class com.lsa.akosha.entity.UserAndroid]
 24 Mar 2015 20:15:14 > org.springframework.web.method.support.HandlerMethodArgumentResolverComposite - Testing if argument resolver [org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor@b1b2466] supports [class com.lsa.akosha.entity.UserAndroid]
 24 Mar 2015 20:15:14 > org.springframework.web.method.HandlerMethod - Error resolving argument [0] [type=com.lsa.akosha.entity.UserAndroid]
HandlerMethod details: 
Controller [com.lsa.akosha.webservices.MobileAppServiceController]
Method [public java.lang.String com.lsa.akosha.webservices.MobileAppServiceController.updateProfile(com.lsa.akosha.entity.UserAndroid,org.springframework.ui.ModelMap,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)]

 org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:149)
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:180)
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:95)
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:123)
    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:745)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
    at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:849)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:649)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:96)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:180)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
24 Mar 2015 20:15:14 > org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Resolving exception from handler [public java.lang.String com.lsa.akosha.webservices.MobileAppServiceController.updateProfile(com.lsa.akosha.entity.UserAndroid,org.springframework.ui.ModelMap,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported
 24 Mar 2015 20:15:14 > org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Resolving exception from handler [public java.lang.String com.lsa.akosha.webservices.MobileAppServiceController.updateProfile(com.lsa.akosha.entity.UserAndroid,org.springframework.ui.ModelMap,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported
 24 Mar 2015 20:15:14 > org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver - Resolving exception from handler [public java.lang.String com.lsa.akosha.webservices.MobileAppServiceController.updateProfile(com.lsa.akosha.entity.UserAndroid,org.springframework.ui.ModelMap,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported
 24 Mar 2015 20:15:14 > org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver - Resolving exception from handler [public java.lang.String com.lsa.akosha.webservices.MobileAppServiceController.updateProfile(com.lsa.akosha.entity.UserAndroid,org.springframework.ui.ModelMap,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported
 24 Mar 2015 20:15:14 > org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Resolving exception from handler [public java.lang.String com.lsa.akosha.webservices.MobileAppServiceController.updateProfile(com.lsa.akosha.entity.UserAndroid,org.springframework.ui.ModelMap,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported
 24 Mar 2015 20:15:14 > org.springframework.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'mvc': assuming HandlerAdapter completed request handling
 24 Mar 2015 20:15:14 > org.springframework.web.servlet.DispatcherServlet - Cleared thread-bound request context: org.apache.struts2.dispatcher.StrutsRequestWrapper@5927198c
 24 Mar 2015 20:15:14 > org.springframework.web.servlet.DispatcherServlet - Successfully completed request
 24 Mar 2015 20:15:14 > org.springframework.web.context.support.XmlWebApplicationContext - Publishing event in WebApplicationContext for namespace 'mvc-servlet': ServletRequestHandledEvent: url=[/mobileapp/v1/put/user/profile.json]; client=[127.0.0.1]; method=[PUT]; servlet=[mvc]; session=[null]; user=[null]; time=[352ms]; status=[OK]
 24 Mar 2015 20:15:14 > org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalScheduledAnnotationProcessor'
 24 Mar 2015 20:15:14 > org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'incomingListener'
 24 Mar 2015 20:15:14 > org.springframework.web.context.support.XmlWebApplicationContext - Publishing event in Root WebApplicationContext: ServletRequestHandledEvent: url=[/mobileapp/v1/put/user/profile.json]; client=[127.0.0.1]; method=[PUT]; servlet=[mvc]; session=[null]; user=[null]; time=[352ms]; status=[OK]
 24 Mar 2015 20:15:14 > org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'incomingListener'
 24 Mar 2015 20:15:14 > org.springframework.transaction.support.TransactionSynchronizationManager - Removed value [org.springframework.orm.jpa.EntityManagerHolder@6427300a] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@47672d99] from thread [http-bio-8080-exec-3]
 24 Mar 2015 20:15:14 > org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter - Closing JPA EntityManager in OpenEntityManagerInViewFilter
 24 Mar 2015 20:15:14 > org.springframework.orm.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager
like image 928
Madhur Ahuja Avatar asked Mar 24 '15 14:03

Madhur Ahuja


People also ask

How do I fix 415 unsupported media type?

Fixing 415 Unsupported Media Type errorsEnsure that you are sending the proper Content-Type header value. Verify that your server is able to process the value defined in the Content-Type header. Check the Accept header to verify what the server is actually willing to process.

How do I fix unsupported media type error in Postman?

You need to set the content-type in postman as JSON (application/json). Go to the body inside your POST request, there you will find the raw option. Right next to it, there will be a drop down, select JSON (application. json).

How do you specify media type in Postman?

To do this, open Postman and create a new request by selecting New->Request from the top left: Under Headers, select Key = Content-Type: For Value, select application/json: THANKS FOR READING.

What is media type in spring?

In Spring REST APIs, Spring uses 'application/json' as a default media type. That is why, a REST controller can consume or produce JSON format payloads without having to specify the media types explicitly. Thus, in order to consume or produce data in a different form, the controller needs to specify that explicitly.


1 Answers

Please check the XML configuration where you have defined the contentnegotiating view resolver there you should have defined the mapping for json type media type . See if it works after updating those changes

This does not directly solves the issue but internally few dependencies resolve the mapping of content types for json as well try if it works

Reference Link

like image 92
Vikrant Mahajan Avatar answered Oct 17 '22 04:10

Vikrant Mahajan