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

Java Spring中UserDetails实现类@JsonIgnore注解不生效问题求助

根本原因

你导入了错误的@JsonIgnore注解包:org.codehaus.jackson.annotate.JsonIgnore是Jackson 1.x版本的类,Spring Boot默认集成的序列化框架为Jackson 2.x,对应的注解包路径是com.fasterxml.jackson.annotation.JsonIgnore,你添加的注解没有被序列化框架识别,因此屏蔽密码字段的逻辑不生效。你之前使用@JsonProperty(access = Access.WRITE_ONLY)报错,大概率也是包导入错误导致的。

解决方案

方案1:修正注解配置(快速修复)

  1. 删除User类中旧版本Jackson的导入语句:import org.codehaus.jackson.annotate.JsonIgnore;
  2. 替换为Jackson 2.x的对应注解,推荐直接使用WRITE_ONLY权限配置,不需要分别给get/set方法加注解:
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import javax.persistence.*;
import java.util.Collection;
import java.util.List;

@Entity
@Table(name = "users")
public class User implements UserDetails {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    private String username;

    // 配置为只允许序列化时写入、反序列化(接口返回)时不输出
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private String password;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private List<Role> roles;

    public User() {}

    public User(String username, String password, List<Role> roles) {
        this.username = username;
        this.password = password;
        this.roles = roles;
    }

    // 不需要给get/set方法加额外Json注解
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    // 其余代码保持不变
}

如果你的项目中同时依赖了Jackson 1.x和2.x版本,需要在构建配置(pom.xml/build.gradle)中排除旧版本的Jackson依赖(如jackson-core-asl、jackson-mapper-asl),避免包冲突。

方案2:使用DTO做传输层隔离(工程实践推荐)

直接将数据库实体类返回给前端存在敏感字段泄露、字段结构耦合的风险,更稳妥的做法是单独定义数据传输对象(DTO),仅包含需要对外暴露的字段:

// 用户信息返回DTO,仅包含允许对外暴露的字段
public class UserDTO {
    private Integer id;
    private String username;
    // 省略getter、setter方法
}

// 博文信息返回DTO
public class PostDTO {
    private Integer id;
    private String title;
    private String body;
    private LocalDate date;
    private UserDTO creator;
    // 省略getter、setter方法
}

接口层查询到Post实体后,转换为PostDTO再返回即可,从结构上避免敏感字段泄露的可能性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 08:57:03