前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >来这看没错!!!报错Cannot serialize; nested exception is org.springframework.core.serializerlaik

来这看没错!!!报错Cannot serialize; nested exception is org.springframework.core.serializerlaik

作者头像
知识浅谈
发布2020-11-24 12:59:21
3.9K0
发布2020-11-24 12:59:21
举报
文章被收录于专栏:分享学习分享学习

model实现了Serializable 但是还是报错Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailed

在学习Shiro使用缓存时,出现: java.io.NotSerializableException:org.apache.shiro.util.SimpleByteSource异常,开启debug会提示: ERROR [authentication.data] - Disk Write of test failed: 错误。

出现这种情况是因为:SimpleByteSource没有是实现Serializable接口

解决办法:自定义一个类继承SimpleByteSource实现Serializable接口

当然也可以实现ByteSource接口和Serializable接口,但是实现ByteSource接口需要实现其方法,不方便。

自定义一个MySimpleByteSource 类继承继承SimpleByteSource实现Serializable接口 方法一:自己实现ByteSource, Serializable 的接口 在springboot启动类的同一目录下新建ShiroByteSource类

代码语言:javascript
复制
package com.englishcode.springboot_jsp_shiro;

import org.apache.shiro.codec.Base64;
import org.apache.shiro.codec.CodecSupport;
import org.apache.shiro.codec.Hex;
import org.apache.shiro.util.ByteSource;

import java.io.File;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Objects;

/**
 * @author cyl
 * @version 1.0
 * @date 2020/11/14 18:29
 */
public class ShiroByteSource implements ByteSource, Serializable {
    private static final long serialVersionUID = -6814382603612799610L;
    private volatile byte[] bytes;
    private String cachedHex;
    private String cachedBase64;

    public ShiroByteSource() {

    }

    public ShiroByteSource(String string) {
        this.bytes = CodecSupport.toBytes(string);
    }

    public void setBytes(byte[] bytes) {
        this.bytes = bytes;
    }

    @Override
    public byte[] getBytes() {
        return this.bytes;
    }

    @Override
    public String toHex() {
        if ( this.cachedHex == null ) {
            this.cachedHex = Hex.encodeToString(getBytes());
        }
        return this.cachedHex;
    }

    @Override
    public String toBase64() {
        if ( this.cachedBase64 == null ) {
            this.cachedBase64 = Base64.encodeToString(getBytes());
        }
        return this.cachedBase64;
    }

    @Override
    public boolean isEmpty() {
        return this.bytes == null || this.bytes.length == 0;
    }

    @Override
    public String toString() {
        return toBase64();
    }

    @Override
    public int hashCode() {
        if (this.bytes == null || this.bytes.length == 0) {
            return 0;
        }
        return Arrays.hashCode(this.bytes);
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }
        if (o instanceof ByteSource) {
            ByteSource bs = (ByteSource) o;
            return Arrays.equals(getBytes(), bs.getBytes());
        }
        return false;
    }

    public static ByteSource of(String string) {
        return new ShiroByteSource(string);
    }
}

之后在自己定义的realm中使用上边定义的类创建salt 就是盐

代码语言:javascript
复制
    //处理认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("调用doGetAuthenticationInfo这个函数");
        String principal = (String) authenticationToken.getPrincipal();
        //在工厂中获取service对象
        UserService userServiceImpl = (UserService) ApplicationContextUtils.getBean("userServiceImpl");
        User user = userServiceImpl.findByUserName(principal); //从数据库中查询
        if(!ObjectUtils.isEmpty(user)){
            //第三个参数注意了,随机盐应该使用ByteSource的工具类把对应的String转换为字节
            // 获取用户的盐值
            //ByteSource salt = ByteSource.Util.bytes(user.getSalt());  //旧代码会抛出NotSerializableException:org异常,替换成下面代码就可以了
            //最重要的是这个地方
            return new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(), new ShiroByteSource(user.getSalt()),this.getName());
        }
        return null;
    }

方法二: 继承SimpleByteSource类

import java.io.Serializable; public class MySimpleByteSource extends org.apache.shiro.util.SimpleByteSource implements Serializable{ private static final long serialVersionUID = 5528101080905698238L; public SimpleByteSource(byte[] bytes) { super(bytes); // TODO 自动生成的构造函数存根 } }

自定义的realm中

return new SimpleAuthenticationInfo(userEntity, credentials,new MySimpleByteSource(userCode),getName()); 但是方法二会在很多步骤中出错,只是满足了临时的不出错

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-11-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档