无法返回正常序列化Json “Could not write JSON”

SpringSecurity UserDetails的坑

报错信息

**2020-01-08 15:59:12.282 WARN 18236 — [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: (was java.lang.NullPointerException); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: link.larva.common.Resp[“data”]->link.larva.security.entity.User[“authorities”])]
**

自己搜索,这个错误的情况有几种

  1. 无构造函数。
  2. Getter,setter方法问题。

经过排查,自认为都没问题。因为用了Lombok的注解生成getset,和默认构造函数。
报错信息的NPE也让人摸不着头脑

但是看到了报错的最后
【authorities】,恍然大悟。

我实现的方法如下:

@Override
  public Collection<? extends GrantedAuthority> getAuthorities() {
    return roles.stream().map(role -> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toList());
  }

方法内部返回的值,存在不确定性。有可能报空指针异常。就会发生碰到的这种错误。
解决方法如下:

  1. @JsonIgnore 方法上加@JsonIgnore注解,防止框架对这个get方法进行序列化。
  2. 或者,将UserDetails额外封装出来。【推荐】其实这种处理方式才是正统的处理方式。

因为看到别的大佬的教程,把数据库对应的实体User直接实现了UserDetails接口。在Security框架中,直接使用User对象,同时UserService也直接实现了UserDetailsService。个人认为,这种使用方式不符合规范。

数据库对应的实体类对象,不应该存在任何的业务逻辑。UserDetails接口却包含了Security的认证权限。合理的处理方式,应该是单独新建类,来包装UserDetails,以及UserDetailsService。对User的检索,也应该UserDetailsService通过User Service来实现。日常使用过程中,只使用User,在security框架封装用户权限时才使用UserDetails。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值