通过FeignClient接收shaded的javabean的JSON序列化
问题说明
最近做了关于flink的需求.
现在需要通过HTTP访问FLINK的 RESTAPI, rest 接口的JSON 非常庞大而复杂。
那么怎么去完整的接收数据呢?
方法一就是手写部分需要的JavaBean,嵌套比较麻烦而复杂。照着json schema写,非常慢。
方法二直接通过jsonObject 接收,当作map 使用,虽然没有第一种方法的问题,但是看不见结构,对于java这种强类型语言,非常不友好。
方法三,直接使用FLINK的源码的类。
那么根据官方文档的 jsonschema 找到对应的实体类。以jobDetailInfo为例.
package org.apache.flink.runtime.rest.messages.job;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.annotation.JsonCreator;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.annotation.JsonIgnore;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.annotation.JsonRawValue;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.annotation.JsonSerialize;
public class JobDetailsInfo implements ResponseBody {
public static final String FIELD_NAME_JOB_ID = "jid";
@JsonProperty(FIELD_NAME_JOB_ID)
@JsonSerialize(using = JobIDSerializer.class)
private final JobID jobId;
@JsonProperty(FIELD_NAME_JOB_NAME)
private final String name;
//.....
}
问题思考
可以看到这里jobId的属性是 jid.
这里我是通过 spring的httpMessageConverter 接收,也就是需要 json序列化工具来处理。
如果是用fastjson序列化工具,那么fastjson 是无法处理jackson的注解的。
第二点,SpringBoot的框架内是带有 jackson的 消息转换器的,但是通过查看import的信息可以看出,这是无法正确处理这种shade的json。此时可以说和jackson毫无关系。
如果把flink的源码类直接复制出来,修改成正常的非shaded的包名下的jackson 是不是可以接收了呢。 一开始我是这么做的,但是实在是接口比较多,而且源码中依赖的类型比较多,一时半会是复制不完的。
最终解决方案
那么我们提供一个专门针对 shadedJackson的 httpMessageConvert不就可以了吗?
步骤一, 定义shaded jackson 的httpMessageConverter
写一个类 继承 Spring的 抽象类:
org.springframework.http.converter.AbstractGenericHttpMessageConverter
其他内容完全复制AbstractJackson2HttpMessageConverter 即可
public abstract class AbstractShadedJackson2HttpMessageConverter extends AbstractGenericHttpMessageConverter<Object> {
}
然后写一个实现类,其他内容依然是复制MappingJackson2HttpMessageConverter即可。
然后这里最重要的是将所有的import com.fasterxml.jackson 替换为import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.
这样就实现了JVM兼容.
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.core.JsonGenerator;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.lang.Nullable;
import java.io.IOException;
public class ShadedMappingJackson2HttpMessageConverter extends AbstractShadedJackson2HttpMessageConverter {
}
此处省略相关的jackson的类型,处理方式类似,都是替换包名。
最后注册到Spring 内大功告成。
@Configuration
public class FeignSupport {
@Bean
public ShadedMappingJackson2HttpMessageConverter httpMessageConverter() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
objectMapper.setDateFormat(new SimpleDateFormat());
return new ShadedMappingJackson2HttpMessageConverter(objectMapper);
}
}
写到这里不得不担心一下 消息转换器的顺序,万一被 fastjson接收了,可能就有很多字段不认识了.
这里可以查看 org.springframework.web.client.HttpMessageConverterExtractor#extractData 的断点,确认是在前面的。
我的另一篇文章提供的方法是将fastjson 注册到底部的。

这里再提供一个FeignClient接口:
/*
* @see org.apache.flink.runtime.rest.messages.job.JobDetailsInfo
*/
@GetMapping(value = "/v1/jobs/{jobid}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
JobDetailsInfo job(@PathVariable("jobid") String jobId, @RequestHeader(APP_ID_HEADER) String appId);
这样便可以接收。
思考
这里有必要条件:就是要保证刚刚提供的HttpMessageConverter 需要比较高的优先级。
为什么说HttpMessageConverter的顺序非常重要_SpringBoot 参考这篇文章
通过FeignClient接收shaded的javabean的JSON序列化的更多相关文章
- JavaBean到JSon格式的转换例子的代码
内容过程,把做工程过程较好的内容片段备份一次,如下的内容是关于 JavaBean到JSon格式的转换例子的内容,应该对各朋友有一些用处. User u = new User(); u.setId(1) ...
- javaBean转为json
一个测试用例 javabean转json @Test @Rollback(false) public void policyQueryTest() throws Exception { // 查询数据 ...
- ASP.Net MVC 在ajax接收controller返回值为Json数据
首先,再次回忆一下ajax的标准用法:(这张图写的比较详细了)(转) 页面部分ajax代码: $.ajax({ url: "/Home/Login?account=&q ...
- RestTemplate接收HashMap变为LinkedHashMap,RestTemplate接收数据后转成json数据出现反斜杠
使用postForObject方法远程调用接口,正常会返回List<HashMap>,然而实际上却返回List<LinkedHashMap>,同时将此数据进行json转换,变成 ...
- fastJson javaBean和JSON对象相互转换
fastjson的作用就是把java 对象转化为字符串,把字符串转化为java对象,然后方便进行后续的逻辑处理. java对象和json互相转换都是通过JSON对象操作的: JavaBean bean ...
- JavaBean和json数据之间的转换(二)含有date类型的JavaBean
1.前言 上次讲了简单的JavaBean和json格式之间的转换,代码很简单,但是实际过程中,往往用到的JavaBean都是比较复杂的,其他的字段还好,如果JavaBean中包含了date类型的字段, ...
- JavaBean和json数据之间的转换(一)简单的JavaBean转换
1.为什么要使用json? JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,因为其高性能.可读性强的原因,成为了现阶段web开发中前后端交互数据的主要数据 ...
- java后端无法接收到前端传递的json对象
java后端无法接收到前端传递的json对象 一·可能是因为未使用@RequestBody 在Controller层中,要么使用@RestController要么使用@Controller+@@Req ...
- NetworkComms V3 使用Json序列化器进行网络通信
刚才在网上闲逛,偶然看到一篇文章 C#(服务器)与Java(客户端)通过Socket传递对象 网址是:http://www.cnblogs.com/iyangyuan/archive/2012/12/ ...
随机推荐
- Hive安装与简单使用并集成SparkSQL
## Hive环境搭建1. hive下载:http://archive-primary.cloudera.com/cdh5/cdh/5/hive-1.1.0-cdh5.7.0.tar.gzwget h ...
- Cisco路由器基本使用
作者:小啊博 QQ:762641008 转载请声明URL:https://www.cnblogs.com/-bobo/ 一.路由器命令行使用 router> ...
- SpringCloudEureka入门
说明 SpringBoot版本 2.1.7.RELEASE SpringCloud版本 Greenwich.SR2 创建eureka server工程 加入pom依赖 <dependencies ...
- springboot结合mybatis使用pageHelper插件进行分页查询
1.pom相关依赖引入 <dependencies> <dependency> <groupId>org.springframework.boot</grou ...
- Linux 常用解压和压缩命令
.tar 解包 tar xvf filename.tar.tar 打包 tar cvf filename.tar dirname.gz 解压1 gunzip filename.gz.gz 解压2 gz ...
- 【爬虫小程序:爬取斗鱼所有房间信息】Xpath(多线程版)
# 本程序亲测有效,用于理解爬虫相关的基础知识,不足之处希望大家批评指正 from queue import Queue import requests from lxml import etree ...
- JQuery 数组按指定长度分组
JQuery方法 // 将data每3个一组进行分组 var data = ['法国','澳大利亚','智利','新西兰','西班牙','加拿大','阿根廷','美国','0','国产','波多黎各' ...
- 你竟然不装油猴插件-Chrome神器TamperMonkey
油猴插件是一款可以在chrome浏览器中使用油猴脚本的插件.理解为脚本运行的平台 脚本 是一段代码,安装之后,有些脚本能为网站添加新的功能,有些能使网站的界面更加易用,有些则能隐藏网站上烦人的部分内容 ...
- Java文件操作——File
创建File isFile().length().exists().createNewFile(). File.separator / isDirtory(). mkdir().mkdirs(). d ...
- MIPI CSI2-TX接口基于FPGA实现
MIPI CSI2-TX用途: 跟海思的3559A芯片进行图像数据传输: MIPI CSI2-TX接口特性: xilinx 7系列芯片最大支持1.25Gbps: 最大支持lanes数量为4: 支持的图 ...