使用@ResponseBody自定义HttpMessageConverter做Json的事情

使用@ResponseBody自定义HttpMessageConverter做Json的事情,第1张

使用@ResponseBody自定义HttpMessageConverter做Json的事情

好吧…很难找到答案,我不得不遵循很多线索来查找不完整的信息,因此我认为在此处发布完整的答案会很好。因此,下一个搜索将更容易。

首先,我必须实现自定义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 {                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"  />    -->    <bean id="conversionService"  />    <bean >        <property name="webBindingInitializer"> <bean  />        </property>        <property name="messageConverters"> <list>     <bean  />     <bean  />     <bean  />     <bean  />     <bean  />     <bean  />     <!-- bean  /--> </list>        </property>    </bean>    <bean id="handlerMapping"  />    <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" >        <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。



欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/4985832.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-11-14
下一篇2022-11-14

发表评论

登录后才能评论

评论列表(0条)

    保存