Весенний запрос 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 73

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 бросает a JsonMappingException с информативным сообщением. Однако это исключение проглатывается 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)

убедитесь, что у вас есть правильная версия Джексона в вашем classpath

проверьте, как @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. Затем я проверил RequestMappingHandlerAdapterMessageConverters и все 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) только частично исправил.

вы можете удалить элемент headers в @RequestMapping и попробовать..

Как


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

Я думаю, весна не содержит проверить, а не точное соответствие для заголовков accept. Но все же, стоит попробовать удалить элемент headers и проверить.