问题说明

最近做了关于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序列化的更多相关文章

  1. JavaBean到JSon格式的转换例子的代码

    内容过程,把做工程过程较好的内容片段备份一次,如下的内容是关于 JavaBean到JSon格式的转换例子的内容,应该对各朋友有一些用处. User u = new User(); u.setId(1) ...

  2. javaBean转为json

    一个测试用例 javabean转json @Test @Rollback(false) public void policyQueryTest() throws Exception { // 查询数据 ...

  3. ASP.Net MVC 在ajax接收controller返回值为Json数据

    首先,再次回忆一下ajax的标准用法:(这张图写的比较详细了)(转) 页面部分ajax代码: $.ajax({            url: "/Home/Login?account=&q ...

  4. RestTemplate接收HashMap变为LinkedHashMap,RestTemplate接收数据后转成json数据出现反斜杠

    使用postForObject方法远程调用接口,正常会返回List<HashMap>,然而实际上却返回List<LinkedHashMap>,同时将此数据进行json转换,变成 ...

  5. fastJson javaBean和JSON对象相互转换

    fastjson的作用就是把java 对象转化为字符串,把字符串转化为java对象,然后方便进行后续的逻辑处理. java对象和json互相转换都是通过JSON对象操作的: JavaBean bean ...

  6. JavaBean和json数据之间的转换(二)含有date类型的JavaBean

    1.前言 上次讲了简单的JavaBean和json格式之间的转换,代码很简单,但是实际过程中,往往用到的JavaBean都是比较复杂的,其他的字段还好,如果JavaBean中包含了date类型的字段, ...

  7. JavaBean和json数据之间的转换(一)简单的JavaBean转换

    1.为什么要使用json? JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,因为其高性能.可读性强的原因,成为了现阶段web开发中前后端交互数据的主要数据 ...

  8. java后端无法接收到前端传递的json对象

    java后端无法接收到前端传递的json对象 一·可能是因为未使用@RequestBody 在Controller层中,要么使用@RestController要么使用@Controller+@@Req ...

  9. NetworkComms V3 使用Json序列化器进行网络通信

    刚才在网上闲逛,偶然看到一篇文章 C#(服务器)与Java(客户端)通过Socket传递对象 网址是:http://www.cnblogs.com/iyangyuan/archive/2012/12/ ...

随机推荐

  1. MyBatis 插件使用-简单的分页插件

    目录 1 分页参数的传递 2 实现 Interceptor 接口 2.1 Interceptor 接口说明 2.1 注解说明 2.3 实现分页接口 PageInterceptor 3. 更改配置 4 ...

  2. meta标签设置(移动端)

    一.首先出结论:移动端meta标签一般设置为: <meta content="width=device-width,initial-scale=1.0,maxinmum-scale=1 ...

  3. Android Adapter的一些记录

    一.摘要 An Adapter object acts as a bridge between an AdapterView and the underlying data for that view ...

  4. POJ 2431——Expedition(贪心,优先队列)

    链接:http://poj.org/problem?id=2431 题解 #include<iostream> #include<algorithm> #include< ...

  5. redis查找大key

    redis中查找出比较大的key 下面直接上代码 (请在测试机上测试) #!/usr/bin/env python import sys import redis def check_big_key( ...

  6. Spark 学习笔记之 map/flatMap/filter/mapPartitions/mapPartitionsWithIndex/sample

    map/flatMap/filter/mapPartitions/mapPartitionsWithIndex/sample:

  7. ELK 学习笔记之 Logstash之inputs配置

    Logstash之inputs配置: input plugin doc: https://www.elastic.co/guide/en/logstash/current/index.html 插件很 ...

  8. [TLSR8267] 泰凌微 telink tlsr8267 ble ADC 用法浅谈

    1.读 datasheet 在<DS_TLSR8267-E21_Datasheet for Telink BLE SoC TLSR8267.pdf>第11章详细介绍了ADC相关属性及参数. ...

  9. Redis对象——字符串

    文章导航-readme 前言     上一篇文章Redis之对象篇--Redis对象系统简介简单介绍了Redis的对象系统.Redis使用对象来表示数据库中的键和值每个对象都由一个redisObjec ...

  10. Node Sass could not find a binding for your current environment: OS X 64-bit with Node.js 10.x

    运行Reac项目报: Node Sass could not find a binding for your current environment: OS X 64-bit with Node.js ...