【问题标题】:Spring JSON request getting 406 (not Acceptable)Spring JSON 请求得到 406(不可接受)
【发布时间】:2011-11-19 16:53:58
【问题描述】:

这是我的javascript:

    function getWeather() {
        $.getJSON('getTemperature/' + $('.data option:selected').val(), null, function(data) {
            alert('Success');                               
        });
    }

这是我的控制器:

@RequestMapping(value="/getTemperature/{id}", headers="Accept=*/*", method = RequestMethod.GET)
@ResponseBody
public Weather getTemparature(@PathVariable("id") Integer id){
    Weather weather = weatherService.getCurrentWeather(id);
        return weather;
}

spring-servlet.xml

<context:annotation-config />
<tx:annotation-driven />

收到此错误:

GET http://localhost:8080/web/getTemperature/2 406 (Not Acceptable)

标题:

响应标头

Server  Apache-Coyote/1.1
Content-Type    text/html;charset=utf-8
Content-Length  1070
Date    Sun, 18 Sep 2011 17:00:35 GMT

请求标头

Host    localhost:8080
User-Agent  Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
Accept  application/json, text/javascript, */*; q=0.01
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip, deflate
Accept-Charset  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection  keep-alive
X-Requested-With    XMLHttpRequest
Referer http://localhost:8080/web/weather
Cookie  JSESSIONID=7D27FAC18050ED84B58DAFB0A51CB7E4

有趣的笔记:

我收到 406 错误,但休眠查询同时工作。 每次我在 Dropbox 中更改选择时,tomcat 日志都是这样说的:

 select weather0_.ID as ID0_0_, weather0_.CITY_ID as CITY2_0_0_, weather0_.DATE as DATE0_0_, weather0_.TEMP as TEMP0_0_ from WEATHER weather0_ where weather0_.ID=?

可能是什么问题?之前在 SO 中有两个类似的问题,我在那里尝试了所有接受的提示,但我猜它们没有用......

有什么建议吗?欢迎提问...

【问题讨论】:

    标签: java javascript ajax json spring


    【解决方案1】:

    我遇到了同样的问题,因为我缺少 @EnableWebMvc 注释。 (我所有的 spring 配置都是基于注释的,XML 等价物是 mvc:annotation-driven)

    【讨论】:

      【解决方案2】:

      确保发送的对象(本例中为天气)包含 getter/setter

      【讨论】:

        【解决方案3】:

        可能没有人向下滚动这么远,但上述解决方案都没有为我解决这个问题,而是让我所有的 getter 方法 public 做到了。

        我在 package-private 中保留了我的 getter 可见性;杰克逊决定找不到他们并炸毁了。 (使用@JsonAutoDetect(getterVisibility=NON_PRIVATE) 只是部分修复了它。

        【讨论】:

        • 这正是我的问题。我将我的 setter 从 public 更改为 protected,Jackson 停止工作。
        • 同样的问题,我使用的是AbstractMap.SimpleImmutableEntry,然后降级为AbstractMap.SimpleEntry,仍然没有骰子,因为它没有密钥的设置器。去吧。
        【解决方案4】:

        Spring 4.3.10:我使用以下设置解决了这个问题。

        第 1 步:添加以下依赖项

            <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.6.7</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.6.7</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-core-asl</artifactId>
            <version>1.9.13</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.13</version>
        </dependency>
        

        第 2 步:在 MVC DispatcherServlet 上下文配置中添加以下内容:

        <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>
        
        <bean id="contentNegotiationManager"
            class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
            <property name="favorPathExtension" value="false"/>
            <property name="favorParameter" value="true"/>
            <property name="ignoreAcceptHeader" value="false" />
        </bean>
        

        从 spring 3.2 开始,根据默认配置,喜爱路径扩展设置为 true,因此如果请求 uri 有任何适当的扩展名,如.htm,spring 将优先考虑扩展名。在第 2 步中,我添加了 contentNegotiationManager bean 来覆盖它。

        【讨论】:

          【解决方案5】:

          检查 dispatcherservlet.xml 中的&lt;mvc:annotation-driven /&gt;,如果没有添加。 并添加

          <dependency>
              <groupId>org.codehaus.jackson</groupId>
              <artifactId>jackson-core-asl</artifactId>
              <version>1.9.13</version>
          </dependency>
          
          <dependency>
              <groupId>org.codehaus.jackson</groupId>
              <artifactId>jackson-mapper-asl</artifactId>
              <version>1.9.13</version>
          </dependency>
          

          pom.xml 中的这些依赖项

          【讨论】:

            【解决方案6】:

            这是 springVersion=5.0.3.RELEASE 的更新答案。

            以上答案仅适用于较旧的 springVersion 。对于最新的春季,您必须在 gradle 文件中添加以下依赖项:

            compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: fasterxmljackson
            compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: fasterxmljackson
            
            fasterxmljackson=2.9.4
            

            我希望这对使用最新春季版本的人有所帮助。

            【讨论】:

              【解决方案7】:

              检查这个线程。 spring mvc restcontroller return json string p/s:您应该将 jackson 映射配置添加到您的 WebMvcConfig 类

              @Override protected void configureMessageConverters( List<HttpMessageConverter<?>> converters) { // put the jackson converter to the front of the list so that application/json content-type strings will be treated as JSON converters.add(new MappingJackson2HttpMessageConverter()); // and probably needs a string converter too for text/plain content-type strings to be properly handled converters.add(new StringHttpMessageConverter()); }

              【讨论】:

                【解决方案8】:

                作为@atott mentioned

                如果您在 pom.xml 中添加了最新版本的 Jackson,并且使用 Spring 4.0 或更高版本,在您的操作方法上使用 @ResponseBody 并使用 produces="application/json;charset=utf-8" 配置 @RequestMapping,但是,您仍然得到 406(不可接受),我想您需要在 MVC DispatcherServlet 上下文配置中尝试此操作:

                <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
                
                <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
                    <property name="favorPathExtension" value="false" />
                </bean>
                

                这就是我最终解决问题的方式。

                【讨论】:

                  【解决方案9】:
                  <dependency>
                          <groupId>com.fasterxml.jackson.core</groupId>
                          <artifactId>jackson-databind</artifactId>
                          <version>2.8.0</version>
                      </dependency>
                  

                  我不使用ssl身份验证,这个jackson-databind包含jackson-core.jar和jackson-databind.jar,然后像这样更改RequestMapping内容:

                  @RequestMapping(value = "/id/{number}", produces = "application/json; charset=UTF-8", method = RequestMethod.GET)
                  public @ResponseBody Customer findCustomer(@PathVariable int number){
                      Customer result = customerService.findById(number);
                      return result;
                  }
                  

                  注意: 如果您的产品不是“application/json”类型,而我没有注意到这一点并收到 406 错误,请帮助您。

                  【讨论】:

                    【解决方案10】:
                    <dependency>
                        <groupId>com.fasterxml.jackson.jaxrs</groupId>
                        <artifactId>jackson-jaxrs-base</artifactId>
                        <version>2.6.3</version>
                    </dependency>
                    

                    【讨论】:

                    • 虽然此代码可以回答问题,但提供有关 如何 和/或 为什么 解决问题的附加上下文将改善答案的长期价值。
                    【解决方案11】:

                    我遇到了同样的问题,我的控制器方法执行但响应是错误 406。 我调试AbstractMessageConverterMethodProcessor#writeWithMessageConverters,发现ContentNegotiationManager#resolveMediaTypes 方法总是返回text/htmlMappingJacksonHttpMessageConverter 不支持。问题是org.springframework.web.accept.ServletPathExtensionContentNegotiationStrategy 早于org.springframework.web.accept.HeaderContentNegotiationStrategy 工作,并且我的请求/get-clients.html 的扩展是我出现错误406 问题的原因。我刚刚将请求url 更改为/get-clients

                    【讨论】:

                    • 您好 atott,我也有同样的问题,您关于更改请求扩展名的提示解决了我的问题。非常感谢您分享您的解决方案!
                    • 在我的情况下,它是一个带有扩展名的休息路径 ID(在测试中)导致 406 出于同样的原因,而普通控制器工作(即使您要使用扩展名)在其余路径 ID 中)。
                    【解决方案12】:

                    不幸的是,我遇到了同样的问题,这里的解决方案没有解决我的问题,因为我的问题属于不同的班级。

                    我首先按照@bekur 的建议检查了所有依赖项是否都已到位 然后我检查了从客户端到服务器的请求/响应,所有标头都由 Jquery 正确设置。 然后我检查了RequestMappingHandlerAdapterMessageConverters,所有7个都到位,我真的开始讨厌春天了!然后我从 Spring 4.0.6.RELEASE 更新到 4.2.0.RELEASE 我得到了另一个响应而不是上面的响应。是Request processing failed; nested exception is java.lang.IllegalArgumentException: No converter found for return value of type

                    这是我的控制器方法

                      @RequestMapping(value = "/upload", method = RequestMethod.POST,produces = "application/json")
                        public ResponseEntity<UploadPictureResult> pictureUpload(FirewalledRequest initialRequest) {
                    
                            DefaultMultipartHttpServletRequest request = (DefaultMultipartHttpServletRequest) initialRequest.getRequest();
                    
                            try {
                                Iterator<String> iterator = request.getFileNames();
                    
                                while (iterator.hasNext()) {
                                    MultipartFile file = request.getFile(iterator.next());
                                    session.save(toImage(file));
                                }
                            } catch (Exception e) {
                                return new ResponseEntity<UploadPictureResult>(new UploadPictureResult(),HttpStatus.INTERNAL_SERVER_ERROR);
                            }
                            return new ResponseEntity<UploadPictureResult>(new UploadPictureResult(), HttpStatus.OK);
                        } 
                    
                    
                    
                    
                        public class UploadPictureResult extends WebResponse{
                    
                        private List<Image> images;
                    
                        public void setImages(List<Image> images) {
                            this.images = images;
                        }
                    }
                    
                    
                    
                    
                    
                    
                        public class WebResponse implements Serializable {
                    
                    
                        protected String message;
                    
                        public WebResponse() {
                        }
                    
                        public WebResponse(String message) {
                    
                            this.message = message;
                        }
                    
                    
                        public void setMessage(String message) {
                            this.message = message;
                        }
                    }
                    

                    解决方案是让 UploadPictureResult 不扩展 WebResponse

                    由于某种原因,spring 在扩展 WebResponse 时无法确定如何转换 UploadPictureReslt

                    【讨论】:

                      【解决方案13】:

                      406 不可接受

                      请求标识的资源只能生成响应实体,其内容特征根据请求中发送的accept headers是不可接受的。

                      因此,您的请求接受标头是 application/json 并且您的控制器无法返回它。当找不到正确的 HTTPMessageConverter 来满足 @ResponseBody 注释的返回值时,就会发生这种情况。当您使用&lt;mvc:annotation-driven&gt; 时,HTTPMessageConverter 会自动注册,因为类路径中有某些 3-d 方库。

                      要么你的类路径中没有正确的 Jackson 库,要么你没有使用 &lt;mvc:annotation-driven&gt; 指令。

                      我成功复制了您的场景,并且使用这两个库并且没有 headers="Accept=*/*" 指令运行良好。

                      • jackson-core-asl-1.7.4.jar
                      • jackson-mapper-asl-1.7.4.jar

                      【讨论】:

                      • 不,这不是问题,检查我的答案。
                      • 如果手动配置 HttpMessageConverters 解决了您的问题,那么使用 mvc:annotation-driven 将与自动配置转换器和 HandlerAdapters(HA) 一样。请注意,如果您明确配置任何 HA,它将取消所有其他默认值。
                      • 嗯,mvc 是什么?我用了&lt;tx:annotation-driven /&gt;,tx 是xmlns:tx="http://www.springframework.org/schema/tx"
                      • 你有类似的东西:&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"&gt; 和 spring-web-3.0.x 和 spring-webmvc-3.0.x jars?
                      • 啊,我没有那个架构位置..但是谢谢,这对我有帮助。我认为tx:annotation-drivenmvc:annotation-drive 或smthin 相同。
                      【解决方案14】:

                      我有同样的问题,从最新的 Spring 4.1.1 开始,您需要将以下 jar 添加到 pom.xml。

                      <dependency>
                          <groupId>com.fasterxml.jackson.core</groupId>
                          <artifactId>jackson-core</artifactId>
                          <version>2.4.1</version>
                      </dependency>
                      <dependency>
                          <groupId>com.fasterxml.jackson.core</groupId>
                          <artifactId>jackson-databind</artifactId>
                          <version>2.4.1.1</version>
                      </dependency>
                      

                      还要确保你有以下 jar:

                      <dependency>
                          <groupId>org.codehaus.jackson</groupId>
                          <artifactId>jackson-core-asl</artifactId>
                          <version>1.9.13</version>
                      </dependency>
                      
                      <dependency>
                          <groupId>org.codehaus.jackson</groupId>
                          <artifactId>jackson-mapper-asl</artifactId>
                          <version>1.9.13</version>
                      </dependency>
                      

                      406 Spring MVC Json, not acceptable according to the request "accept" headers

                      【讨论】:

                      • 这个答案是最佳答案的 Maven 感知版本,它工作得很好! Maven 异常可以更清楚地了解幕后实际发生的事情。
                      • 您能否提供 Springs 官方文档中记录的位置?怎么会有人知道这是问题所在?
                      • 只需要指定jackson-databind和jackson-mapper-asl的依赖,另外两个是传递依赖,反正都会被解析。
                      • 这仅在添加后两个依赖项后对我有用。谢谢。
                      • 你绝对不需要两者。 Spring将为Jackson 1添加MappingJacksonHttpMessageConverter,为Jackson 2添加MappingJackson2HttpMessageConverter。每个都足以序列化/反序列化JSON。您只需要一个(选择 Jackson 2,因为它功能更丰富)。
                      【解决方案15】:

                      除了在 Spring servlet 中包含所有可能的 JAR、依赖项和注释之外,还有一个我无法解决的明显问题。最终我发现我有错误的文件扩展名,我的意思是我有两个单独的 servlet 在同一个容器中运行,我需要映射到不同的文件扩展名,其中一个是“.do”,另一个用于订阅的随机命名为“.do”。子”。一切都很好,但 SUB 是通常用于电影字幕文件的有效文件扩展名,因此 Tomcat 覆盖了标题并返回类似“text/x-dvd.sub ...”的内容,所以一切都很好,但应用程序期待 JSON 但得到字幕因此,我所要做的就是更改我添加的web.xml 文件中的映射:

                      <mime-mapping>
                          <extension>sub</extension>
                          <mime-type>application/json</mime-type>
                      </mime-mapping>
                      

                      【讨论】:

                        【解决方案16】:

                        确保以下 2 个jar 存在于类路径中。

                        如果缺少任何一个或两个,则会出现此错误。

                        jackson-core-asl-1.9.X.jar jackson-mapper-asl-1.9.X.jar
                        

                        【讨论】:

                          【解决方案17】:

                          还有另一种情况会返回此状态:如果 Jackson 映射器无法确定如何序列化您的 bean。例如,如果您对同一个布尔属性有两个访问器方法,isFoo()getFoo()

                          发生的事情是 Spring 的 MappingJackson2HttpMessageConverter 调用 Jackson 的 StdSerializerProvider 以查看它是否可以转换您的对象。在调用链的底部,StdSerializerProvider._createAndCacheUntypedSerializer 抛出带有信息性消息的 JsonMappingException。但是,这个异常被StdSerializerProvider._createAndCacheUntypedSerializer 吞下了,它告诉Spring 它不能转换对象。在用完转换器后,Spring 报告说它没有得到它可以使用的 Accept 标头,当你给它 */* 时,这当然是假的。

                          这种行为有一个bug,但它被关闭为“无法重现”:被调用的方法没有声明它可以抛出,所以吞下异常显然是一个合适的解决方案(是的,那是讽刺)。不幸的是,Jackson 没有任何日志记录……而且代码库中有很多 cmets 都希望这样做,所以我怀疑这不是唯一隐藏的问题。

                          【讨论】:

                          • 非常感谢!我是 Spring MVC 的新手,很难弄清楚如何返回 JSON。每个人都提到缺少 @ResponseBody 注释和 Jackson 依赖项是 406 错误的原因。就我而言,事实证明我只是缺少一个公共字段的访问器方法,该字段属于我想以 JSON 形式返回的对象。
                          • 谢谢@kdgregory!我忘了为字段添加 getter/setter。添加它们解决了这个问题。
                          【解决方案18】:

                          终于从这里找到答案:

                          Mapping restful ajax requests to spring

                          我引用:

                          @RequestBody/@ResponseBody 注解不使用普通的视图解析器,它们使用自己的 HttpMessageConverters。为了使用这些注解,您应该在 AnnotationMethodHandlerAdapter 中配置这些转换器,如参考中所述(您可能需要 MappingJacksonHttpMessageConverter)。

                          【讨论】:

                            【解决方案19】:

                            你能不能把@RequestMapping 中的headers 元素去掉,然后试试..

                            喜欢

                            @RequestMapping(value="/getTemperature/{id}", method = RequestMethod.GET)

                            我猜 spring 会进行“包含检查”而不是完全匹配接受标头。但是,仍然值得尝试删除 headers 元素并检查。

                            【讨论】:

                            • 我删除了,但仍然出错。顺便说一句,当我查看 tomcat 日志时,然后用这个查询是weatherService.getCurrentWeather(id);“激活”......所以有些东西......是否有可能出现 406 和 Hibernate SQL select 同时工作?
                            • 请试试这个应该可以的。在控制器上添加这个注解 @RequestMapping(method = RequestMethod.GET,headers = {"Accept=text/xml, application/json"})
                            【解决方案20】:

                            在控制器中,响应主体注释不应该是返回类型而不是方法,就像这样:

                            @RequestMapping(value="/getTemperature/{id}", headers="Accept=*/*", method = RequestMethod.GET)
                            public @ResponseBody Weather getTemparature(@PathVariable("id") Integer id){
                                Weather weather = weatherService.getCurrentWeather(id);
                                    return weather;
                            }
                            

                            我还会使用原始 jquery.ajax 函数,并确保正确设置 contentType 和 dataType。

                            另一方面,我发现 json 的 spring 处理相当有问题。当我自己使用字符串和 GSON 完成这一切时,这会更容易。

                            【讨论】:

                            • @ResponseBody 的位置应该无关紧要......我会研究 GSON......但如果可能的话,仍然希望这个 JSON 能够工作。
                            【解决方案21】:

                            像@joyfun 那样检查jackson 的正确版本,但也要检查我们的标头...接受 / 客户端可能不会传输...使用 firebug 或等效工具来检查您得到的请求实际上正在发送。我认为注释 / 可能 / 的 headers 属性正在检查文字,尽管我不是 100% 确定。

                            【讨论】:

                            • 我将来自 firebug 的标题添加到了主帖中。他们还好吗?
                            【解决方案22】:

                            确保您的类路径中有正确的杰克逊版本

                            【讨论】:

                            • 我将 jackson-all-1.8.5.jar 添加到我的WEB-INF/lib 文件夹中,但仍然是同样的问题:/
                            猜你喜欢
                            • 2014-12-24
                            • 1970-01-01
                            • 2013-04-26
                            • 2017-12-24
                            • 2013-03-18
                            • 1970-01-01
                            相关资源
                            最近更新 更多