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
Оцените любую помощь в этом отношении.
Ответы
Ответ 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>