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 ответов
Вам нужно следующее:
- Установить модель программирования на основе аннотаций: положить
<mvc:annotation-driven />
вspring.xml
- Поместите jaskson jar (Maven artifactId является
org.codehaus.jackson:jackson-mapper-asl
) в classpath. Используйте как следующее:
@RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }) public @ResponseBody Foo method(@Valid Request request, BindingResult result){ return new Foo(3,4) }
Это работает для меня.
Обратите внимание, что
@ResponseBody
применяется к типу возвращаемого значения, а не к определению метода.- Тебе нужно
@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 причины:
- Неверный URL запроса (ошибка на стороне клиента или неверный URL в данной ссылке / кнопке).
- Ресурс не там, где вы ожидаете (ошибка на стороне сервера).
Чтобы исправить 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). Может быть, это ваш случай тоже.