文档章节

springboot加载自定义MessageConverter

呵呵3547
 呵呵3547
发布于 2016/07/20 13:02
字数 481
阅读 267
收藏 2

想通过fastjson解析springmvc返回的自定义数据类型

  1. 实现类AbstractHttpMessageConverter
public class ResultMessageConverter extends AbstractHttpMessageConverter<ResultInfo> {   
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
	private Logger logger = LoggerFactory.getLogger(ResultMessageConverter.class);
	public ResultMessageConverter() {
		super(new MediaType("text", "html", DEFAULT_CHARSET), new MediaType("application", "json", DEFAULT_CHARSET));
	}
	@Override
	public boolean canRead(Class<?> clazz, MediaType mediaType) {
		return false;
	}
	@Override
	public boolean canWrite(Class<?> clazz, MediaType mediaType) {
		return true;
	}
	@Override
	protected boolean supports(Class<?> clazz) {
		return Response.class.isAssignableFrom(clazz);
	}
	@Override
	protected ResultInfo readInternal(Class<? extends ResultInfo> clazz, HttpInputMessage inputMessage)
			throws IOException, HttpMessageNotReadableException {
		String requestData = StreamUtils.copyToString(inputMessage.getBody(), DEFAULT_CHARSET);
		System.out.print(requestData);
		return null;
	}
	@Override
	protected void writeInternal(ResultInfo resultInfo, HttpOutputMessage outputMessage)
			throws IOException, HttpMessageNotWritableException {
		HttpServletRequest httpRequest = getHttpRequest();
		Holder holder = (Holder)httpRequest.getAttribute(Holder.Key.HOLDER.getKey());
		Response response = toResponse(resultInfo, holder);
		String jsondata = DataUtils.response2json(response);
		LogUtils.info(jsondata, logger);
		//String newjson = URLEncoder.encode(jsondata, "UTF-8");
		outputMessage.getHeaders().setContentType(new MediaType("application", "json", DEFAULT_CHARSET));
		StreamUtils.copy(jsondata, DEFAULT_CHARSET, outputMessage.getBody());
        //outputMessage.getBody().write(jsondata.getBytes());
	}
	private Response toResponse(ResultInfo resultInfo, Holder holder) {
		if (holder != null) {
			return Response.Builder.create(holder.getValue(Holder.Key.TRANCEID), resultInfo);
		}
		return Response.Builder.create(UUID.randomUUID().toString(), resultInfo);
	}
	private HttpServletRequest getHttpRequest() {
		return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
	}
  1. 注册到springboot注册的messageConverter中
@Configuration
public class BaseMVCConfiguration extends WebMvcConfigurerAdapter {

    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        for (HttpMessageConverter<?> messageConverter : converters) {
            System.out.println("message converter " + messageConverter); //2
        }
    }

    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        ResultMessageConverter resultConverter = new ResultMessageConverter();
        converters.add(0, resultConverter);
        for (HttpMessageConverter<?> messageConverter : converters) {
            System.out.println("message converter " + messageConverter); //2
        }
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new BaseInterceptor());
        super.addInterceptors(registry);
    }
}

. 注册MessageConverter时需要注册converters.add(0, resultConverter) 因为springboot会默认加载jackson进行解析json,springboot是按顺序查询的.如果是用converters.add(resultConverter)自定义的Messageconverter是在jackson之后.可能会先使用jackson进行解析

. 另一种方法是在maven依赖包中去除jackson的依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
	<exclusions>
		<exclusion>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
		</exclusion>
	</exclusions>
</dependency>

查看springboot源码类WebMvcConfigurationSupport中方法addDefaultHttpMessageConverters时

protected final void addDefaultHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
		StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
		stringConverter.setWriteAcceptCharset(false);

		messageConverters.add(new ByteArrayHttpMessageConverter());
		messageConverters.add(stringConverter);
		messageConverters.add(new ResourceHttpMessageConverter());
		messageConverters.add(new SourceHttpMessageConverter<Source>());
		messageConverters.add(new AllEncompassingFormHttpMessageConverter());

		if (romePresent) {
			messageConverters.add(new AtomFeedHttpMessageConverter());
			messageConverters.add(new RssChannelHttpMessageConverter());
		}

		if (jackson2XmlPresent) {
			ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.xml().applicationContext(this.applicationContext).build();
			messageConverters.add(new MappingJackson2XmlHttpMessageConverter(objectMapper));
		}
		else if (jaxb2Present) {
			messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
		}

		if (jackson2Present) {
			ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().applicationContext(this.applicationContext).build();
			messageConverters.add(new MappingJackson2HttpMessageConverter(objectMapper));
		}
		else if (gsonPresent) {
			messageConverters.add(new GsonHttpMessageConverter());
		}
	}

变量的声明如下

private static final boolean jaxb2Present =
			ClassUtils.isPresent("javax.xml.bind.Binder", WebMvcConfigurationSupport.class.getClassLoader());

private static final boolean jackson2Present =
			ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", WebMvcConfigurationSupport.class.getClassLoader()) &&
					ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", WebMvcConfigurationSupport.class.getClassLoader());

private static final boolean jackson2XmlPresent =
			ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", WebMvcConfigurationSupport.class.getClassLoader());

private static final boolean gsonPresent =
			ClassUtils.isPresent("com.google.gson.Gson", WebMvcConfigurationSupport.class.getClassLoader());

© 著作权归作者所有

共有 人打赏支持
呵呵3547
粉丝 1
博文 5
码字总数 1461
作品 0
昌平
程序员
私信 提问
【SpringBoot专题】快速体验

前言 在Spring 4推出来之前,我们的编码是存在一些问题,比如:大量的xml配置存在项目中,配置相当繁琐;整合第三方框架非常麻烦;开发效率和部署效率不高等问题。正是因为这些问题,Spring开...

张丰哲
08/05
0
0
恒宇少年/spring-boot-chapter

简书整套文档以及源码解析 专题 专题名称 专题描述 001 Spring Boot 核心技术 讲解SpringBoot一些企业级层面的核心组件 002 Spring Cloud 核心技术 对Spring Cloud核心技术全面讲解 003 Quer...

恒宇少年
04/19
0
0
Spring Boot干货系列: (三)启动原理解析

     前言   前面几章我们见识了SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说,如果不大懂SpringBoot内部启动原理,以后难免会吃亏。所以这次博主就跟你们一起一步步...

后端编程嘟
2017/03/13
0
0
007SpringBoot之配置文件加载的优先级以及位置

一、基础 1、定义 之前我们的文件都放到了下,然后SpringBoot项目启动后会自动读取并加载,那么这个文件放在哪呢?只能放到下吗?不是。 2、位置以及优先级 SpringBoot启动后会扫描以下位置的...

编程界的小学生
05/28
0
0
springboot 是如何帮我们省去web.xml配置的

概述 最开始使用原生的springmvc时,总是免不了有如下xml配置 但是,切换到springboot之后,web.xml之类的繁琐的配置基本上都不见了。出于好奇研究了下springboot究竟帮我们做了什么,我们可...

端吉
06/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

ConcurrentHashMap 高并发性的实现机制

ConcurrentHashMap 的结构分析 为了更好的理解 ConcurrentHashMap 高并发的具体实现,让我们先探索它的结构模型。 ConcurrentHashMap 类中包含两个静态内部类 HashEntry 和 Segment。HashEnt...

TonyStarkSir
今天
3
0
大数据教程(7.4)HDFS的java客户端API(流处理方式)

博主上一篇博客分享了namenode和datanode的工作原理,本章节将继前面的HDFS的java客户端简单API后深度讲述HDFS流处理API。 场景:博主前面的文章介绍过HDFS上存的大文件会成不同的块存储在不...

em_aaron
昨天
2
0
聊聊storm的window trigger

序 本文主要研究一下storm的window trigger WindowTridentProcessor.prepare storm-core-1.2.2-sources.jar!/org/apache/storm/trident/windowing/WindowTridentProcessor.java public v......

go4it
昨天
6
0
CentOS 生产环境配置

初始配置 对于一般配置来说,不需要安装 epel-release 仓库,本文主要在于希望跟随 RHEL 的配置流程,紧跟红帽公司对于服务器的配置说明。 # yum update 安装 centos-release-scl # yum ins...

clin003
昨天
9
0
GPON网络故障处理手册

导读 为了方便广大网络工作者工作需要,特搜集以下GPON网络处理流程供大家学习参考。开始—初步定为故障—检查光纤状况—检查ONU状态--检查设备运行状态—检查设备数据配置—检查上层设备状态...

问题终结者
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部