当前位置: 代码迷 >> 综合 >> 来这看没错!!!报错Cannot serialize; nested exception is org.springframework.core.serializerlaik
  详细解决方案

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

热度:81   发布时间:2023-11-22 06:55:20.0

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类

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;}@Overridepublic byte[] getBytes() {
    return this.bytes;}@Overridepublic String toHex() {
    if ( this.cachedHex == null ) {
    this.cachedHex = Hex.encodeToString(getBytes());}return this.cachedHex;}@Overridepublic String toBase64() {
    if ( this.cachedBase64 == null ) {
    this.cachedBase64 = Base64.encodeToString(getBytes());}return this.cachedBase64;}@Overridepublic boolean isEmpty() {
    return this.bytes == null || this.bytes.length == 0;}@Overridepublic String toString() {
    return toBase64();}@Overridepublic int hashCode() {
    if (this.bytes == null || this.bytes.length == 0) {
    return 0;}return Arrays.hashCode(this.bytes);}@Overridepublic 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 就是盐

    //处理认证@Overrideprotected 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());
但是方法二会在很多步骤中出错,只是满足了临时的不出错

  相关解决方案