it-roy-ru.com

Spring 3.0 делает JSON-ответ с использованием конвертера сообщений Джексона

тогда я настраиваю свой конвертер сообщений как Джексона

class Foo{int x; int y}

и в контроллере

@ResponseBody
public Foo method(){
   return new Foo(3,4)
}

из этого я ожидаю вернуть JSON-строку {x: '3', y: '4'} с сервера без какой-либо другой конфигурации. но получая 404 сообщения об ошибке на мой запрос ajax 

Если метод аннотирован @ResponseBody, возвращаемый тип записывается в тело ответа HTTP. Возвращаемое значение будет преобразовано в объявленный тип аргумента метода с использованием HttpMessageConverters.

Я ошибся ? или я должен преобразовать свой объект ответа в строку Json самостоятельно, используя сериализатор, а затем вернуть эту строку в качестве ответа (я мог бы правильно выполнить строковые ответы), или я должен сделать некоторые другие конфигурации? как добавление аннотаций для класса Foo 

вот мой conf.xml 

<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">

  <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
  <list>
    <ref bean="jacksonMessageConverter"/>
  </list>
</property>

23
dupdup

Вам нужно следующее:

  1. Задайте модель программирования на основе аннотаций: поместите <mvc:annotation-driven /> в spring.xml
  2. Поместите jaskson jar (Maven artifactId - org.codehaus.jackson:jackson-mapper-asl) в путь к классам.
  3. Используйте как следующее:

    @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST })
    public @ResponseBody Foo method(@Valid Request request, BindingResult result){
    return new Foo(3,4)
    }
    

Это работает для меня.

Обратите внимание, что 

  1. @ResponseBody применяется к типу возвращаемого значения, а не к определению метода.
  2. Вам нужна аннотация @RequestMapping, чтобы Spring ее обнаружил.
22
uthark

Интерфейс MessageConverter http://static.springsource.org/spring/docs/3.0.x/javadoc-api/ определяет метод getSupportedMediaTypes (), который в случае MappingJacksonMessageCoverter возвращает application/json

public MappingJacksonHttpMessageConverter() {
    super(new MediaType("application", "json", DEFAULT_CHARSET));
}

Я предполагаю, что заголовок запроса Accept: application/json отсутствует. 

3
Sven Haiges

Это сработало для меня:

@RequestMapping(value = "{p_LocationId}.json", method = RequestMethod.GET)
protected void getLocationAsJson(@PathVariable("p_LocationId") Integer p_LocationId,
     @RequestParam("cid") Integer p_CustomerId, HttpServletResponse response) {
        MappingJacksonHttpMessageConverter jsonConverter = 
                new MappingJacksonHttpMessageConverter();
        Location requestedLocation = new Location(p_LocationId);
        MediaType jsonMimeType = MediaType.APPLICATION_JSON;
        if (jsonConverter.canWrite(requestedLocation.getClass(), jsonMimeType)) {
        try {
            jsonConverter.write(requestedLocation, jsonMimeType,
                                   new ServletServerHttpResponse(response));
            } catch (IOException m_Ioe) {
                // TODO: announce this exception somehow
            } catch (HttpMessageNotWritableException p_Nwe) {
                // TODO: announce this exception somehow
            }
        }
}

Обратите внимание, что метод ничего не возвращает: MappingJacksonHttpMessageConverter#write() делает магию.

3
Boris Brudnoy

Ошибка HTTP 404 просто означает, что ресурс не может быть найден. Это может иметь 2 причины:

  1. Неверный URL запроса (ошибка на стороне клиента или неверный URL в данной ссылке/кнопке).
  2. Ресурс не там, где вы ожидаете (ошибка на стороне сервера).

Чтобы исправить 1, убедитесь, что вы используете или предоставляете правильный URL-адрес запроса (с учетом регистра!). Чтобы исправить 2, проверьте журналы запуска сервера на наличие ошибок запуска и исправьте их соответствующим образом.

Это все выходит за рамки того, как далеко размещены код и информация.

2
BalusC

Я обнаружил, что мне тоже нужен jackson-core-asl.jar, а не только jackson-mapper-asl.jar

1
ricor

В дополнение к ответам здесь ..

если вы используете jquery на стороне клиента, это работает для меня:

Джава:

@RequestMapping(value = "/ajax/search/sync") 
public ModelAndView sync(@RequestBody Foo json) {

Jquery (необходимо включить json2.js Дугласа Крокфорда, чтобы иметь функцию JSON.stringify):

$.ajax({
    type: "post",
    url: "sync", //your valid url
    contentType: "application/json", //this is required for spring 3 - ajax to work (at least for me)
    data: JSON.stringify(jsonobject), //json object or array of json objects
    success: function(result) {
        //do nothing
    },
    error: function(){
        alert('failure');
    }
});
0
rafael lean ansay

Это всего лишь предположение, но по умолчанию Джексон автоматически обнаруживает только открытые поля (и публичные геттеры; но все сеттеры независимо от видимости). Это можно настроить (с версией 1.5 ), чтобы также автоматически определять частные поля, если это необходимо (см. здесь для получения подробной информации).

0
StaxMan

Я думаю, что 404 не связан с вашим HttpMessageConverter. У меня была та же проблема 404, и причина была в том, что я забыл, что только запросы, соответствующие<url-pattern>, отправляются в DispatcherServlet (я изменил сопоставление запросов с * .do на * .json). Может быть, это ваш случай тоже.

0
Aleksey Otrubennikov