org.springframework.http.converter.HttpMessageNotWritableException...解决方法

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

项目场景

在进行在线使用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接口

  1. lombok@Data注解没有加上导致某些字段没有getter以及setter方法
  2. 对于Spring SecurityUserDetails的接口字段有一些是不需要返回给前端的

对应的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;

/**
 * <p>
 * 
 * </p>
 *
 * @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注解的使用进行一个小的总结

  1. 作用在JSON序列化时将Java Bean中的⼀些属性忽略掉序列化和反序列化都受影响
  2. 使⽤场景⼀般标记在属性或者⽅法上返回的Json数据即不包含该属性
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Spring