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>

8 ответов

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

  1. Установить модель программирования на основе аннотаций: положить <mvc:annotation-driven /> в spring.xml
  2. Поместите jaskson jar (Maven artifactId является org.codehaus.jackson:jackson-mapper-asl) в classpath.
  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 обнаружит это.

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

@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() делает магию.

Интерфейс 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 отсутствует.

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

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

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

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

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

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

если вы используете 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');
    }
});

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

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

Другие вопросы по тегам