SpringCloud Feign Jackson自定义配置方式

目录
  • FeignJackson自定义配置
    • 出现的问题
    • 解决思路
    • 解决方法
  • Feign自定义配置应用
    • 环境
    • 自定义Feign的配置
    • Feign中记录日志
    • 测试Feign自定义的配置
    • 查看日志

Feign Jackson自定义配置

Spring Cloud Feign 默认支持Spring MVC的注解 使用相同的HttpMessageConverters类转换

官方文档说明:

Spring Cloud adds support for Spring MVC annotations and for using the same HttpMessageConverters used by default in Spring Web.

但是我们一般在返回给前端JSON格式的时候 都会把相应的 NULL值转为相应的"",这使得Spring Cloud Feign也使用相同的Jackson配置,例如我们项目的配置

    @Bean
    public ObjectMapper jacksonObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        // objectMapper.setSerializationInclusion(Include.NON_NULL);
        objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
            @Override
            public void serialize(Object value, JsonGenerator jg, SerializerProvider sp)
                throws IOException, JsonProcessingException {
                jg.writeString("");
                sp.getDefaultNullKeySerializer();
            }
        });
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        return objectMapper;
    }

出现的问题

在服务通过Feign进行请求的时候,传NULL值引用类型值时,会出现类型转换异常,由于HttpMessageConverters直接把NULL转为了""。

解决思路

自定义配置 Spring Cloud Feign Encoder与Decoder

官方文档说明:

Spring Cloud Netflix provides the following beans by default for feign (BeanType beanName: ClassName):Decoder feignDecoder: ResponseEntityDecoder (which wraps a SpringDecoder)Encoder feignEncoder: SpringEncoderLogger feignLogger: Slf4jLoggerContract feignContract: SpringMvcContractFeign.Builder feignBuilder: HystrixFeign.BuilderClient feignClient: if Ribbon is enabled it is a LoadBalancerFeignClient, otherwise the default feign client is used.

解决方法

统一配置Feign 的Encoder和Decoder的Jackson转换方式

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import feign.codec.Decoder;
import feign.codec.Encoder;
@Configuration
public class CustomFeignConfig {
    @Bean
    public Decoder feignDecoder() {
        HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(customObjectMapper());
        ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(jacksonConverter);
        return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
    }
    @Bean
    public Encoder feignEncoder(){
        HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(customObjectMapper());
        ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(jacksonConverter);
        return new SpringEncoder(objectFactory);
    }
    public ObjectMapper customObjectMapper(){
        ObjectMapper objectMapper = new ObjectMapper();
        //Customize as much as you want
        objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
        return objectMapper;
    }
}

如果配置DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT 不起作用可以试试这种方式

public ObjectMapper customObjectMapper(){
        ObjectMapper objectMapper = new ObjectMapper();
        //Customize as much as you want
        objectMapper.registerModule(new StringSanitizerModule());
        return objectMapper;
}
public class StringSanitizerModule extends SimpleModule {
    public StringSanitizerModule() {
        addDeserializer(String.class, new StdScalarDeserializer<String>(String.class) {
            @Override
            public String deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException {
               return StringUtils.trimToNull(jsonParser.getValueAsString());
            }
        });
    }
}

Feign自定义配置应用

环境

nacos: 1.3.1

启动nacos

cd /usr/local/nacos/bin

sh startup.sh -m standalone

自定义Feign的配置

1)添加依赖

加入nacos-discovery发现服务的依赖、web、actuator用于监控检查,添加openfeign依赖才能使用Feign功能

2)修改配置文件

配置nacos注册中心地址,因为不提供服务,所以不需要再注册中心注册因此register-enabled=false

3)添加Feign支持

配置FeignConfiguration类文件

Spring Cloud Netflix默认的SpringMvcController将替换为feign.Contract.Default

用feign.Contract.Default将契约改为Feign原生的默认契约,就可以使用feign自带的注解了

4)自定义Feign接口

Feign接口文件需和启动类再同一包目录下,使用@FeignClient注解配置所需要调用服务,此处nacos-provider是需要在注册中心提供服务

因为上面配置了feign.Contract.Deafault,所以在接口中可以使用Feign原生的注解@RequestLine

添加HelloController类文件

此处使用接口MyFeignClient调用hello方法获取到nacos-provider客户端提供的服务

Feign中记录日志

1)添加配置项

在配置文件中添加记录日志的包,* 而每个FeignClient都需要单独配置,它只能响应debug级别的日志

2)设置日志等级

在FeignConfiguration类文件中配置日志等级

日志等级:

  • NONE:不记录(默认)
  • BASIC:只记录请求方法、URL、响应状态码和执行时间
  • HEADERS:记录基本信息,请求和响应标题
  • FULL: 记录请求和响应标题、正文和行数据

测试Feign自定义的配置

启动nacos-provider、feign-config客户端,进入nacos查询nacos-provider服务是否注册

进入浏览器端键入地址http://localhost:2334/hello,就能访问到nacos-provider提供的服务内容

查看日志

控制台会输出如下信息

[MyFeignClient#hello] <— HTTP/1.1 200 (405ms)
2020-08-13 16:16:23.021 DEBUG 3680 — [nio-2334-exec-1] com.kk.feign.MyFeignClient : [MyFeignClient#hello] content-length: 16
2020-08-13 16:16:23.021 DEBUG 3680 — [nio-2334-exec-1] com.kk.feign.MyFeignClient : [MyFeignClient#hello] content-type: text/plain;charset=UTF-8
2020-08-13 16:16:23.021 DEBUG 3680 — [nio-2334-exec-1] com.kk.feign.MyFeignClient : [MyFeignClient#hello] date: Thu, 13 Aug 2020 08:16:23 GMT
2020-08-13 16:16:23.021 DEBUG 3680 — [nio-2334-exec-1] com.kk.feign.MyFeignClient : [MyFeignClient#hello]
2020-08-13 16:16:23.021 DEBUG 3680 — [nio-2334-exec-1] com.kk.feign.MyFeignClient : [MyFeignClient#hello] Hello Gateway A!
2020-08-13 16:16:23.021 DEBUG 3680 — [nio-2334-exec-1] com.kk.feign.MyFeignClient : [MyFeignClient#hello] <— END HTTP (16-byte body)

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 详解Spring Cloud Feign 熔断配置的一些小坑

    1.在使用feign做服务调用时,使用继承的方式调用服务,加入Hystrix的熔断处理fallback配置时,会报错,已解决. 2.使用feign默认配置,熔断不生效,已解决. 最近在做微服务的学习,发现在使用feign做服务调用时,使用继承的方式调用服务,加入Hystrix的熔断处理fallback配置时,会报错,代码如下: @RequestMapping("/demo/api") public interface HelloApi { @GetMapping("user/

  • Spring Cloud Feign组成配置过程解析

    Feign的组成 接口 作用 默认值 Feign.Builder Feign的入口 Feign.Builder Client Feign底层用什么去请求 和Ribbon配合时:LoadBalancerFeignClient 不和Ribbon配合时:Fgien.Client.Default Contract 契约,注解支持 SpringMVCContract Encoder 解码器,用于将独享转换成HTTP请求消息体 SpringEncoder Decoder 编码器,将相应消息体转成对象 Res

  • Spring Cloud Feign 自定义配置(重试、拦截与错误码处理) 代码实践

    基于 spring-boot-starter-parent 2.1.9.RELEASE, spring-cloud-openfeign 2.1.3.RELEASE 引子 Feign 是一个声明式.模板化的HTTP客户端,简化了系统发起Http请求.创建它时,只需要创建一个接口,然后加上FeignClient注解,使用它时,就像调用本地方法一样,作为开发者的我们完全感知不到这是在调用远程的方法,也感知不到背后发起了HTTP请求: /** * @author axin * @suammry xx 客

  • SpringCloud Feign Jackson自定义配置方式

    目录 FeignJackson自定义配置 出现的问题 解决思路 解决方法 Feign自定义配置应用 环境 自定义Feign的配置 Feign中记录日志 测试Feign自定义的配置 查看日志 Feign Jackson自定义配置 Spring Cloud Feign 默认支持Spring MVC的注解 使用相同的HttpMessageConverters类转换 官方文档说明: Spring Cloud adds support for Spring MVC annotations and for

  • SpringCloud Feign服务调用请求方式总结

    前言 最近做微服务架构的项目,在用feign来进行服务间的调用.在互调的过程中,难免出现问题,根据错误总结了一下,主要是请求方式的错误和接参数的错误造成的.在此进行一下总结记录.以下通过分为三种情况说明,无参数,单参数,多参数.每种情况再分get和post两种请求方式进行说明.这样的话,6种情况涵盖了feign调用的所有情况. 有个建议就是为了保证不必要的麻烦,在写feign接口的时候,与我们的映射方法保持绝对一致,同时请求方式,请求参数注解也都不偷懒的写上.如果遵循这种规范,可以避开90%的调

  • SpringCloud Feign客户端使用流程

    目录 一.HTTP客户端Feign 1.1RestTemplate方式调用存在的问题 1.2Feign的介绍 1.3Feign的使用 1.4自定义Feign的配置 1.5Feign性能优化 1.6Feign的最佳实践 一.HTTP客户端Feign 1.1RestTemplate方式调用存在的问题 以前我用使用RestTemplate发起远程调用的代码: String url = "http://userservice/user/" + order.getUserId(); User u

  • SpringCloud Feign高级配置详解

    目录 1.Feign对负载均衡的支持 2.Feign对熔断器的支持 3.Feign对请求压缩和响应压缩的支持 4.Feign的日志级别配置 1.Feign对负载均衡的支持 Feign 本身已经集成了Ribbon依赖和自动配置,因此我们不需要额外引入依赖,可以通过 ribbon.xx 来进行全局配置,也可以通过服务名.ribbon.xx 来对指定服务进行细节配置配置(参考之前,此处略) Feign默认的请求处理超时时长1s,有时候我们的业务确实执行的需要一定时间,那么这个时候,我们就需要调整请求处

  • SpringCloud Feign配置应用详细介绍

    目录 前言 1.Feign简介 2.Feign配置应用 前言 服务消费者调用服务提供者的时候使用RestTemplate技术 存在不便之处: 拼接url restTmplate.getForObJect 这两处代码都比较模板化,能不能不让我我们来写这种模板化的东西,另外来说,拼接url非常的low,拼接字符串,拼接参数,很low还容易出错 1.Feign简介 Feign是Netflix开发的一个轻量级RESTful的HTTP服务客户端(用它来发起请求,远程调用的),是以Java接口注解的方式调用

  • Spring Cloud超详细i讲解Feign自定义配置与使用

    目录 日志配置 Basic 认证配置 超时时间配置 客户端组件配置 GZIP压缩配置 继承特性 多参数请求构造 日志配置 有时候我们遇到 Bug,比如接口调用失败.参数没收到等 问题,或者想看看调用性能,就需要配置 Feign 的日志了, 以此让 Feign 把请求信息输出来. 首先定义一个配置类,代码如下所示. package com.by.config; import feign.Logger; import org.springframework.context.annotation.Be

  • Nginx自定义访问日志的配置方式

    前言 Nginx日志主要分为两种:访问日志和错误日志.日志开关在Nginx配置文件(/etc/nginx/nginx.conf)中设置,两种日志都可以选择性关闭,默认都是打开的. 访问日志主要记录客户端访问Nginx的每一个请求,格式可以自定义.通过访问日志,你可以得到用户地域来源.跳转来源.使用终端.某个URL访问量等相关信息. 日志的重要性不言而喻,一般来说我们开发过程中会为每个项目定义自己的日志格式以及存储路径. 就我们普通的JAVAWEB项目来说,重要的日志一般输出并存放在Tomcat的

  • django的403/404/500错误自定义页面的配置方式

    要实现标题的功能,总共分四步: 1.创建html错误页 2.配置settings 3.编写视图 4.配置url 我的开发环境: django1.10.3 python2.7.12 前期工作 创建项目及app $ django-admin.py startproject Test ... $ python manage.py startapp myapp ... 1.创建html错误页 在Test目录下,创建templates文件夹 在文件夹下创建404.html/403.html/500.htm

  • Spring-cloud Config Server的3种配置方式

    目录 Spring-cloud Config Server的3种配置 1.config 默认Git加载 2.加载本地开发环境 3.加载 本地物理环境 4.加载svn环境 springcloud统一配置中心(config server 端) 1.为什么要使用统一配置中心? 2.登陆github 创建一个用于存放配置的项目 3.存放配置的项目的git地址 配置到项目的yml中 4.项目中的配置(Spring Cloud Config server 端) 5.再git上创建文件夹 用来存放配置信息 6

随机推荐