Spring-MVC 406 неприемлем вместо ответа JSON - PullRequest
13 голосов
/ 19 сентября 2011

Я пытаюсь вернуть ответ JSON с Spring 3.0.6, но я получаю 406 ответ «Не приемлемо» с описанием: «Ресурс, идентифицированный этим запросом, способен генерировать ответы только с характеристиками не принимается в соответствии с запросом "accept" headers (). "

Я знаю, что очень похожий вопрос задавался ранее, но я не могу заставить его работать для моего проекта, несмотря на многие тесты и я не понимаю, что я делаю не так.

В моем Maven pom.xml я имею следующее:

<dependency>
  <groupId>org.codehaus.jackson</groupId>
  <artifactId>jackson-mapper-asl</artifactId>
  <version>1.8.5</version>
  <scope>compile</scope>
</dependency>
<dependency>
  <groupId>org.codehaus.jackson</groupId>
  <artifactId>jackson-core-asl</artifactId>
  <version>1.8.5</version>
  <scope>compile</scope>
</dependency>

В web.xml я ссылаюсь на webmvc-config.xml, и журнал подтверждает, что загружен.

<servlet>
    <servlet-name>mainServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/webmvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

В файле webmvc-config.xml есть следующее:

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/jsp/" />
            <property name="suffix" value=".jsp" />
    </bean> 
    <mvc:annotation-driven />

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

@Controller
public class ClassifiedController {

    @RequestMapping(value = "/classified/{idClassified}", headers = "Accept=*/*",
                    method = RequestMethod.GET)
    @ResponseBody
    public final Classified getClassified(@PathVariable final int idClassified) {
        ...

Я пытался с или без параметра заголовков с одинаковыми результатами. Если я позвоню URL непосредственно в Firefox заголовки запроса содержат следующее (проверено с помощью firebug):

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Если я использую следующий JQuery:

$.ajax({
        url: '/classified/38001',
        type: 'GET',
        dataType: 'json'
});

Отправляются следующие заголовки:

Accept: application/json, text/javascript, */*; q=0.01

В обоих случаях результатом является ошибка 406. Я не знаю, что еще я должен проверить, чтобы сделать это работает.


ОБНОВЛЕНИЕ : я решил выполнить отладку через Spring и обнаружил, что Джексон был вызван правильно, и в org.codehaus.jackson.map.ser.StdSerializerProvider метод _findExplicitUntypedSerializer содержит следующий код:

try {
    return _createAndCacheUntypedSerializer(runtimeType, property);
} catch (Exception e) {
    return null;
}

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

Conflicting getter definitions for property "reminded": 
ClassifiedImpl#isReminded(0 params) vs
ClassifiedImpl#getReminded(0 params)

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

Ответы [ 5 ]

7 голосов
/ 11 мая 2015

Я наткнулся на ту же ошибку (406: содержимое не приемлемо) с аннотацией Spring MVC и @RestController.

Обработчик Spring:

@RequestMapping(value = "/stuff-acknowledgment/{id}", produces ="application/json;charset=UTF-8", headers="Accept=*")
public Message acknowledgeStuff(@PathVariable("id") String id, @ModelAttribute("ack") AckBean acquittement) {

Наблюдение:

  • URI имеет вид: http://www.host.com/stuff-acknowledgment/{id}
  • НО $id имеет очень специфический формат: xxxcomplicatedhashxxx.png (или любое другое расширение, которое вы можете придумать).

Следовательно:

Spring MVC интерпретирует расширение и хочет получить результат того же типа MIME (даже если я определю его как переменную пути), здесь тип MIME "image/png", даже если я скажу ему создать JSON. Таким образом, выдается исключение 406.

Исправлено:

Удалите расширение ".png" в URI, или удалите PathVariable и поместите его в тело, или добавьте суффикс после pathVariable (не проверено, но также должно работать), суть в том, чтобы избежать расширения файла в конец URI.

PS: я знаю, что это не отвечает на конкретную проблему (с решением в обновлении) в вопросе, но я обнаружил, что ТАКОЙ поток при поиске этой проблемы, и выложил здесь свое исправление для записи, надеясь, что это поможет кто-то в будущем.

7 голосов
/ 11 сентября 2013

Добавьте следующее в DispatcherServlet-servlet.xml.

<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
        <list>
            <ref bean="jacksonMessageConverter"/>
        </list>
    </property>
</bean>
6 голосов
/ 19 сентября 2011

С точки зрения обработки MappingJacksonJson вам необходимо убедиться, что Jackson ObjectMapper поддерживает ваш тип объекта для сериализации.

4 голосов
/ 26 ноября 2014

Я столкнулся с этой проблемой, потому что объекты, которые я хотел вернуть как JSON, не имели методов получения для своих свойств. Джексон, вероятно, нуждается в этом. После добавления их это сработало.

2 голосов
/ 11 сентября 2013

хотя этот поток немного старый ...

вам нужно добавить следующее (зависимость maven):

org.codehaus.jacksonjackson-mapper-asl1.9.13

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...