Google-GSON 的 Spring MVC 映射视图?
Posted
技术标签:
【中文标题】Google-GSON 的 Spring MVC 映射视图?【英文标题】:Spring MVC mapping view for Google-GSON? 【发布时间】:2011-04-14 19:41:28 【问题描述】:有谁知道Gson 是否有Spring MVC 映射视图?我正在寻找类似于org.springframework.web.servlet.view.json.MappingJacksonJsonView 的东西。
理想情况下,它将采用我的 ModelMap 并将其呈现为 JSON,尊重我在 ContentNegotiatingViewResolver 声明中设置的 renderAttributes
我们计划在应用程序中广泛使用 Gson,因为它看起来比 Jackson 更安全、更好。也就是说,我们需要有两个不同的 JSON 库才能执行原生 JSON 视图。
提前致谢!
[交叉发布到Spring forums]
【问题讨论】:
想详细说明“似乎更安全、更好”?如,以什么方式更好? (或者更安全,就此而言) +1,正是我想要的。 对于从 Spring boot 5.0 开始来到这里的任何人,请查看我的回答 force spring to use GSON, instead of Jackson 【参考方案1】:我建议像 MappingJacksonJsonView 一样扩展 AbstractView。
就个人而言,对于 JSON,我更喜欢使用 @Responsebody,并且只返回对象而不是模型和视图,这样更容易测试。如果您想为此使用 GSON,只需像这样创建一个自定义 HttpMessageConverter:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken;
import com.vitalimages.string.StringUtils;
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 org.springframework.stereotype.Component;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.sql.Timestamp;
@Component
public class GSONHttpMessageConverter extends AbstractHttpMessageConverter<Object>
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private GsonBuilder gsonBuilder = new GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
.registerTypeAdapter(Timestamp.class, new GSONTimestampConverter());
public GSONHttpMessageConverter()
super(new MediaType("application", "json", DEFAULT_CHARSET));
@Override
protected boolean supports(Class<?> clazz)
// should not be called, since we override canRead/Write instead
throw new UnsupportedOperationException();
@Override
public boolean canRead(Class<?> clazz, MediaType mediaType)
return MediaType.APPLICATION_JSON.isCompatibleWith(mediaType);
public boolean canWrite(Class<?> clazz, MediaType mediaType)
return MediaType.APPLICATION_JSON.isCompatibleWith(mediaType);
public void registerTypeAdapter(Type type, Object serializer)
gsonBuilder.registerTypeAdapter(type, serializer);
@Override
protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException
try
Gson gson = gsonBuilder.create();
return gson.fromJson(StringUtils.convertStreamToString(inputMessage.getBody()), clazz);
catch (JsonParseException e)
throw new HttpMessageNotReadableException("Could not read JSON: " + e.getMessage(), e);
@Override
protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException
Type genericType = TypeToken.get(o.getClass()).getType();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputMessage.getBody(), DEFAULT_CHARSET));
try
// See http://code.google.com/p/google-gson/issues/detail?id=199 for details on SQLTimestamp conversion
Gson gson = gsonBuilder.create();
writer.append(gson.toJson(o, genericType));
finally
writer.flush();
writer.close();
然后将其添加到处理程序适配器中的转换器列表中,如下所示:
@Bean
public HandlerAdapter handlerAdapter()
final AnnotationMethodHandlerAdapter handlerAdapter = new AnnotationMethodHandlerAdapter();
handlerAdapter.setAlwaysUseFullPath(true);
List<HttpMessageConverter<?>> converterList = new ArrayList<HttpMessageConverter<?>>();
converterList.addAll(Arrays.asList(handlerAdapter.getMessageConverters()));
converterList.add(jibxHttpMessageConverter);
converterList.add(gsonHttpMessageConverter);
handlerAdapter.setMessageConverters(converterList.toArray(new HttpMessageConverter<?>[converterList.size()]));
return handlerAdapter;
【讨论】:
你能对 bean 做同样的事情,但在applicationContext.xml
中吗?【参考方案2】:
aweigold 帮助我完成了大部分工作,但为了具体概述基于 Spring 3.1 Java 的配置的解决方案,这就是我所做的。
从spring-android-rest-template 项目中获取GsonHttpMessageConverter.java。
在您的 MVC 配置中使用消息转换器注册您的 GsonHttpMessageConverter
。
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters)
converters.add(new GsonHttpMessageConverter());
Spring 文档概述了这个过程,但并不十分清楚。为了让它正常工作,我不得不扩展WebMvcConfigurerAdapter
,然后覆盖configureMesageConverters
。完成此操作后,您应该能够在控制器方法中执行以下操作:
@Controller
public class AppController
@RequestMapping(value = "messages", produces = MediaType.APPLICATION_JSON_VALUE)
public List<Message> getMessages()
// .. Get list of messages
return messages;
瞧! JSON 输出。
【讨论】:
谢谢,这对我很有帮助!使用 Spring 3.2.2 和 jackson,我无法摆脱它说的问题:406 not accaptable。我这样做了,它奏效了,但我还必须将 添加到服务 xml 文件中。以上是关于Google-GSON 的 Spring MVC 映射视图?的主要内容,如果未能解决你的问题,请参考以下文章
Spring MVC学习笔记---Spring MVC 的HelloWorld
Spring MVC学习笔记---Spring MVC 的HelloWorld