Spring JSON请求获取406(不可接受)


85

这是我的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错误,但休眠查询同时起作用。 每当我在保管箱中更改选择时,这就是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=?

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

有什么建议么?随意问的问题...

Answers:


107

406不可接受

由请求标识的资源仅能够生成响应实体,该响应实体具有根据请求中发送的接受标头不可接受的内容特征。

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

您的类路径中没有正确的Jackson库,或者您没有使用 <mvc:annotation-driven>指令。

我成功地复制了您的方案,并且使用这两个库并且没有任何headers="Accept=*/*"指令,它可以正常工作。

  • 杰克逊核心-asl-1.7.4.jar
  • 杰克逊-映射器-asl-1.7.4.jar

不,那不是问题,请检查我的答案。
Jaanus 2011年

如果手动配置HttpMessageConverters可以解决您的问题,则使用mvc:annotation-driven会执行与自动配置转换器和HandlerAdapters(HA)相同的操作。请注意,如果您显式配置任何高可用性,它将取消所有其他默认设置。
Villu Sepman 2011年

嗯,那是什么mvc?我曾经用过<tx:annotation-driven />,TX是xmlns:tx="http://www.springframework.org/schema/tx"
Jaanus 2011年

1
您得到的像是: <?xml version="1.0" encoding="UTF-8"?> <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">和spring-web-3.0.x和spring-webmvc-3.0.x罐子?
Villu Sepman 2011年

1
啊,我那里没有那个schemalocation。但是,谢谢,这对我有所帮助。我以为tx:annotation-drivenmvc:annotation-drivesmthin相同。
Jaanus 2011年

74

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

<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,根据请求“接受”标头不可接受


这个答案是Maven感知的最佳答案版本,并且完全可以正常工作!Maven异常可以更清楚地了解引擎盖下的实际情况。
2015年

4
您能提供Springs官方文档中记载的内容吗?有人怎么知道这是问题所在?
阿德林

您只需要指定对jackson-databind和jackson-mapper-asl的依赖关系,其他两个是传递性依赖关系,无论如何都可以解决。
ANRE

1
这仅在添加后两个依赖项后对我有用。谢谢。
DocWatson,2015年

您绝对不需要两者。Spring将为MappingJacksonHttpMessageConverterJackson 1和MappingJackson2HttpMessageConverterJackson 2添加。每一个都足以对JSON进行序列化/反序列化。您只需要一个(与Jackson 2一起使用,因为它具有更多功能)。
Sotirios Delimanolis 2015年

16

在另一种情况下,将返回此状态:如果Jackson映射器无法弄清楚如何序列化bean。举例来说,如果你有相同的布尔等两项访问方法,isFoo()getFoo()

发生的是,Spring的MappingJackson2HttpMessageConverter调用了Jackson的StdSerializerProvider来查看它是否可以转换您的对象。在呼叫链的底部,StdSerializerProvider._createAndCacheUntypedSerializer引发JsonMappingException带有提示信息的。但是,此异常被吞噬了StdSerializerProvider._createAndCacheUntypedSerializer,它告诉Spring无法转换对象。Spring已经用尽了转换器,报告说没有给Accept它提供可以使用的标头,给您它当然是虚假的*/*

这种行为存在一个错误,但是由于“无法重现”而被关闭:被调用的方法并未声明它可以抛出,因此吞咽异常显然是一个适当的解决方案(是的,这很讽刺)。不幸的是,杰克逊没有任何日志记录……并且在代码库中有很多注释希望它这样做,所以我怀疑这不是唯一隐藏的陷阱。


非常感谢!我是Spring MVC的新手,很难弄清楚如何返回JSON。每个人都提到缺少@ResponseBody批注和Jackson依赖项是406错误的原因。就我而言,事实证明我只是缺少属于我想以JSON返回的对象的公共字段的访问器方法。
安东尼·杰克

谢谢@kdgregory!我忘记为字段添加getter / setter。添加它们解决了此问题。
鲁本斯·马里努佐

16

我遇到了同样的问题,我的控制器方法执行了,但响应为错误406。我调试后AbstractMessageConverterMethodProcessor#writeWithMessageConverters发现该方法ContentNegotiationManager#resolveMediaTypes始终返回text/html,但不支持MappingJacksonHttpMessageConverter。问题在于,org.springframework.web.accept.ServletPathExtensionContentNegotiationStrategy早于的 工作org.springframework.web.accept.HeaderContentNegotiationStrategy以及我的请求的扩展/get-clients.html是导致我出现错误406的原因/get-clients


嗨atott,我遇到了同样的问题,关于更改请求扩展名的提示也解决了我的问题。非常感谢您分享您的解决方案!!
jherranzm 2014年

在我的情况下,由于相同的原因,是一个REST路径ID(其中带有扩展名)(在测试中)导致了406,而普通控制器正常工作(即使您要在REST路径ID中使用扩展名)。
–'Jur_

9

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

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

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

6

终于从这里找到答案:

将宁静的ajax请求映射到spring

我引用:

@ RequestBody / @ ResponseBody批注不使用普通的视图解析器,而是使用自己的HttpMessageConverters。为了使用这些注释,您应该按照参考资料中的说明在AnnotationMethodHandlerAdapter中配置这些转换器(您可能需要MappingJacksonHttpMessageConverter)。


3

<mvc:annotation-driven />入dispatcherservlet.xml,如果没有添加。并添加

<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中的这些依赖项


2
<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-base</artifactId>
    <version>2.6.3</version>
</dependency>

2
尽管此代码可以回答问题,但提供有关如何和/或为什么解决问题的其他上下文将提高答案的长期价值。
Francesco Menzani 2015年

2

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

我将获取者的可见性留在package-private上。杰克逊认为找不到它们并炸死了。(@JsonAutoDetect(getterVisibility=NON_PRIVATE)仅部分修复它。


那正是我的问题。我将二传手从公开改为保护,杰克逊停止了工作。
JuanMiguel

同样的问题,我当时使用AbstractMap.SimpleImmutableEntry然后降级为AbstractMap.SimpleEntry,仍然没有骰子,因为它没有密钥的二传手。去了吧。
罗伯特·贝恩

2

确保发送的对象(在这种情况下为“天气”)包含getter / setter


1

在控制器中,响应主体注释不应位于返回类型上,而不应位于方法上,例如:

@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能正常工作。
Jaanus 2011年

1

正如@atott提到的

如果您已在pom.xml中添加了最新版本的Jackson,并且使用的是Spring 4.0或更高版本,请@ResponseBody在您的操作方法上使用并且@RequestMapping配置了produces="application/json;charset=utf-8",但是您仍然得到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>

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


1

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开始,按照默认配置,favorPathExtension设置为true,因此,如果请求uri具有任何适当的扩展名(例如.htmspring),则优先考虑该扩展名。在步骤2中,我添加了contentNegotiationManager bean来覆盖它。


1

我遇到了同样的问题,因为我缺少@EnableWebMvc批注。(我所有的spring配置都是基于注释的,等效的XML将由mvc:annotation驱动)


0

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


我将jackson-all-1.8.5.jar添加到我的WEB-INF/lib文件夹中,但仍然存在相同的问题:/
Jaanus 2011年

0

像@joyfun一样检查杰克逊的正确版本,但还要检查我们的标头...接受/可能不会被客户端发送...使用Firebug或等效命令检查您的get请求实际发送的内容。我不确定注解/ may /的headers属性正在检查文字,尽管我不确定100%。


我将萤火虫的标头添加到主要帖子中。可以吗
Jaanus 2011年

0

除了这些明显的问题之外,我还有另一个无法解决的问题,无论在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>

0

不幸的是,我遇到了同样的问题,因为我的问题是在另一个班级里解决的。

我首先检查了@bekur所建议的所有依赖项是否存在,然后检查了从客户端到服务器的请求/响应,所有标头均已由Jquery正确设置。然后我检查了RequestMappingHandlerAdapter MessageConverters,所有的7个都到位,我真的开始讨厌Spring!然后,我更新为从Spring4.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


0
<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错误,则可以帮助您。


0

检查此线程。 spring mvc restcontroller返回json字符串 p / s:您应该将jack son映射配置添加到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()); }


0

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

上面的答案仅适用于较早的springVersion <4.1版本。对于最新的春季,您必须在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

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


-3

是否可以删除@RequestMapping中的headers元素并尝试。

喜欢


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

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


我删除了,但仍然出错。顺便说一句,当我查看tomcat日志时,然后对此查询被weatherService.getCurrentWeather(id);“激活”了。
Jaanus 2011年

请尝试这个应该可以的方法。添加上控制器@RequestMapping此注解(方法= RequestMethod.GET,标头= { “接受=文本/ XML,应用/ JSON”})
SATS
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.