Подтвердить что ты не робот

Spring 3.x JSON status 406 "характеристики неприемлемы в соответствии с запросом" принять "заголовки()"

При попытке получить ответ в JSON с помощью Spring 3.x я получаю 406 error "Ресурс, идентифицированный этим запросом, способен генерировать ответы с характеристиками, неприемлемыми в соответствии с request" accept " заголовки().

Вот моя среда

* Spring 3.2.0.RELEASE
* included jackson-mapper-asl-1.7.9.jar, jackson-core-asl-1.7.9.jar
* Tomcat 6.x
* mvc:annotation-driven in Spring configuration XML file

Мой контроллер:

@RequestMapping("/contest")
public class ContestController {

    @RequestMapping(value="{name}", headers="Accept=*/*", method = RequestMethod.GET)
    public @ResponseBody Contest getContestInJSON(@PathVariable String name) {
        Contest contest = new Contest();
        contest.setName(name);
        contest.setStaffName(new String("contestitem1"));

        return contest;
    }

}

Мой Spring Файл конфигурации

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

<context:component-scan base-package="com.contestframework.controllers" />

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">

<property name="mediaTypes">
    <map>
      <entry key="atom" value="application/atom+xml"/>
      <entry key="html" value="text/html"/>
      <entry key="json" value="application/json"/>
    </map>
 </property>

 <property name="viewResolvers">
 <list>
  <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/pages/"/>
    <property name="suffix" value=".jsp"/>
  </bean>
 </list>
 </property>

 <property name="defaultViews">
  <list>
   <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
  </list>
 </property>

 </bean>

<mvc:annotation-driven />

</beans>

После этого я просто получаю доступ к контроллеру, используя ниже:

http://domain/SpringWebProject/json/contest/abcd

и ответ, который я получаю, - это состояние 406: "Ресурс, идентифицированный этим запросом, способен генерировать ответы с характеристиками, недопустимыми в соответствии с запросом" принять "заголовки()."

Я также попробовал альтернативный механизм, обратившись к нему с помощью Javascript AJAX, чтобы убедиться, что заголовок моего запроса имеет application/JSON, но это привело к тому же результату статуса 406

$.getJSON('contest/abcd', function(data) {
console.log(data) }

Вот мой ЗАЯВИТЕЛЬ HEADER, захваченный в браузере:

Request URL:http://localhost:8080/SpringWebProject/json/contest/abcd
Request Method:GET
Status Code:406 Not Acceptable

Accept:application/json, text/javascript, */*; q=0.01
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Cookie:JSESSIONID=59689C95B0B9C21494EB0AB9D9F7BCCD
Host:localhost:8080
Referer:http://localhost:8080/SpringWebProject/json/welcome
User-Agent:Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4
X-Requested-With:XMLHttpRequest
Response Headersview source
Content-Length:1070
Content-Type:text/html;charset=utf-8
Date:Fri, 12 Oct 2012 18:23:40 GMT
Server:Apache-Coyote/1.1

Оцените любую помощь в этом отношении.

4b9b3361

Ответ 1

В вашей конфигурации нет ничего плохого, позвольте мне предложить несколько небольших изменений:

a) Пространства имен ошибочны - они относятся к схемам 3.0, просто изменяют их на 3.1 или не ссылаются на версию явно, таким образом, например.

xsi:schemaLocation="
    http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans.xsd

ИЛИ

xsi:schemaLocation="
    http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd

b) Вам не требуется ContentNegotiationViewResolver, вы можете удалить все, кроме component-scan и <mvc:annotation-driven/> из своей конфигурации

c) Запрос не будет работать непосредственно из браузера, поскольку он явно требует, чтобы заголовок Accept для вызова "application/json" - $.getJson работал, хотя он отправляет правильные заголовки

d) Извлеките headers=Acc.. из @RequestMapping и также вы получите оба критерия фильтрации для соответствия правильному методу вызова метода.

С этими словами нет причин, по которым json не должен обслуживаться, можете ли вы попробовать с ними и посмотреть, как это происходит.

Ответ 2

Я тоже испытал эту же проблему. Похоже, что это проблема с последней версией 3.2.0.RELEASE, поскольку я ранее имел 3.1.2.RELEASE, и все это сработало. После перехода на 3.2.0.RELEASE он ломается. Испытали с 3.1.3.RELEASE и это работает нормально. Поэтому на данный момент я бы предложил вернуться к 3.1.3.RELEASE

EDIT: благодаря другому сообщению на этом сайте, которое связано со следующим местоположением: http://static.springsource.org/spring-framework/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-config-content-negotiation

Теперь у меня это работает, отключив получение типа носителя на основе расширения запрошенного пути. Это можно сделать следующим образом:

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <!-- Turn off working out content type based on URL file extension, should fall back to looking at the Accept headers -->
    <property name="favorPathExtension" value="false" />
</bean>

И укажите версию 3.2 для всех расположений схемы xsd.

И это использует следующие jsonson jars:

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

Ответ 3

У меня была та же проблема, и я решил ее, добавив следующую зависимость

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>${jackson.version}</version>
</dependency>

Раньше я делаю это со следующей зависимостью

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>${com.jackson.core-version}</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>${com.jackson.core-version}</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${com.jackson.core-version}</version>
</dependency>

Короче, я заменил com.fasterxml.jackson.core на org.codehaus.jackson

Ответ 4

У меня была эта проблема в Spring MVC 4. Добавление джексон-аннотаций, jackson-core и jackson-databind не решило проблему. Попробуйте этот libs:

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

Ответ 5

Я думаю, вам нужно добавить create = "application/json" в ваш @RequestMapping (не смотрел на spring mvc через некоторое время, поэтому я не на 100% положителен)...

http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html

16.3.2.6 Типы воспроизводимых носителей

Вы можете сузить первичное сопоставление, указав список доступных типов носителей. Запрос будет сопоставляться только в том случае, если заголовок запроса принятия соответствует одному из этих значений. Кроме того, использование условия получения гарантирует, что фактический тип содержимого, используемый для генерации ответа, соответствует типам носителей, указанным в условии получения. Например:

@Controller
@RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, produces="application/json")
@ResponseBody
public Pet getPet(@PathVariable String petId, Model model) {    
    // implementation omitted
}

Ответ 6

У меня была такая же проблема, и комментарий, добавленный Biju Kunjummen в этом ответе, сработал у меня отлично

fooobar.com/questions/136296/...

У меня есть публичные геттеры в моем классе Java

Ответ 7

У меня была аналогичная проблема, она была решена, когда я добавил библиотеку jackson-databind.

Это мои зависимости:

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

Ответ 8

Спасибо, что поделились опытом. У меня возникла такая же проблема, и он работает для меня, используя конфигурацию, как показано ниже:

  • Spring Версия MVC: 3.2.5.RELEASE
  • Apache-6.0.24-кот
  • JDK1.6
  • ДЖЕКСОНА-ядро-ASL-1.9.10.jar
  • ДЖЕКСОНА-картографа-ASL-1.9.10.jar

Spring Файл конфигурации MVC:

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<!-- Turn off working out content type based on URL file extension, should fall back to looking at the Accept headers -->
    <property name="favorPathExtension" value="false" />
</bean>

Модельный класс: Country.java

 private Integer countryId;
 private String name;
 //public setters and getters

Метод контроллера:

@RequestMapping(value = "/get_country_json",method = RequestMethod.GET)
@ResponseBody
public Country getCountry()

Дескриптор развертывания (web.xml)

 <servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>       
</servlet>
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*.htm</url-pattern>
</servlet-mapping>

URL Требуется вызов метода контроллера:/SpringCURDApp/get_country_json.htm

Я надеюсь, что это может помочь кому-то.

Ответ 9

Не делайте ту же ошибку, что и я, проводите весь день с настройкой Spring, когда на самом деле ваш объект, возвращаемый в веб-службе, не правильно обрабатывает XML. Кажется, что Spring обнаруживает ошибку маршалинга JAXB и не сообщает об этом. Используйте этот код песочницы для проверки маршалинга JAXB:

MyClass myclass = new MyClass();
//populate myclass here

JAXBContext context = JAXBContext.newInstance(MyClass.class);

Marshaller m = context.createMarshaller();
StringWriter w = new StringWriter();

m.marshal(myclass, w);
System.out.println(w);

Это создало и отобразило исключение. Исправлена ​​причина, и мой веб-сервис доступен как в XML, так и в JSON.

Ответ 10

В ближайшее время:

Для Spring MVC 4.1.6 достаточно:

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

jackson-databind имеет зависимость от артефактов ядра и аннотаций.


Подробнее:

Что такое HTTP 406 ошибка?

406 Неприемлемо Запрошенный ресурс способен генерировать контент не приемлемым в соответствии с заголовками Accept, отправленными в запросе.

Это означает, что сервер не может генерировать контент, указанный в заголовке Accept Header.

Но как сервер знает, какой MEDIA TYPE он может генерировать, а какой нет?

Spring В Интернете есть концепция HttpMessageConverter. Некоторые из этих конвертеров уже зарегистрированы в Spring, а AbstractMessageConverterMethodArgumentResolver содержит их в свойствах messageConverters.

Во время обработки запроса AbstractMessageConverterMethodProcessor анализируется, что Spring может конвертировать и сохранять все поддерживаемые типы СМИ в переменной producibleMediaTypes. Если запрошено MEDIA TYPE не может быть произведено, тогда говорит Ошибка 406 == Я не могу создать запрошенный тип носителя. К сожалению.

Чтобы сократить длинную историю, необходимо скопировать регистраторы. В вашем случае это библиотека джексона, которая создает application/json

Ответ 11

Пожалуйста, смотрите http://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-config-content-negotiation Как вы можете видеть

"Для расширений файлов в URI запроса, конфигурации Java MVC и MVC, автоматически регистрирует расширения, такие как .json,.xml,.rss и .atom, если соответствующие зависимости, такие как Jackson, JAXB2 или Rome присутствуют на пути к классам.

Вы должны добавить ".json" в конце URI (например, http://domain/SpringWebProject/json/contest/abcd.json) Меня устраивает.

Ответ 12

У меня была аналогичная проблема, но это было странно. Я объясню, как я это разрешил.

В моем web.xml мой сервлет-диспетчер был сопоставлен с *.htm

<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

и независимо от того, что я делал, это всегда бросало -

Ресурс, идентифицированный этим запросом, способен генерировать ответы с характеристиками, неприемлемыми в соответствии с заголовком запроса "принять"

Наконец, я изменил его на

<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

и это сработало. Я думаю, что когда вы просто указываете

<mvc:annotation-driven/> 

расширение имеет приоритет над заголовком accept, а .htm создает проблемы. И, очевидно, я не мог использовать xml или json, поскольку сам сервлет не был отображен.

Я также хотел бы добавить, что выдает аннотацию, которую вы, spring попытаетесь сопоставить, будет принимать заголовок входящего запроса. Я использовал метод обработчика запросов для json и xml. Поскольку я использую Java 8, а Jaxb встроен в Java, поскольку Java 7 не нуждается в зависимости от JAXB. Для json мне нужно было добавить -

<dependency org="com.fasterxml.jackson.core" name="jackson-databind" rev="2.8.5"/>

Я использую плющ для управления зависимостями.

Ответ 13

Возможно, вам стоит обновить вашу библиотеку Джексона. Я использую Spring v4.3.8, и я использую его следующим образом:

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

Ответ 14

Если вы используете Spring 4, вы должны только обновлять свои библиотеки:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.3.0</version>
    </dependency>

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