gpt4 book ai didi

json - 使用 @ResponseBody 自定义 HttpMessageConverter 来做 Json 事情

转载 作者:IT老高 更新时间:2023-10-28 12:49:22 28 4
gpt4 key购买 nike

我不喜欢 jackson 。

我想使用 ajax,但要使用 Google Gson。

所以我试图弄清楚如何实现我自己的 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 "";
}
}

}

然后我只好去掉annnotaion-driven标签,在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>

看到,为了使 FormaterValidator 工作,我们也必须构建一个自定义的 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);
}

}

有趣的是,为了使配置在没有 annotaion-driven 标签的情况下工作,我们必须手动配置一个 AnnotationMethodHandlerAdapter 和一个 DefaultAnnotationHandlerMapping。为了使 AnnotationMethodHandlerAdapter 能够处理格式化和验证,我们必须配置一个 validator、一个 conversionService 并构建一个自定义 em>webBindingInitializer.

我希望这一切对我以外的其他人有所帮助。

在我绝望的搜索中,this @Bozho 帖子非常有用。我也很感谢@GaryF,因为他的回答把我带到了@Bozho post。 .对于尝试在 Spring 3.1 中执行此操作的您,请参阅@Robby Pond 的答案。要容易得多,不是吗?

关于json - 使用 @ResponseBody 自定义 HttpMessageConverter 来做 Json 事情,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5019162/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com