webflux项目如何用fastjson来解析请求参数

项目场景:

项目采用的是webflux框架,对于传入json格式的请求数据用fastjson来解析


问题描述:

假设实体是下面的结构:

@Data
public class Student {

    //姓名
    @JSONField(name = "Name")
    private String name;

    //性别
    @JSONField(name = "Gender")
    private String sex;

    //年龄
    @JSONField(name = "Age")
    private Integer age;


}

按照要求如果传入json请求数据格式如下:
{“Name”:“张三”,“Gender”:“male”,“Age”:“25”}
上面的实体按照fastJson对字段进行配置,但是实体并未映射到,后台结果如下

在这里插入图片描述


原因分析:

目前springboot webflux内置的消息解析器,还不支持fastJson,即使容器中配置fastJson也不行。


解决方案:

修改内置解析jackson的解析方式,让部分数据按照fastJson来解析,配置代码如下。

package com.zhoule.webflux.webflux_demo.config;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.ResolvableType;
import org.springframework.core.codec.DecodingException;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.http.codec.json.AbstractJackson2Decoder;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.util.MimeType;
import org.springframework.web.reactive.config.WebFluxConfigurer;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

/**
 * @author zhoule
 * @Description: config
 * @date 2022/1/7 14:39
 */
@Configuration
public class WebFluxConfig implements WebFluxConfigurer {


    private static FastJsonHttpMessageConverter fastJsonHttpMessageConverter;

    @Bean
    public HttpMessageConverters fastJsonHttpMessageConverters() {
        fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
        config.setSerializerFeatures(SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullStringAsEmpty);
        fastJsonHttpMessageConverter.setFastJsonConfig(config);
        HttpMessageConverter<?> converter = fastJsonHttpMessageConverter;
        return new HttpMessageConverters(converter);
    }

    private ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build();

    @Override
    public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
        //自定义解码器
        configurer.defaultCodecs().jackson2JsonDecoder(new CustomJsonDecoder(objectMapper));
        //自定义编码器 编码器的道理和解码器基本类似,可以自行尝试
        //configurer.defaultCodecs().jackson2JsonEncoder(null);
    }


    static class CustomJsonDecoder extends AbstractJackson2Decoder {

        public CustomJsonDecoder(ObjectMapper mapper, MimeType... mimeTypes) {
            super(mapper, mimeTypes);
        }

        @Override
        public Object decode(DataBuffer dataBuffer, ResolvableType targetType, MimeType mimeType, Map<String, Object> hints) throws DecodingException {
            Object read = null;
            boolean flag = false;
            try {
                //如果是json格式 以及是否是自己的业务包
                if (mimeType.toString().contains(MediaType.APPLICATION_JSON_VALUE) &&
                        targetType.getType().getTypeName().startsWith("com.zhoule")) {
                    read = fastJsonHttpMessageConverter.read(targetType.getType(), null, new CustomHttpInputMessage(dataBuffer.asInputStream()));
                } else {
                    //不是想转换的数据直接返回父类调用
                    return super.decode(dataBuffer, targetType, mimeType, hints);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (flag) {
                    DataBufferUtils.release(dataBuffer);
                }
            }
            return read;
        }
    }

    //定义一个fastJson相关的HttpInputMessage
    static class CustomHttpInputMessage implements HttpInputMessage {
        private InputStream inputStream;

        public CustomHttpInputMessage(InputStream inputStream) {
            this.inputStream = inputStream;
        }

        @Override
        public InputStream getBody() throws IOException {
            return inputStream;
        }

        @Override
        public HttpHeaders getHeaders() {
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.set("Content-Type", MediaType.APPLICATION_JSON_VALUE);
            return httpHeaders;
        }
    }
}

改完后的效果如下:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值