SpringBoot ResponseBody返回值处理

1. SpringBoot ResponseBody 返回值中null值处理

@PostMapping(path = "/test", produces = MediaType.APPLICATION_JSON_VALUE)
public Object test() {
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("test","test");
		jsonObject.put("testnull",null);
		ApiResponseVo apiResponseVo = new ApiResponseVo();
		apiResponseVo.setData(jsonObject );
		apiResponseVo.setStatus(0);
		return apiResponseVo;
}
接口返回 (想实现将testnull也进行返回) : 
{
    "data": {
        "test": "test"
    },
    "status": 0
}
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
@Configuration
public class fastJsonConfig extends WebMvcConfigurationSupport {
	@Override
	public void configureMessageConverters(List> converters) {
		FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
		FastJsonConfig config = new FastJsonConfig();
		config.setSerializerFeatures(
				// 保留 Map 空的字段
				SerializerFeature.WriteMapNullValue,
				// 将 String 类型的 null 转成""
//                SerializerFeature.WriteNullStringAsEmpty,
                // 将 Number 类型的 null 转成 0
//                SerializerFeature.WriteNullNumberAsZero,
                // 将 List 类型的 null 转成 []
//                SerializerFeature.WriteNullListAsEmpty,
                // 将 Boolean 类型的 null 转成 false
//                SerializerFeature.WriteNullBooleanAsFalse,
				// 避免循环引用
				SerializerFeature.DisableCircularReferenceDetect
		);
		converter.setFastJsonConfig(config);
		converter.setDefaultCharset(Charset.forName("UTF-8"));
		List mediaTypeList = new ArrayList<>();
		// 解决中文乱码问题,相当于在 Controller 上的 @RequestMapping 中加了个属性 produces = "application/json"
		mediaTypeList.add(MediaType.APPLICATION_JSON);
		converter.setSupportedMediaTypes(mediaTypeList);
		converters.add(converter);
	}
}

2. 拦截responsebody转json,对数据进行二次处理 (字典转换做案例)

2.1> 设置拦截器

import java.nio.charset.StandardCharsets;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.fintell.dp3.manager.interceptor.LogInterceptor;
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 自定义拦截器,添加拦截路径和排除拦截路径
		registry.addInterceptor(getLogInterceptor()).addPathPatterns("/**");
	}
	@Bean
	public LogInterceptor getLogInterceptor() {
		return new LogInterceptor();
	}
	/**
	 * 修改StringHttpMessageConverter默认配置 & Json 默认序列化方式 (改这个方法)
	 */
	@Override
	public void configureMessageConverters(List> converters) {
	    //创建fastJson消息转换器
	    FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
	    //创建配置类
	    FastJsonConfig fastJsonConfig = new FastJsonConfig();
	    //修改配置返回内容的过滤
	    fastJsonConfig.setSerializerFeatures(
	            SerializerFeature.DisableCircularReferenceDetect,
	            SerializerFeature.WriteMapNullValue,
	            SerializerFeature.WriteNullStringAsEmpty
	    );
	    fastConverter.setFastJsonConfig(fastJsonConfig);
	    //将fastjson添加到视图消息转换器列表内
	    converters.add(fastConverter);
	}
}

2.2> 字典注解类

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Dict {
	String type(); 
}

2.3> 序列化类

import java.io.IOException;
import java.lang.reflect.Field;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Configuration;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Configuration
public class DictJsonSerializer extends JsonSerializer {
	@Override
    public void serialize(Object dictVal, JsonGenerator generator, SerializerProvider provider) throws IOException {
    	ObjectMapper objectMapper = new ObjectMapper();
        String currentName = generator.getOutputContext().getCurrentName();
        try {
            // 1> 获取字段
            Field field = generator.getCurrentValue().getClass().getDeclaredField(currentName);
            // 2> 获取字典注解
            Dict dict = field.getDeclaredAnnotation(Dict.class);
            // 3> 判断是否添加了字典注解
            if(dict == null) {
            	objectMapper.writeValue(generator, dictVal);
            	return;
            }
            // 4> 获取注解的type值
            String type = dict.type();
            // **************** 以下依据实际业务处理即可  ********************
            // 5> 获取到字段的值
            String val = dictVal == null ? "" : dictVal.toString();
            String dictValName = "";
            if(!StringUtils.isEmpty(val)) {
                // 6> 这里可以依据type做不同的处理逻辑
            	dictValName = "通过自己的方法,依据val获取到对应的字典值";
            }
            // 7> 将字段改写为{"code":"code","name":"name"}格式
            objectMapper.writeValue(generator, BaseEnum.builder().code(dictVal).name(dictValName.toString()).build());
        } catch (NoSuchFieldException e) {
        	log.error(e);
        }
    }
}
 
  

2.4> 字典注解使用

@SuppressWarnings("serial")
@Builder
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class BizRuleDto implements Serializable{
    // 指定使用哪种序列化
    @JsonSerialize(using = DictJsonSerializer.class)
    // 指定字典 (将被转换为{"code":"content","name":"contentname"}格式)
    @Dict(type = "content")
	private String content;
}

3. 其它补充 (从容器中获取某个实例) : 如 DictJsonSerializer 需要通过service查询数据库获取字典

@Slf4j
public class DictJsonSerializer extends JsonSerializer {
    // service
	private static ProductProxy productProxy;
	static {
		productProxy = SpringUtils.getBean(ProductProxy.class);
	}
    @Override
    public void serialize(Object dictVal, JsonGenerator generator, SerializerProvider provider) throws IOException {
    }
}
 
  

SpringUtils

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringUtils implements ApplicationContextAware {
	private static ApplicationContext ctx;
	/**
	 * 获取bean
	 */
	@SuppressWarnings("unchecked")
	public static  T getBean(String id) {
		return (T) ctx.getBean(id);
	}
	/**
	 * 按类型获取bean
	 */
	public static  T getBean(Class clazz) {
		return ctx.getBean(clazz);
	}
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		ctx = applicationContext;
	}
}

你可能感兴趣的:(后端,java)