避坑!OpenFeign+FastJson带签名访问出现Json格式问题

  • 前提场景:使用OpenFeign访问一个外部接口,访问时需要将请求体的参数序列化为字符串然后加密等生成sign放到请求头中。

  • 现象:访问时出现签名验证失败;

  • 分析:其实请求体和在签名中的请求参数是一样的,但是在生成签名时我使用的fastjson,而OpenFeign默认的序列化器是Jackson。虽然从外部结果上看来序列化结果都一样,但是如果放在postman中测试,就会发现:在这里插入图片描述
    在这里插入图片描述
    两者字符串相同,但是格式化后的请求体参数访问失败,而未格式化的请求体访问成功

  • 原因:在生成签名时使用的fastjson的Json.toJsonString(),他默认是不会格式化json字符串的,所以当服务拿到sign时解析发现是未格式化的json字符串,而请求体是OpenFeign使用Jackson格式化的json,所以两者对比失败,就请求失败。
    而使用postman测试时,请求体是未格式化的json,sign当中也是未格式化的json,所以可以请求成功。

  • 解决方式:在代码中,在sign生成过程中和OpenFeign访问时使用相同的序列化和格式化方式可以保证请求成功。因为我的项目都是用的FastJson作为序列化器,所以把请求体参数用于生成sign时,使用JSON.toJSONString(param, JSONWriter.Feature.PrettyFormat, JSONWriter.Feature.NotWriteEmptyArray)格式化,并且修改了feign接口默认的序列化器

 @Bean
    public Encoder feignEncoder() {
        return new SpringEncoder(feignHttpMessageConverter());
    }

    private ObjectFactory feignHttpMessageConverter() {
        HttpMessageConverters httpMessageConverters = new HttpMessageConverters(getFastJsonConverter());
        return () -> httpMessageConverters;
    }

    private FastJsonHttpMessageConverter getFastJsonConverter() {
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        // -------------------设置MediaType   没有这里会报错 Content-type 通配符问题
        List<MediaType> supportedMediaTypes = new ArrayList<>();
        supportedMediaTypes.add(MediaType.APPLICATION_JSON);
        supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
        supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
        supportedMediaTypes.add(MediaType.APPLICATION_PDF);
        supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_XML);
        supportedMediaTypes.add(MediaType.IMAGE_GIF);
        supportedMediaTypes.add(MediaType.IMAGE_JPEG);
        supportedMediaTypes.add(MediaType.IMAGE_PNG);
        supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM);
        supportedMediaTypes.add(MediaType.TEXT_HTML);
        supportedMediaTypes.add(MediaType.TEXT_MARKDOWN);
        supportedMediaTypes.add(MediaType.TEXT_PLAIN);
        supportedMediaTypes.add(MediaType.TEXT_XML);
        fastJsonHttpMessageConverter.setSupportedMediaTypes(supportedMediaTypes);
        //修改配置返回内容的过滤
        FastJsonConfig config = new FastJsonConfig();
        config.setDateFormat("yyyy-MM-dd HH:mm:ss");
        config.setReaderFeatures(JSONReader.Feature.FieldBased, JSONReader.Feature.SupportArrayToBean);
        config.setWriterFeatures(JSONWriter.Feature.PrettyFormat, JSONWriter.Feature.NotWriteEmptyArray);
        fastJsonHttpMessageConverter.setFastJsonConfig(config);
        return fastJsonHttpMessageConverter;

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值