欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > 关于Blade框架对数字类型的null值转为-1问题

关于Blade框架对数字类型的null值转为-1问题

2025/4/16 8:25:06 来源:https://blog.csdn.net/H_Q_Li/article/details/147243189  浏览:    关键词:关于Blade框架对数字类型的null值转为-1问题

关于Blade框架对数字类型的null值转为-1问题

问题:最近项目遇到了一个问题,SpringBoot项目后端Long类型的数据,如果是NULL的话,返回给前端的时候是-1。如下图:
在这里插入图片描述

分析

是由于使用了 blade 框架,项目启动的时候会执行MessageConfiguration类的代码:

MappingApiJackson2HttpMessageConverter这个类会执行:
在这里插入图片描述
BladeBeanSerializerModifier类对于 Number 类型会执行下面:

在这里插入图片描述
在这里插入图片描述
可以看到设置为 -1了。

解决办法

从上面我们可以看出主要是由于BladeBeanSerializerModifier类里面的方法,如果 Number 类型就会 NUMBER_JSON_SERIALIZER ,这个里面设为了 -1,那么我们只需要修改这里为 我们想返回的值就好。
但是这是源码,我们不能直接修改,所以就要"围魏救赵"。我们可以采用下面的方法

1、添加三个类:

  • MessageConfiguration :

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springblade.core.tool.jackson.BladeJacksonProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.List;@Configuration
@Order(value = (Integer.MIN_VALUE + 1))
public class MessageConfiguration implements WebMvcConfigurer {private final ObjectMapper objectMapper;private final BladeJacksonProperties properties;public MessageConfiguration(final ObjectMapper objectMapper, final BladeJacksonProperties properties) {this.objectMapper = objectMapper;this.properties = properties;}public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {converters.removeIf((x) -> {return x instanceof AbstractJackson2HttpMessageConverter;});converters.add(new MappingApiJackson2HttpMessageConverter(this.objectMapper, this.properties));}
}

注意:Order 设置为 Integer.MIN_VALUE + 1,让我们写的这个类的 configureMessageConverters 方法,执行顺序在 原本MessageConfiguration类的configureMessageConverters方法之后,在我们的方法移出他们框架的MappingApiJackson2HttpMessageConverter,添加我们自己的 MappingApiJackson2HttpMessageConverter 类(后面代码有提供)。

  • MappingApiJackson2HttpMessageConverter :
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;import org.springblade.core.tool.jackson.AbstractReadWriteJackson2HttpMessageConverter;
import org.springblade.core.tool.jackson.BladeJacksonProperties;
import org.springblade.core.tool.jackson.BladeNumberModule;
import org.springblade.core.tool.utils.Charsets;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.StreamUtils;public class MappingApiJackson2HttpMessageConverter extends AbstractReadWriteJackson2HttpMessageConverter {@Nullableprivate String jsonPrefix;public MappingApiJackson2HttpMessageConverter(ObjectMapper objectMapper, BladeJacksonProperties properties) {super(objectMapper, initWriteObjectMapper(objectMapper, properties), initMediaType(properties));}private static List<MediaType> initMediaType(BladeJacksonProperties properties) {List<MediaType> supportedMediaTypes = new ArrayList();supportedMediaTypes.add(MediaType.APPLICATION_JSON);supportedMediaTypes.add(new MediaType("application", "*+json"));if (Boolean.TRUE.equals(properties.getSupportTextPlain())) {supportedMediaTypes.add(MediaType.TEXT_PLAIN);}return supportedMediaTypes;}private static ObjectMapper initWriteObjectMapper(ObjectMapper readObjectMapper, BladeJacksonProperties properties) {ObjectMapper writeObjectMapper = readObjectMapper.copy();if (Boolean.TRUE.equals(properties.getBigNumToString())) {writeObjectMapper.registerModules(new Module[]{BladeNumberModule.INSTANCE});}if (Boolean.TRUE.equals(properties.getNullToEmpty())) {writeObjectMapper.setSerializerFactory(writeObjectMapper.getSerializerFactory().withSerializerModifier(new BladeBeanSerializerModifier()));writeObjectMapper.getSerializerProvider().setNullValueSerializer(BladeBeanSerializerModifier.NullJsonSerializers.STRING_JSON_SERIALIZER);}return writeObjectMapper;}protected void writeInternal(@NonNull Object object, @Nullable Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {if (object instanceof String) {Charset defaultCharset = this.getDefaultCharset();Charset charset = defaultCharset == null ? Charsets.UTF_8 : defaultCharset;StreamUtils.copy((String)object, charset, outputMessage.getBody());} else {super.writeInternal(object, type, outputMessage);}}public void setJsonPrefix(@Nullable String jsonPrefix) {this.jsonPrefix = jsonPrefix;}public void setPrefixJson(boolean prefixJson) {this.jsonPrefix = prefixJson ? ")]}', " : null;}protected void writePrefix(@NonNull JsonGenerator generator, @NonNull Object object) throws IOException {if (this.jsonPrefix != null) {generator.writeRaw(this.jsonPrefix);}}
}
  • BladeBeanSerializerModifier:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
/import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;import java.io.IOException;
import java.time.OffsetDateTime;
import java.time.temporal.TemporalAccessor;
import java.util.Collection;
import java.util.Date;
import java.util.List;public class BladeBeanSerializerModifier extends BeanSerializerModifier {public BladeBeanSerializerModifier() {}public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {beanProperties.forEach((writer) -> {if (!writer.hasNullSerializer()) {JavaType type = writer.getType();Class<?> clazz = type.getRawClass();if (type.isTypeOrSubTypeOf(Number.class)) {writer.assignNullSerializer(BladeBeanSerializerModifier.NullJsonSerializers.NUMBER_JSON_SERIALIZER);} else if (type.isTypeOrSubTypeOf(Boolean.class)) {writer.assignNullSerializer(BladeBeanSerializerModifier.NullJsonSerializers.BOOLEAN_JSON_SERIALIZER);} else if (type.isTypeOrSubTypeOf(Character.class)) {writer.assignNullSerializer(BladeBeanSerializerModifier.NullJsonSerializers.STRING_JSON_SERIALIZER);} else if (type.isTypeOrSubTypeOf(String.class)) {writer.assignNullSerializer(BladeBeanSerializerModifier.NullJsonSerializers.STRING_JSON_SERIALIZER);} else if (!type.isArrayType() && !clazz.isArray() && !type.isTypeOrSubTypeOf(Collection.class)) {if (type.isTypeOrSubTypeOf(OffsetDateTime.class)) {writer.assignNullSerializer(BladeBeanSerializerModifier.NullJsonSerializers.STRING_JSON_SERIALIZER);} else if (!type.isTypeOrSubTypeOf(Date.class) && !type.isTypeOrSubTypeOf(TemporalAccessor.class)) {writer.assignNullSerializer(BladeBeanSerializerModifier.NullJsonSerializers.OBJECT_JSON_SERIALIZER);} else {writer.assignNullSerializer(BladeBeanSerializerModifier.NullJsonSerializers.STRING_JSON_SERIALIZER);}} else {writer.assignNullSerializer(BladeBeanSerializerModifier.NullJsonSerializers.ARRAY_JSON_SERIALIZER);}}});return super.changeProperties(config, beanDesc, beanProperties);}public interface NullJsonSerializers {JsonSerializer<Object> STRING_JSON_SERIALIZER = new JsonSerializer<Object>() {public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {// 这里是关键:你要是想返回 NULL,这样写:gen.writeNull()// 返回空字符串按照下面写:gen.writeString("");}};JsonSerializer<Object> NUMBER_JSON_SERIALIZER = new JsonSerializer<Object>() {public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {gen.writeString("");}};JsonSerializer<Object> BOOLEAN_JSON_SERIALIZER = new JsonSerializer<Object>() {public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {gen.writeObject(Boolean.FALSE);}};JsonSerializer<Object> ARRAY_JSON_SERIALIZER = new JsonSerializer<Object>() {public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {gen.writeStartArray();gen.writeEndArray();}};JsonSerializer<Object> OBJECT_JSON_SERIALIZER = new JsonSerializer<Object>() {public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {gen.writeStartObject();gen.writeEndObject();}};}
}

注意:上面三个类导入的都是我们重写的类,不要导入 blade 框架原有的了哦~。

测试

启动项目,进行测试:
在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词