Весенний запрос JSON получение 406 (не приемлемо)
это мой 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-сервлет.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, но запрос hibernate работает тем временем. Это то, что котяра журнал говорит, что, каждый раз, когда я меняю выбор в dropbox:
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 раньше, я попробовал все принятые намеки там, но они не сработали, я думаю...
какие предложения? Не стесняйтесь задавать вопросы...
21 ответ:
406 Неприемлемо
ресурс, идентифицированный запросом, способен генерировать только объекты ответа, которые имеют характеристики контента, неприемлемые в соответствии с заголовками accept, отправленными в запросе.
Итак, ваш запрос принимает заголовок application / json, и ваш контроллер не может его вернуть. Это происходит, когда правильный HTTPMessageConverter не может быть найден, чтобы удовлетворить @ResponseBody аннотированное возвращаемое значение. HTTPMessageConverter автоматически регистрируются при использовании
<mvc:annotation-driven>
учитывая некоторые 3-д партии библиотеки в classpath.либо у вас нет правильной библиотеки Джексона в вашем classpath, либо вы не использовали
у меня была такая же проблема, с последней весной 4.1.1 и далее вам нужно добавить следующие банки в 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>
также убедитесь, что у вас есть следующие банки:
<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, не приемлемый в соответствии с запросом "принять" заголовки
есть еще один случай, когда этот статус будет возвращен: если Jackson mapper не может понять, как сериализовать ваш Боб. Например, если у вас есть два метода доступа для одного и того же логического свойства,
isFoo()
иgetFoo()
.то, что происходит, это весна MappingJackson2HttpMessageConverter называет StdSerializerProvider чтобы увидеть, если он может преобразовать ваш объект. В нижней части цепочки вызовов,
StdSerializerProvider._createAndCacheUntypedSerializer
бросает aJsonMappingException
с информативным сообщением. Однако это исключение проглатываетсяStdSerializerProvider._createAndCacheUntypedSerializer
, что говорит Spring, что он не может преобразовать объект. Исчерпав конвертеры, Spring сообщает, что ему не даютAccept
заголовок, который он может использовать, что, конечно, является фиктивным, когда вы даете его*/*
.есть ошибка для этого поведения, но он был закрыт как "не может воспроизвести": вызываемый метод не объявляет, что он может бросать, поэтому глотает исключения очевидно подходящее решение (да, это был сарказм). К сожалению, у Джексона нет никакой регистрации ... и есть много комментариев в кодовой базе, желающих это сделать, поэтому я подозреваю, что это не единственный скрытый gotcha.
у меня была та же проблема, мой метод контроллера выполняется, но ответ-ошибка 406. Я отлаживаю
AbstractMessageConverterMethodProcessor#writeWithMessageConverters
и нашел этот методContentNegotiationManager#resolveMediaTypes
всегда возвращаетtext/html
, который не поддерживаетсяMappingJacksonHttpMessageConverter
. Проблема в том, чтоorg.springframework.web.accept.ServletPathExtensionContentNegotiationStrategy
строительство раньше, чемorg.springframework.web.accept.HeaderContentNegotiationStrategy
, и продление моего запроса/get-clients.html
является причиной моей проблемы с ошибкой 406. Я только что изменил url запроса на/get-clients
.
убедитесь, что следующие 2
jar
' s присутствуют в пути к классу.Если один или оба отсутствуют, то эта ошибка придет.
jackson-core-asl-1.9.X.jar jackson-mapper-asl-1.9.X.jar
наконец-то нашел ответ здесь:
отображение restful ajax запросов к spring
цитирую:
аннотации@RequestBody/@ResponseBody не используют обычные распознаватели представлений, они используют свои собственные HttpMessageConverters. Чтобы использовать эти аннотации, вы должны настроить эти конвертеры в AnnotationMethodHandlerAdapter, как описано в ссылке (вам, вероятно, понадобится MappingJacksonHttpMessageConverter).
Регистрация
<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
<dependency> <groupId>com.fasterxml.jackson.jaxrs</groupId> <artifactId>jackson-jaxrs-base</artifactId> <version>2.6.3</version> </dependency>
в контроллере не должна ли аннотация тела ответа быть на типе возврата, а не на методе, например:
@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 довольно проблематичной. Это было проще, когда я сделал все это сам, используя строки и GSON.
У меня была та же проблема, потому что мне не хватало аннотации @EnableMvc. (Вся моя весенняя конфигурация основана на аннотациях, эквивалент XML будет mvc: annotation-driven)
проверьте, как @joyfun сделал для правильной версии Джексона, но также проверьте наши заголовки ... Принять / не может быть передано клиентом ... используйте firebug или эквивалент, чтобы проверить, что ваш запрос get на самом деле отправляет. Я думаю, что атрибут заголовков аннотации / может / проверять литералы, хотя я не уверен на 100%.
кроме очевидных проблем у меня была еще одна, которую я не мог исправить, независимо от включения всех возможных банок, зависимостей и аннотаций в Spring servlet. В конце концов я обнаружил, что у меня неправильное расширение файла, что я имею в виду, что у меня было два отдельных сервлета, работающих в одном контейнере, и мне нужно было сопоставить разные расширения файлов, где один был ".do", а другой, используемый для подписок, был случайным образом назван ".подводная лодка." Все хорошо, но SUB-это допустимое расширение файла, обычно используемое для фильмов файлы субтитров и, таким образом, Tomcat переопределяли заголовок и возвращали что-то вроде "text/x-dvd.подводная лодка..."так что все было хорошо, но приложение ожидало JSON, но получая субтитры, таким образом, все, что мне нужно было сделать, это изменить отображение в моем
web.xml
файл, который я добавил:<mime-mapping> <extension>sub</extension> <mime-type>application/json</mime-type> </mime-mapping>
у меня была та же проблема, к сожалению, не решение здесь решило мою проблему, поскольку моя проблема была чем-то в другом классе.
Я сначала проверил, что все зависимости находятся на месте, как предложил @bekur затем я проверил запрос / ответ, который перемещается от клиентов к серверу, все заголовки были правильно установлены Jquery. Затем я проверил
RequestMappingHandlerAdapter
MessageConverters
и все 7 из них были в месте, я действительно начал ненавидеть весну ! Затем я обновился до С весны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 не смог определить, как конвертировать UploadPictureReslt, когда он расширил WebResponse
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.0</version> </dependency>
Я не использую аутентификацию ssl, и этот jackson-databind содержит jackson-core.jar и Джексон-метод 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, помогите это может помочь вам.
как @atott указано.
если вы добавили последнюю версию Jackson в свой pom.xml, а также с 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>
вот как я решил свою проблему, наконец.
проверка этой теме. spring MVC restcontroller возвращает строку json p / s: Вы должны добавить Jack son mapping config в свой класс 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()); }
это ответ на обновление для springVersion=5.0.3.ОСВОБОЖДАТЬ.
эти ответы выше будут работать только старше 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
Я надеюсь, это будет полезно для тех, кто использует последние версии весна.
Весна 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>
начиная с весны 3.2, согласно конфигурации по умолчанию favorPathExtension устанавливается как true, из-за этого, если uri запроса имеет какие-либо правильные расширения, такие как
.htm
весна даст приоритет для расширения. В шаге 2 я добавил contentNegotiationManager фасоли, чтобы переопределить это.
вероятно, никто не прокручивает это далеко, но ни одно из вышеперечисленных решений не исправило это для меня, но делает все мои методы getter
public
сделал.Я оставил свой геттер видимость на пакет-private; Джексон решил, что он не может найти их и взорвался. (Используя
@JsonAutoDetect(getterVisibility=NON_PRIVATE)
только частично исправил.