本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《
项目场景:
在进行在线使用
Spring Security
做为权限
框架
的办公系统的个人项目开发中,控制台输出的错误信息为
无法写入JSON
的错误,遇到
了这个比较让人摸不着头脑的问题,我想应该不局限于当前项目场景,将目前遇到这种错误的解决方法进行记录,如果以后再遇到相同的错误,有不同解决方法时再回来记录。
问题描述
要实现的功能是获取管理员列表,向后端传递的参数和数据库中想要查询的内容也可以正常的获取到,但是在将查询到的数据返回到前端时就出现了报错
Swagger调试的内容如下:
从控制台的截图可以看到数据库中的数据正常返回以及前端传递的参数正常接收
控制台报错如下:
Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: A granted authority textual representation is required; nested exception is com.fasterxml.jackson.databind.JsonMappingException: A granted authority textual representation is required (through reference chain: java.util.ArrayList[0]->net.csdn.server.pojo.Admin["authorities"])]
将问题进行翻译后可以知道内容为:
[org.springframework.http.converter.HttpMessageNotWritableException:无法写入 JSON:需要授予权限的文本表示; 嵌套异常是 com.fasterxml.jackson.databind.JsonMappingException:需要授予权限的文本表示(通过引用链:java.util.ArrayList[0]->net.csdn.server.pojo.Admin[“authorities”]) ]
原因分析:
出现了这种问题,首先可以在控制台中看到是
Admin
类中的某个字段需要授予权限,因此问题就在于
Admin
类中的字段上,首先能够想到考虑以下几点(
项目中引入了
lombok
, 同时
Admin
类实现了
UserDetails
接口
)
-
lombok
的
@Data
注解没有加上,导致某些字段没有
getter
以及
setter
方法
-
对于
Spring Security
中
UserDetails
的接口字段有一些是不需要返回给前端的
对应的
Admin
类代码如下:
package net.csdn.server.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
* @author zhangrongkang
* @since 2022-01-23
@Data
@EqualsAndHashCode(callSuper = false)
@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 = "是否启用")
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;
* 通过角色名获取到对应的权限
* @return 与角色名对应的权限集合
@Override
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;
}
可以看到在
Admin
类中是有
@Data
注解的,因此排除第一种可能的情况。对于第二种情况来说,发现重写的
getAuthorities
方法中返回的
authorities
与控制台中的报错字段一致,因此可以将问题缩小至前端不需要将
authorities
进行返回
解决方案:
在当前
Admin
类中的
getAuthorities
方法上
添加
@JsonIgnore
注解
,将
getAuthorities
方法返回的内容不出现在返回结果中
在添加该注解后,代码正常运行
总结:
无法将
JSON
返回到前端有很多原因,这里的解决方法是对
UserDetails
的实现类中的方法添加注解,表示其返回到内容不需要返回到前端。对
@JsonIgnore
注解的使用进行一个小的总结
-
作用:在
JSON
序列化时将
Java Bean
中的⼀些属性忽略掉,序列化和反序列化都受影响
-
使⽤场景:
⼀般标记在属性或者⽅法上
,返回的
Json
数据即不包含该属性
No qualifying bean of type ‘org.springframework.boot.autoconfigure.http.HttpMessageConverters‘ avail
Failed to meta-introspect annotation interface org.springframework.web.bind.annotation.RequestBody:
The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path类似问题简单解决方案
required a bean of type ‘org.springframework.web.client.RestTemplate‘ that could not be found.
The superclass “javax.servlet.http.HttpServlet“ was not found on the Java Build Path的解决方案
java.lang.IllegalStateException: Cannot load configuration class: org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration报错问题处理