利用Jackson的JsonFilter来实现动态过滤数据列(数据列权限控制)

2023-05-16

利用Jackson的JsonFilter来实现动态过滤数据列。

也就是说,同一个实体,你配置了不同的@JsonFilter,通过Jackson展现的结果可以是不一样的。

举个栗子:

@lombok.Data
public class User{
  String username;
  String password;
  Integer age;
  String gender;
  String blog;
}

默认不做任何配置的话,通过Jackson序列化出来的结果是:

{
  "username" : "tomcatandjerry",
  "password" : "123456",
  "age" : 36,
  "gender" : "男",
  "blog" : "http://www.cnblogs.com/tomcatandjerry/"
}

可是password不应该要展示,方法有多种:

方法1:在不想序列化的字段上加注解JsonProperty:

@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)//Jackson
@JSONField(serialize = false)//fastjson
String password;

方法2:

2.1在User类上面加注解JsonFilter:

@JsonFilter("non-password")
public class User {
  ...
}

2.2 配置FilterProvider

测试方法&配置如下:

public class JsonFilterTest {

    private ObjectMapper setupJsonFilter(){
        ObjectMapper mapper = new ObjectMapper();
        String[] beanProperties = new String[]{"password"};
        String nonPasswordFilterName = "non-password";//需要跟User类上的注解@JsonFilter("non-password")里面的一致
        FilterProvider filterProvider = new SimpleFilterProvider()
                .addFilter(nonPasswordFilterName, SimpleBeanPropertyFilter.serializeAllExcept(beanProperties));
                //serializeAllExcept 表示序列化全部,除了指定字段
                //filterOutAllExcept 表示过滤掉全部,除了指定的字段
        mapper.setFilterProvider(filterProvider);
        return mapper;
    }

    @Test
    public void testJsonFilter() throws JsonProcessingException {
        User user = new User();
        user.setUsername("tomcatandjerry");
        user.setPassword("123456");
        user.setAge(36);
        user.setGender("男");    
        System.out.println(setupJsonFilter().writeValueAsString(user));
    }
}

打印测试结果:

{
  "username" : "tomcatandjerry",
  "age" : 36,
  "gender" : "男",
  "blog" : "http://www.cnblogs.com/tomcatandjerry/"
}

小结:

看上去似乎使用@JsonProperty更简单。
但是当有一堆字段需要配置,而且整个项目都需要统一处理的时候,后者@JsonFilter是一个不错的选择。

扩展:

同一个API,如果我想不同的人看到不一样的结果呢?
比如同一个用户API,有的展示username+age, 有的展示username+gender等

这个时候JsonFilter就非常适合了。

有人可能会问:不对啊?一个对象只能配置一个JsonFilter,怎么动态切换不同的Filter?
对的,一个对象只能配置一个JsonFilter,但只要稍加修改,就能实现??

思路:
既然一个对象只能配置一个JsonFilter,那么靠一个对象来动态展示不同的属性是不可能的。
我们可以多写几个对象,都继承User对象,不同的子类里面使用不同的JsonFilter

@JsonFilter("normal-user")
public class UserNormal extends User{
 //空class,里面没有任何属性
}

@JsonFilter("admin")
public class UserAdmin extends User{
 //空class,里面没有任何属性
}

利用Spring的切点,根据当前用户的角色,替换返回值为不同的子类

原本:
public class UserService{
  
  public User get(String id){
    
  }
}

利用切点(可以自定义注解,加到方法上,切在注解上面),替换返回的对象为子类:

具体需要用到的:

  1. 扫描并缓存子类
  2. @Aspect切点,@Around(value=“比如:自定义注解”)
  3. 利用反射,创建出子类对象,BeanUtils.copyProperties

这样看似调用userService.get(“id”)返回的是User对象,其实可能已经替换成某一个子类了。

在ObjectMapper配置多个Filter,就实现了动态展示不同属性,且对开发人员透明。

小结:

优点: 对开发透明
缺点:一个对象需要写多个子类,虽然是空class

这也算是一种数据列权限控制的一种解决方案吧。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

利用Jackson的JsonFilter来实现动态过滤数据列(数据列权限控制) 的相关文章

随机推荐

  • Node.JS中调用JShaman,加密JS代码

    在Node JS环境中 xff0c 调用JShaman的WebAPI接口 xff0c 对JS代码进行混淆加密 效果如下 xff1a 代码 xff1a js代码 var js code 61 96 function NewObject pre
  • 在Node.JS中调用JShaman接口,实现JS代码加密

    在Node JS中调用JShaman接口 xff0c 实现JS代码加密 使用axios库实现https的post请求 xff0c 代码如下 xff1a const axios 61 require 34 axios 34 const jsh
  • js加密混淆,jshaman和jscrambler哪个好用?

    在前端开发中 xff0c JavaScript混淆加密是一种十分重要的技术 xff0c 其可以防止代码被反编译以及保护代码的安全性 在市场上有很多的JavaScript混淆工具 xff0c 其中jshaman和jscrambler是两个非常
  • CMake Error at CMakeLists.txt:11

    背景 xff1a 编译opencv源码 问题 xff1a 用clion或者CMake命令时报错 xff0c 报错类型为 xff1a CMake Error at CMakeLists txt 11 message FATAL In sour
  • PHP出现Warning: A non-numeric value encountered问题的原因及解决方法

    PHP出现Warning A non numeric value encountered问题的原因及解决方法 参考文章 xff1a xff08 1 xff09 PHP出现Warning A non numeric value encount
  • openstack总结2_环境搭建+keystone模块安装

    上篇说到我的openstack的部署环境是ubuntu16 04 xff0c 安装的版本是ocata 其实我最开始安装的版本是mitaka 因为mitaka有中文的安装部署文档 官方的Demo配置是ubuntu14 04 43 mitaka
  • WSL(ubuntu2204)xfce4语言支持报错及配置WSL服务自启

    语言支持报错 在图形桌面或命令行打开语言支持报错 xff1a dbus exceptions DBusException org freedesktop DBus Error FileNotFound Failed to connect t
  • 设置未识别的网络默认为专用网络

    在WIN7 WIN2008R2中 xff0c 没有配置网关的网络连接默认是公用网络 比如双网卡做软路由的时候 xff0c 连接内网的网卡是不配置网关的 xff0c 如果开启防火墙而又被识别为公用网络有时候很不方便 修改默认为专用网络的操作如
  • 多模块,Maven无法下载依赖,仓库查看有这个版本但是无法下载,点reload也没用

    Maven无法下载依赖 xff0c 点reload也没用 配置文件正确 也不是maven版本问题 最后发现是pom文件里面的依赖是写在 这个标签内的 这个的作用是子模块当引入同个依赖的时候 xff0c 不需要去写版本号 但是父模块的pom文
  • 在TypeORM中使用实体@Entity与字段@Column注解

    在TypeORM中使用实体 64 Entity与字段 64 Column注解 客观存在并相互区别的事物称为实体 Entity 实体是一个抽象名词 xff0c 是指一个独立的事物个体 xff0c 自然界的一切具体存在的事物都可以看做一个实体
  • ubuntu 16.04升级到ubuntu 18.04

    昨天升级了一下ubuntu xff0c 发现升级过程不是很顺利 xff0c 我这里分享一下我的经验 xff0c 在升级前 xff0c 需要把所有的ppa软件源和相应的软件删除 然后执行下面的操作 xff1a sudo apt get upd
  • Ubuntu系统下载及安装教程

    ubuntu下载及系统安装步骤 说明 xff1a 本教程介绍的是安装DeskTop版的系统 1 官网下载镜像 官方网址 https ubuntu com download 进入官网后会有最新版本的镜像下载地址 xff0c 如果需要下载最新版
  • Xrdp编译报错configure failed for librfxcodec解决方案

    vnc对异地网络远程控制不是很友好 这段时间中午休息的时候总是会远程连回寝室电脑 于是将目标锁定了Xrdp 但是使用apt install xrdp安装的xrdp不支持声音 xff0c RDP版本也很低 那就干脆自己编译一个 遇到问题先百度
  • python解析.pyd文件

    有的时候 xff0c 为了对python文件进行加密 xff0c 会把python模块编译成 pyd文件 xff0c 供其他人调用 拿到一个 pyd文件 xff0c 在没有文档说明的情况下 xff0c 可以试试查看模块内的一些函数和类的用法
  • 字节与KB的关系

    1个二进制位 61 1位 8位 xff08 bit xff09 61 1字节bai xff08 Byte xff09 xff0c 1024字节 61 1KB 字节 xff1a 英文单词 xff1a xff08 byte xff09 xff0
  • AF_INET域与AF_UNIX域socket通信原理对比

    1 AF INET域socket通信过程 典型的TCP IP四层模型的通信过程 发送方 接收方依赖IP Port来标识 xff0c 即将本地的socket绑定到对应的IP端口上 xff0c 发送数据时 xff0c 指定对方的IP端口 xff
  • Ubuntu20.04 idea/pycharm 搜狗中文输入法不跟随光标问题

    概述 在 linux 平台下使用搜狗输入法在 IDEA PYCHARM xff08 pycharm2020 3 xff09 中输入中文时 xff0c 输入法候选框总是静止在 IDEA 的左下角 xff0c 而不能跟随光标进行移动 虽然不影响
  • 子网掩码使用详解

    一 子网掩码 IP地址是以网络号和主机号来标示网络上的主机的 xff0c 我们把网络号相同的主机称之为本地网络 xff0c 网络号不相同的主机称之为远程网络主机 xff0c 本地网络中的主机可以直接相互通信 xff1b 远程网络中的主机要相
  • centos7 安装 wireshark

    1 安装 root安装 最好在root 路径下安装 xff1a yum y span class token function install span wireshark yum y span class token function i
  • 利用Jackson的JsonFilter来实现动态过滤数据列(数据列权限控制)

    利用Jackson的JsonFilter来实现动态过滤数据列 也就是说 xff0c 同一个实体 xff0c 你配置了不同的 64 JsonFilter 通过Jackson展现的结果可以是不一样的 举个栗子 xff1a span class