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

简介: org.springframework.http.converter.HttpMessageNotWritableException...解决方法

项目场景:


在进行在线使用Spring Security做为权限框架的办公系统的个人项目开发中,控制台输出的错误信息为无法写入JSON的错误,遇到了这个比较让人摸不着头脑的问题,我想应该不局限于当前项目场景,将目前遇到这种错误的解决方法进行记录,如果以后再遇到相同的错误,有不同解决方法时再回来记录。

问题描述


要实现的功能是获取管理员列表,向后端传递的参数和数据库中想要查询的内容也可以正常的获取到,但是在将查询到的数据返回到前端时就出现了报错

Swagger调试的内容如下:

image.png

image.png

从控制台的截图可以看到数据库中的数据正常返回以及前端传递的参数正常接收

控制台报错如下:

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方法返回的内容不出现在返回结果中

在添加该注解后,代码正常运行

image.png

总结:


无法将JSON返回到前端有很多原因,这里的解决方法是对UserDetails的实现类中的方法添加注解,表示其返回到内容不需要返回到前端。对@JsonIgnore注解的使用进行一个小的总结

  1. 作用:在JSON序列化时将Java Bean中的⼀些属性忽略掉,序列化和反序列化都受影响
  2. 使⽤场景:⼀般标记在属性或者⽅法上,返回的Json数据即不包含该属性
相关文章
|
11月前
|
JSON 前端开发 数据格式
【前后端异常】http/https post请求 返回415错误状态码的解决方法
【前后端异常】http/https post请求 返回415错误状态码的解决方法
2504 0
|
Java
http访问springboot接口出现401 、403、 Forbidden 错误解决方法
http访问springboot接口出现401 、403、 Forbidden 错误解决方法
2024 0
|
开发框架 .NET
ueditor上传大容量视频报http请求错误的解决方法
故障现象: 当使用百度编辑器ueditor上传大容量视频或大容量图片的时候,编辑器报“http请求错误”的解决方法详解; 原因分析: 目前很多CMS整合了百度的ueditor编辑器,但是上传稍微大一点的文件就会报错, 解决方案 1:修改相对应的ueditor\asp\config.
3028 0
|
开发工具 数据安全/隐私保护 git
Git报错:remote: HTTP Basic: Access denied的解决方法
Git报错:remote: HTTP Basic: Access denied的解决方法
1650 0
Git报错:remote: HTTP Basic: Access denied的解决方法
|
前端开发 Java
Java 技术篇 - 前端浏览器发送一次url请求后端ServerSocket接收到两次请求原因及解决方法,GET /favicon.ico HTTP/1.1问题处理
Java 技术篇 - 前端浏览器发送一次url请求后端ServerSocket接收到两次请求原因及解决方法,GET /favicon.ico HTTP/1.1问题处理
738 0
Java 技术篇 - 前端浏览器发送一次url请求后端ServerSocket接收到两次请求原因及解决方法,GET /favicon.ico HTTP/1.1问题处理
|
2月前
|
Java 数据库连接 应用服务中间件
表单数据返回不到,HTTP状态 404 - 未找未找到,解决方法,针对这个问题,写一篇文章,理一下思路,仔细与原项目比对,犯错的原因是Mapper层的select查询表单数据写错,注意打开的路径对不对
表单数据返回不到,HTTP状态 404 - 未找未找到,解决方法,针对这个问题,写一篇文章,理一下思路,仔细与原项目比对,犯错的原因是Mapper层的select查询表单数据写错,注意打开的路径对不对
|
缓存 Linux 开发工具
centos 7 yum安装失败(HTTP Error 404 - Not Found)的解决方法
centos 7 yum安装失败(HTTP Error 404 - Not Found)的解决方法
1892 0
|
XML Java 应用服务中间件
JSP项目报错在build path里找不到javax.servlet.http.HttpServlet的解决方法
JSP项目报错在build path里找不到javax.servlet.http.HttpServlet的解决方法
JSP项目报错在build path里找不到javax.servlet.http.HttpServlet的解决方法
|
Java 应用服务中间件 Maven
HTTP Status 500 - The absolute uri: http://java.sun.com/jsp/jstl/core cannot-报错解决方法
HTTP Status 500 - The absolute uri: http://java.sun.com/jsp/jstl/core cannot-报错解决方法
170 0
|
缓存
Discuz!论坛如何去除隐藏文章内容图片鼠标经过时显示“下载附件”等信息解决方法本文来自:XM技术学习分享,原地址:http://xmwl.cc/mb/41.html
在discuz!系统中发帖上传图片,鼠标经过的时候会显示一个小菜单,显示图片的基本信息和下载链接,有些站长觉得每次鼠标经过的时候弹出这个体验不好希望去掉!本文来自:XM技术学习分享,原地址:http://xmwl.cc/mb/41.html
807 0