Jackson序列化json时null转成空对象或空串

博客介绍了在Java项目中,当遇到将对象转JSON时不希望出现null的情况,可添加JacksonConfig配置解决。还对关键代码进行分析,如objectMapper.configure的作用,以及注解@ConditionalOnMissingBean的功能和使用场景,避免多个配置同时注入。

在项目中可能会遇到null,转JSON时不希望出现null,可以添加下面的配置解决这个问题。

一、添加JacksonConfig 配置

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.io.IOException;

@Configuration
public class JacksonConfig {

    @Bean
    @Primary
    @ConditionalOnMissingBean(ObjectMapper.class)
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        // 关键代码-解决No serializer found for class java.lang.Object异常
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
            @Override
            public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
                //jsonGenerator.writeString("");//空串
                jsonGenerator.writeObject(new Object());//空对象
            }
        });
        return objectMapper;
    }

}

二、注意

1关键代码分析

objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)

代码的作用是解决下面的异常

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.lang.Object and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: cloudpc.datasource.common.response.Result["data"])

2 @ConditionalOnMissingBean

它是修饰bean的一个注解,主要实现的是,当你的bean被注册之后,如果而注册相同类型的bean,就不会成功,它会保证你的bean只有一个,即你的实例只有一个,当你注册多个相同的bean时,会出现异常,以此来告诉开发人员。

一般来说,对于自定义的配置类,我们应该加上@ConditionalOnMissingBean注解,以避免多个配置同时注入的风险。

三、参考

https://blog.youkuaiyun.com/sdyy321/article/details/40298081

https://www.cnblogs.com/long88-club/p/11361174.html

https://segmentfault.com/a/1190000008287502

http://www.cppcns.com/ruanjian/java/333889.html

<think>我们正在讨论的是在将Java对象换为JSON字符串,如何将对象中的null字段换为字符串("")而不是null。 根据引用[4]的内容,我们可以通过配置Jackson的ObjectMapper来实现:当序列化遇到null值,将其序列化字符串。 具体做法是自定义一个JsonSerializer来处理null值,然后在ObjectMapper中注册这个序列化器。 以下是具体的步骤: 步骤1:创建一个配置类(例如在Spring Boot项目中),定义一个ObjectMapper Bean,并设置null值的序列化器。 步骤2:在null序列化器中,覆盖serialize方法,当遇到null,写入字符串。 引用[4]中提供了这样的配置代码: ```java @Configuration public class JacksonConfig { @Bean @Primary @ConditionalOnMissingBean(ObjectMapper.class) public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) { ObjectMapper objectMapper = builder.createXmlMapper(false).build(); objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() { @Override public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeString(""); } }); return objectMapper; } } ``` 这段代码的作用是:当ObjectMapper序列化一个对象,如果遇到属性值为null,就会调用这个自定义的序列化器,将null写为字符串。 注意:这个配置是针对整个ObjectMapper的,所以所有通过这个ObjectMapper序列化对象都会应用这个规则。 如果你不是在Spring Boot环境中,也可以直接创建一个ObjectMapper实例并进行配置: ```java ObjectMapper objectMapper = new ObjectMapper(); objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() { @Override public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeString(""); } }); ``` 然后使用这个objectMapper来序列化对象。 示例: 假设有一个User对象: ```java public class User { private String name; private Integer age; // 省略getter和setter } ``` 创建一个User实例,其中name为null: ```java User user = new User(); user.setName(null); user.setAge(30); ``` 使用配置好的ObjectMapper序列化: ```java String json = objectMapper.writeValueAsString(user); ``` 输出结果将是: ```json {"name":"","age":30} ``` 注意:这里name字段原本是null,被换成了字符串。 但是,这种方法会将所有类型的null值都序列化字符串。例如,一个Integer类型的字段为null,也会被写成空字符串(即`""`),这可能不是我们期望的(因为数字字段我们希望可能是0者不出现,但是字符串不是有效的数字)。因此,这种方法适用于所有需要将null换为字符串的场景,但要注意数据类型。 如果你希望只对字符串类型的null字段换为字符串,而对其他类型(如数字、布尔等)的null字段进行不同的处理(比如忽略、换为0等),那么你需要更精细的控制。这,你可以通过为特定类型注册序列化器来实现,者使用注解。 不过,根据用户的需求,他要求的是“若对象字段为则将其设置为空串”,这里没有区分类型,所以上述方法可以满足。 总结:通过配置Jackson的ObjectMapper,设置一个全局的NullValueSerializer,在序列化null值替换为字符串。 相关问题: 1. 如何仅在字符串类型字段为null换为字符串,而其他类型保持原样? 2. Jackson中如何忽略值为null的字段? 3. 使用Jackson注解如何定制特定字段的null值行为? </think>在将对象换为JSON字符串,若字段值为null需要换为字符串(""),可以通过以下两种方法实现。以下是详细步骤和示例: --- ### 方法1:全局配置Jackson(推荐) 在Spring Boot项目中配置全局`ObjectMapper`,自动将null转为字符串: ```java @Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); // 设置null序列化字符串 mapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() { @Override public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeString(""); // 所有null转为字符串 } }); return mapper; } } ``` **效果**: ```java User user = new User(null, 25, null); String json = objectMapper.writeValueAsString(user); // 输出: {"name":"","age":25,"gender":""} ``` --- ### 方法2:使用注解定制字段 通过`@JsonInclude`和`@JsonSerialize`注解单独控制字段: ```java public class User { @JsonSerialize(nullsUsing = NullAsEmptyStringSerializer.class) private String name; private Integer age; @JsonInclude(JsonInclude.Include.NON_NULL) // 直接忽略null字段 private String gender; // Getter/Setter省略 } // 自定义null序列化器 public class NullAsEmptyStringSerializer extends JsonSerializer<Object> { @Override public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException { gen.writeString(""); } } ``` **效果**: ```java User user = new User(null, 25, null); String json = objectMapper.writeValueAsString(user); // 输出: {"name":"","age":25} (gender被忽略) ``` --- ### 关键说明 1. **数据类型影响**: - 字符串字段:`null → ""` (符合需求) - 数字字段:`null → ""` (可能导致类型错误) - 推荐只对字符串类型使用此换[^4] 2. **注意事项**: ```mermaid graph LR A[对象字段] -->|值为null| B{处理方式} B --> C[全局配置""] B --> D[注解忽略字段] B --> E[注解定制""] C --> F[所有类型生效] D --> G[字段不出现] E --> H[仅指定字段生效] ``` 3. **数据库对比**: - 数据库字段设为`NOT NULL`,插入字符串是被允许的(如MySQL)[^3] - Oracle中`NOT NULL`字段不允许插入字符串[^2] - JSON序列化不受数据库约束影响 --- ### 应用场景对比 | 场景 | 全局配置 | 注解定制 | |---------------------|----------|----------| | 所有字符串字段"" | ✓ | ✗ | | 特定字段"" | ✗ | ✓ | | 完全忽略null字段 | ✗ | ✓ | | 处理非字符串字段 | 可能出错 | 安全 | > **最佳实践**:对关键字符串字段使用`@JsonSerialize(nullsUsing=...)`注解,避免全局配置影响数字/布尔类型。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值