我不喜欢 jackson 。
我想与Google Gson一起使用Ajax。
因此,我试图弄清楚如何实现自己的HttpMessageConverter以便与@ResponseBody批注一起使用。
有人可以花点时间告诉我我应该走的路吗?我应该打开什么配置?
我也想知道我是否可以这样做并且仍然使用?
提前致谢。
我已经在3天前的Spring Community Foruns中问过了,但没有答案,所以我在这里问我是否有更好的机会。
Spring Community Forums link to my question
我还在网络上进行了详尽的搜索,发现了一些与此主题有关的有趣内容,但似乎他们正在考虑将其放在Spring 3.1中,而我仍在使用spring 3.0.5:
Jira's Spring Improvement ask
好吧...现在,我正在尝试调试Spring代码以了解如何执行此操作,但是我遇到了一些问题,例如我在这里所说的:
Spring Framework Build Error
如果还有其他方法可以解决,但我想念它,请告诉我。
最佳答案
好吧...很难找到答案,我不得不遵循很多线索来查找不完整的信息,因此我认为在此处发布完整的答案会很好。因此,下一个搜索将更容易。
首先,我必须实现自定义HttpMessageConverter:package net.iogui.web.spring.converter;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.Reader;import java.io.StringWriter;import java.io.Writer;import java.nio.charset.Charset;import org.springframework.http.HttpInputMessage;import org.springframework.http.HttpOutputMessage;import org.springframework.http.MediaType;import org.springframework.http.converter.AbstractHttpMessageConverter;import org.springframework.http.converter.HttpMessageNotReadableException;import org.springframework.http.converter.HttpMessageNotWritableException;import com.google.gson.Gson;import com.google.gson.JsonSyntaxException;public class GsonHttpMessageConverter extends AbstractHttpMessageConverter<Object> { private Gson gson = new Gson(); public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); public GsonHttpMessageConverter(){ super(new MediaType("application", "json", DEFAULT_CHARSET)); } @Override protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { try{ return gson.fromJson(convertStreamToString(inputMessage.getBody()), clazz); }catch(JsonSyntaxException e){ throw new HttpMessageNotReadableException("Could not read JSON: " + e.getMessage(), e); } } @Override protected boolean supports(Class<?> clazz) { return true; } @Override protected void writeInternal(Object t, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { //TODO: adapt this to be able to receive a list of json objects too String json = gson.toJson(t); outputMessage.getBody().write(json.getBytes()); } //TODO: move this to a more appropriated utils class public String convertStreamToString(InputStream is) throws IOException { /* * To convert the InputStream to String we use the Reader.read(char[] * buffer) method. We iterate until the Reader return -1 which means * there's no more data to read. We use the StringWriter class to * produce the string. */ if (is != null) { Writer writer = new StringWriter(); char[] buffer = new char[1024]; try { Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); int n; while ((n = reader.read(buffer)) != -1) { writer.write(buffer, 0, n); } } finally { is.close(); } return writer.toString(); } else { return ""; } }}
然后,我不得不剥离annantotaion驱动的标签,并亲自在spring-mvc配置文件上进行所有配置:<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- Configures the @Controller programming model --> <!-- To use just with a JSR-303 provider in the classpath <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" /> --> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" /> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="webBindingInitializer"> <bean class="net.iogui.web.spring.util.CommonWebBindingInitializer" /> </property> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" /> <bean class="org.springframework.http.converter.StringHttpMessageConverter" /> <bean class="org.springframework.http.converter.ResourceHttpMessageConverter" /> <bean class="net.iogui.web.spring.converter.GsonHttpMessageConverter" /> <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter" /> <bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter" /> <!-- bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter" /--> </list> </property> </bean> <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /> <context:component-scan base-package="net.iogui.teste.web.controller"/> <!-- Forwards requests to the "/" resource to the "login" view --> <mvc:view-controller path="/" view-name="home"/> <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources/ directory --> <mvc:resources mapping="/resources/**" location="/resources/" /> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/view/"/> <property name="suffix" value=".jsp"/> </bean></beans>
看到,要使Formater和Validator正常工作,我们还必须构建一个自定义的webBindingInitializer:package net.iogui.web.spring.util;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.core.convert.ConversionService;import org.springframework.validation.Validator;import org.springframework.web.bind.WebDataBinder;import org.springframework.web.bind.support.WebBindingInitializer;import org.springframework.web.context.request.WebRequest;public class CommonWebBindingInitializer implements WebBindingInitializer { @Autowired(required=false) private Validator validator; @Autowired private ConversionService conversionService; @Override public void initBinder(WebDataBinder binder, WebRequest request) { binder.setValidator(validator); binder.setConversionService(conversionService); }}
有趣的事情是,为了使配置在没有注释驱动标签的情况下工作,我们必须手动配置AnnotationMethodHandlerAdapter和DefaultAnnotationHandlerMapping。为了使AnnotationMethodHandlerAdapter能够处理格式和验证,我们必须配置一个验证器,一个conversionService并构建一个自定义的webBindingInitializer。
我希望所有这些都能对我以外的人有所帮助。
在我的绝望搜索中,this @Bozho帖子非常有用。我也感谢@GaryF,因为他的回答将我带到了@Bozho post。
对于正在Spring 3.1中尝试执行此操作的用户,请参见@Robby Pond答案。。要容易得多,不是吗?
关于json - 使用@ResponseBody自定义HttpMessageConverter来做Json的事情,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5019162/