Spring PUT请求:不支持的媒体类型(代码:415)



我遇到了一个相当模糊的问题,经过几天的调试,我无法解决。问题是我们的PUT REST API在生产中开始抛出Unsupported Media type。以下是方法的定义:

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

在PUT请求中,我们只是按如下方式传递手机号码:

{ "mobile": "9999559848"}

这是UserAndroid实体:

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

现在,最令人惊讶的部分。在追踪github提交之后,我们将错误追踪到User(不是UserAndroid。它们不同但相关)实体中新引入的字段(https://gist.github.com/madhur/06bbcfe11c0e751ab4df):

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

如果我们删除此字段,API将开始正常工作。有人能告诉我为什么会发生这种事吗?

更新:以下是执行请求时的Spring MVC日志:

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

使用弹簧3.2.2。是的,类路径中有gson-2.2.4.jar和jackson。

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

请检查XML配置,您已经在其中定义了内容协商视图解析器,您应该在那里定义json类型媒体类型的映射。看看更新这些更改后是否有效

这并不能直接解决问题,但在内部,很少有依赖关系可以解决json的内容类型映射,也可以尝试它是否有效

参考链接

最新更新