You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jackson反序列化User类报无构造器错误,加@JsonProperty仍无效如何解决

问题根本原因

  1. Jackson无法识别你User类的全参数构造器作为反序列化入口,@AllArgsConstructor默认生成的构造器没有Jackson的@JsonCreator注解,无法被反序列化逻辑识别
  2. 入参JSON字段和User类字段的@JsonProperty配置不匹配:入参里的given_name对应你类里的firstName、family_name对应lastName,当前注解配置的字段名完全不匹配
  3. Instant类型字段的反序列化需要额外的JSR310模块支持,默认ObjectMapper没有注册该模块
  4. 你的fromJson方法没有处理异常,也没有正确返回Optional值
  5. toJson方法存在笔误,lastName错误赋值为firstName的值

分步解决方案

1. 修复User类的构造器和字段映射配置

两种可选方案,推荐用第一种lombok原生配置:

方案A:lombok注解配置(不需要手动写构造器)

修改User类的注解,给全参构造器加@JsonCreator,同时修正字段的JsonProperty和入参匹配:

@Document(collection = "user")
@Builder
@AllArgsConstructor(onConstructor_ = @JsonCreator) // 关键配置:让lombok生成的构造器带@JsonCreator注解
public class User {

    @Indexed(unique = true)
    @JsonProperty("email")
    public final String email;

    @JsonProperty("password")
    public final String password;

    @JsonProperty("given_name") // 和入参JSON的given_name对应
    public final String firstName;

    @JsonProperty("family_name") // 和入参JSON的family_name对应
    public final String lastName;

    @JsonProperty("gender")
    public final Gender gender;

    // 注册时间后端生成,不需要前端传,加@JsonIgnore避免反序列化报错
    @JsonIgnore
    public final Instant registrationTime;

    public static User createUser(
            String email,
            String password,
            String firstName,
            String lastName,
            Gender gender,
            Instant registrationTime){
        return new User(email, password, firstName, lastName, gender, registrationTime);
    }
}

方案B:手动写构造器(不用lombok配置)

如果不想改lombok注解,可以手动写带@JsonCreator的全参构造器:

@JsonCreator
public User(
    @JsonProperty("email") String email,
    @JsonProperty("password") String password,
    @JsonProperty("given_name") String firstName,
    @JsonProperty("family_name") String lastName,
    @JsonProperty("gender") Gender gender
){
    this.email = email;
    this.password = password;
    this.firstName = firstName;
    this.lastName = lastName;
    this.gender = gender;
    this.registrationTime = Instant.now(); // 直接在构造器里生成注册时间
}

2. 配置ObjectMapper支持JSR310时间类型

首先引入JSR310模块依赖(Maven为例):

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

修改ObjectMapper的Bean配置,注册时间模块:

@Bean
ObjectMapper getObjectMapper(){
    return new ObjectMapper()
        .registerModule(new JavaTimeModule())
        .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}

3. 修复UserMapper的代码

修正fromJson方法:

public Optional<User> fromJson(ObjectNode jsonUser) {
    try {
        User user = objectMapper.treeToValue(jsonUser, User.class);
        // 如果用方案A的注解,需要手动补全注册时间
        User fullUser = User.createUser(user.email, user.password, user.firstName, user.lastName, user.gender, Instant.now());
        return Optional.of(fullUser);
    } catch (JsonProcessingException e) {
        // 反序列化失败返回空Optional
        return Optional.empty();
    }
}

修正toJson方法的笔误,同时移除敏感字段密码:

public JsonNode toJson(User user) {
    ObjectNode node = objectMapper.createObjectNode();
    node.put("email", user.email);
    // 不要把密码返回给前端,删除密码输出逻辑
    node.put("firstName", user.firstName);
    node.put("lastName", user.lastName); // 修正之前的笔误,原为user.firstName
    node.put("gender", user.gender.value);
    node.put("registrationTime", user.registrationTime.toString());
    return node;
}

4. 可选:枚举类适配

如果你的Gender枚举反序列化报错,给枚举的value字段加@JsonValue注解即可:

public enum Gender {
    FEMALE("FEMALE"),
    MALE("MALE");

    @JsonValue
    public final String value;
    // 省略构造器
}

内容的提问来源于stack exchange,提问作者user9347049

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 20:45:04