1.实体类实现了Userdetails接口,重写了几个方法,但是admin实体类没有
Collection<? extends GrantedAuthority>这个属性,json就不能反序列化这个获得角色的类
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("t_admin")
@ApiModel(value="Admin对象", description="")
public class Admin implements Serializable, UserDetails {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "id")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "姓名")
private String name;
@ApiModelProperty(value = "手机号码")
private String phone;
@ApiModelProperty(value = "住宅电话")
private String telephone;
@ApiModelProperty(value = "联系地址")
private String address;
@ApiModelProperty(value = "是否启用")
@Getter(AccessLevel.NONE)
private Boolean enabled;
@ApiModelProperty(value = "用户名")
private String username;
@ApiModelProperty(value = "密码")
private String password;
@ApiModelProperty(value = "用户头像")
private String userFace;
@ApiModelProperty(value = "备注")
private String remark;
@ApiModelProperty(value = "角色")
@TableField(exist = false)
private List<Role> roles;
@Override
@JsonDeserialize(using = CustomAuthorityDeserializer.class)
public Collection<? extends GrantedAuthority> getAuthorities() {
List<SimpleGrantedAuthority> authorities = roles
.stream()
.map(role -> new SimpleGrantedAuthority(role.getName()))
.collect(Collectors.toList());
return authorities;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return enabled;
}
}
2.场景:更新用户信息
这里从前端传入admin json对象,但是无法转换出Collection<? extends GrantedAuthority>类型的角色字段,所以必须使用自定义反序列化,转换出这个对象
@ApiOperation(value="更新当前用户信息")
@PutMapping("/admin/info")
public respBean updateAdmin(@RequestBody Admin admin,Authentication authentication){
if(adminService.updateById(admin)){
//将更新的对象使用security写到全局中去,表明当前的登录对象,以后可以使用principal 调用当前登录任
SecurityContextHolder.getContext().setAuthentication(new UserNamePasswordAuthenyicationToken(admin,null,authentication.getAuthorities));
return RespBean.success("更新成功");
}
}
3.编写反序列化类
public class CustomAuthorityDeserializer extends JsonDeserializer {
//json解析
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
ObjectMapper mapper = (ObjectMapper) p.getCodec();
JsonNode jsonNode = mapper.readTree(p);//读取json数据
List<GrantedAuthority> grantedAuthorities = new LinkedList<>();
Iterator<JsonNode> elements = jsonNode.elements();//
while (elements.hasNext()){
JsonNode next = elements.next();
JsonNode authority = next.get("authority");
grantedAuthorities.add(new SimpleGrantedAuthority(authority.asText()));
}
return grantedAuthorities;
}
}
4.在需要反序列化的类属性或方法上加上注释
@JsonDeserialize(using = CustomAuthorityDeserializer.class)