Spring 3.0, создающий ответ JSON с использованием конвертера сообщений Jackson

Я настраиваю свой messageconverter как Jackson, тогда

class Foo{int x; int y}

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

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

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

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

Неужели я ошибаюсь? или мне нужно преобразовать свой ответ Object в строку Json самостоятельно с помощью serializer и затем вернуть эту строку в качестве ответа. (Я мог бы корректно отвечать на строки) или мне нужно сделать некоторые другие конфигурации? например добавление аннотаций для класса 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>

Ответ 1

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

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

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

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

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

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

Ответ 2

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

@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

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

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

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

Ответ 4

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

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

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

Все это выходит за пределы размещенного кода и информации.

Ответ 5

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

Ответ 6

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

Ответ 7

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

Ответ 8

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

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

Java:

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

JQuery (вам нужно включить Douglas Crockford 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');
    }
});