fastjson2
fastjson2 copied to clipboard
[QUESTION] 序列化和反序列化SimpleGrantedAuthority有没有完整教程啊?
存序列化存Redis的时候报错: org.springframework.data.redis.serializer.SerializationException: Could not deserialize: invoke constructor error, public org.springframework.security.core.authority.SimpleGrantedAuthority(java.lang.String)
SimpleGrantedAuthority是springsecurity的类,没有默认的无参构造器。但是又没有详细的mixin文档
什么版本?2.0.12应该是能自动注册SimpleGrantedAuthority的mixin的
static Filter filter = JSONReader.autoTypeFilter(
// 这里可以配置多个前缀
"org.springframework.security.core.authority.SimpleGrantedAuthority",
"org.springframework.util.LinkedCaseInsensitiveMap"
);
public Object deserialize(byte[] bytes) {
return JSON.parseObject(bytes, Object.class, filter);
}
public Object deserialize(String str) {
return JSON.parseObject(str, Object.class, filter);
}
@Test
public void testAuthority() {
String json = "{\"@type\":\"org.springframework.security.core.authority.SimpleGrantedAuthority\",\"authority\":\"abc\"}";
byte[] bytes = json.getBytes(StandardCharsets.UTF_8);
Object object = deserialize(bytes);
assertEquals(org.springframework.security.core.authority.SimpleGrantedAuthority.class, object.getClass());
}
参考上面的代码试试看
有指定某个字段序列化规则到方式么?像jackson那样给某个属性加个注解,自己实现该属性的序列化和反序列化实现。我看了fastjson2的相关注解,JSONField的serializeUsing和deserializeUsing根本不生效,打断点不执行方法。JSONType里面到那两个属性是可以执行serializeUsing和deserializeUsing定义的方法的。但是也没找到别的参考文档可以看,代码注释写的太模糊。
能提供JSONField#serializeUsing和deserializeUsing不生效的重现的testcase么?
能提供JSONField#serializeUsing和deserializeUsing不生效的重现的testcase么?
我这反序列化还是有问题:
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<Object, Object>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
// GenericFastJsonRedisSerializer fastJsonRedisSerializer = new GenericFastJsonRedisSerializer();
FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
FastJsonConfig fastJsonConfig = fastJsonRedisSerializer.getFastJsonConfig();
fastJsonConfig.setReaderFeatures(JSONReader.Feature.SupportAutoType);
fastJsonConfig.setWriterFeatures(JSONWriter.Feature.WriteClassName);
fastJsonConfig.setReaderFilters(JSONReader.autoTypeFilter("org.springframework.security.core.authority.SimpleGrantedAuthority"));
redisTemplate.setDefaultSerializer(fastJsonRedisSerializer);//设置默认的Serialize,包含 keySerializer & valueSerializer
redisTemplate.setValueSerializer(fastJsonRedisSerializer);//单独设置valueSerializer
redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);//单独设置hashValueSerializer
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);//单独设置keySerializer
redisTemplate.setHashKeySerializer(stringRedisSerializer);//单独设置hashKeySerializer
return redisTemplate;
}
这个是我反序列化的类型:
@Data
@NoArgsConstructor
public class LoginUser implements UserDetails {
private User user;
/**
* 帐户是否过期
*/
private boolean accountNonExpired = true;
/**
* 帐户是否被锁定
*/
private boolean accountNonLocked = true;
/**
* 密码是否过期
*/
private boolean credentialsNonExpired = true;
/**
* 帐户是否可用
*/
private boolean enabled = true;
/**
* 拥有权限集合
*/
private Set<? extends GrantedAuthority> authorities;
/**
* 可访问的菜单集合
*/
private Set<MenuVo> menuSet;
public LoginUser(User user) {
this.user = user;
}
@JSONField(serialize = false,deserialize = false)
public String getPassword() {
return user.getPassword();
}
@JSONField(serialize = false,deserialize = false)
public String getUsername() {
return user.getUsername();
}
}
日志信息: org.springframework.data.redis.serializer.SerializationException: Could not deserialize: invoke constructor error, public org.springframework.security.core.authority.SimpleGrantedAuthority(java.lang.String)
这个错误是我在redisTemplate.get的时候报的
redis里面存的数据信息:
{"@type":"top.jiangqiang.framework.system.entity.LoginUser","accountNonExpired":true,"accountNonLocked":true,"authorities":Set[{"@type":"org.springframework.security.core.authority.SimpleGrantedAuthority","authority":"123"},{"@type":"org.springframework.security.core.authority.SimpleGrantedAuthority","authority":"12312"}],"credentialsNonExpired":true,"enabled":true,"menuSet":Set[{"@type":"top.jiangqiang.framework.system.entity.vo.MenuVo","authority":"","component":"routerView/parent.vue","externalLink":false,"id":25,"menuSort":8,"menuType":"menu","meta":{"@type":"java.util.LinkedHashMap","isIframe":false,"isKeepAlive":true,"icon":"iconfont icon-diannao1","isAffix":false,"title":"测试名称","url":"","isHide":false},"name":"test","parentId":0,"path":"/test","redirect":""},{"@type":"top.jiangqiang.framework.system.entity.vo.MenuVo","component":"home/index.vue","externalLink":false,"id":1,"menuSort":1,"menuType":"menu","meta":{"@type":"java.util.LinkedHashMap","isLink":"","isIframe":false,"roles":["admin","common"],"isKeepAlive":true,"icon":"iconfont icon-shouye","isAffix":true,"title":"首页","isHide":false},"name":"home","parentId":0,"path":"/home"},{"@type":"top.jiangqiang.framework.system.entity.vo.MenuVo","authority":"","component":"3123123","externalLink":false,"id":51,"menuSort":0,"menuType":"menu","meta":{"@type":"java.util.LinkedHashMap","isIframe":false,"isKeepAlive":true,"icon":"","isAffix":false,"title":"123","url":"","isHide":false},"name":"3123","parentId":0,"path":"12312312","redirect":"1231"},{"@type":"top.jiangqiang.framework.system.entity.vo.MenuVo","authority":"123","component":"system/generator/index.vue","externalLink":false,"id":48,"menuSort":0,"menuType":"menu","meta":{"@type":"java.util.LinkedHashMap","isIframe":false,"isKeepAlive":true,"icon":"iconfont icon-diannao-shuju","isAffix":false,"title":"代码生成","url":"","isHide":false},"name":"112","parentId":0,"path":"/genCode","redirect":""},{"@type":"top.jiangqiang.framework.system.entity.vo.MenuVo","children":[{"component":"system/dept/index.vue","externalLink":false,"id":6,"menuSort":6,"menuType":"menu","meta":{"@type":"java.util.LinkedHashMap","isLink":"","isIframe":false,"roles":["admin"],"isKeepAlive":true,"icon":"ele-OfficeBuilding","isAffix":false,"title":"部门管理","isHide":false},"name":"systemDept","parentId":2,"path":"/system/dept"},{"component":"system/menu/index.vue","externalLink":false,"id":3,"menuSort":3,"menuType":"menu","meta":{"@type":"java.util.LinkedHashMap","isLink":"","isIframe":false,"roles":["admin"],"isKeepAlive":true,"icon":"iconfont icon-caidan","isAffix":false,"title":"菜单管理","isHide":false},"name":"systemMenu","parentId":2,"path":"/system/menu"},{"component":"system/user/index.vue","externalLink":false,"id":5,"menuSort":5,"menuType":"menu","meta":{"@type":"java.util.LinkedHashMap","isLink":"","isIframe":false,"roles":["admin"],"isKeepAlive":true,"icon":"iconfont icon-icon-","isAffix":false,"title":"用户管理","isHide":false},"name":"systemUser","parentId":2,"path":"/system/user"},{"component":"system/role/index.vue","externalLink":false,"id":4,"menuSort":4,"menuType":"menu","meta":{"@type":"java.util.LinkedHashMap","isLink":"","isIframe":false,"roles":["admin"],"isKeepAlive":true,"icon":"ele-ColdDrink","isAffix":false,"title":"角色管理","isHide":false},"name":"systemRole","parentId":2,"path":"/system/role"},{"authority":"","component":"system/i18n/index.vue","externalLink":false,"id":45,"menuSort":9,"menuType":"menu","meta":{"@type":"java.util.LinkedHashMap","isIframe":false,"isKeepAlive":true,"icon":"iconfont icon-diannao1","isAffix":false,"title":"国际化","url":"","isHide":false},"name":"i18n","parentId":2,"path":"/system/i18n","redirect":""},{"component":"system/dic/index.vue","externalLink":false,"id":7,"menuSort":7,"menuType":"menu","meta":{"@type":"java.util.LinkedHashMap","isLink":"","isIframe":false,"roles":["admin"],"isKeepAlive":true,"icon":"ele-SetUp","isAffix":false,"title":"字典管理","isHide":false},"name":"systemDic","parentId":2,"path":"/system/dic"}],"component":"routerView/parent.vue","externalLink":false,"id":2,"menuSort":2,"menuType":"menu","meta":{"@type":"java.util.LinkedHashMap","isLink":"","isIframe":false,"roles":["admin"],"isKeepAlive":true,"icon":"iconfont icon-xitongshezhi","isAffix":false,"title":"系统设置","isHide":false},"name":"system","parentId":0,"path":"/system","redirect":"/system/setting"}],"user":{"active":true,"deleted":false,"id":1,"nickname":"admin","password":"d29d20329fbd47d8b42fb2ac69069a4a104f215e509b85868c1f47ba9eab114dd6fdfe4d6812e7b7f498056f7b0ac5740c6c056e198632992fa8b9dd958e9bd5ef765b4e46b8fe58079eb6b10a7e563c4bee074b412138ca2d426a9b3f406ad3","username":"admin"}}
您发的这个例子,我都跑不了。
看这报错,我是不是还要给他弄一个mixin?
您发的这个例子,我都跑不了。
看这报错,我是不是还要给他弄一个mixin?
写了个mixin,这个是可以用的,但是Redis的那个我应该在哪里给他注入mixin呢?有点不清楚fastjson内部逻辑是啥,JSON调用mixin之后,项目任何地方都可以用???这个是全局的?
interface JSON {
static void mixIn(Class<?> target, Class<?> mixinSource) {
JSONFactory.defaultObjectWriterProvider.mixIn(target, mixinSource);
JSONFactory.getDefaultObjectReaderProvider().mixIn(target, mixinSource);
}
}
通过JSON.mxin是注册在defaultObjectWriterProvider和defaultObjectReaderProvider上的,可以理解是全局的
interface JSON { static void mixIn(Class<?> target, Class<?> mixinSource) { JSONFactory.defaultObjectWriterProvider.mixIn(target, mixinSource); JSONFactory.getDefaultObjectReaderProvider().mixIn(target, mixinSource); } }
通过JSON.mxin是注册在defaultObjectWriterProvider和defaultObjectReaderProvider上的,可以理解是全局的
我随便写了个自定义序列化字段的demo,不生效,是使用jsonfield注解配置的,反序列化可以生效,序列化不执行。
同样的问题,字段是UnmodifiableSet类型,想通过自定义字段反序列化方法来做,发现@JSONField(deserializeUsing = 指定的反序列化类不生效),只有@JSONType(deserializer=指定反序列化类生效)但是反序列化的具体方法没有任何例子和说明,实现起来成本太高了
@cycle2zhou 单开一个issue吧,你这个是新问题,否则无法跟踪
已开https://github.com/alibaba/fastjson2/issues/1509#issue-1728517832