1. 前言

Java开发中有时候某些敏感信息我们需要屏蔽掉,不能被消费这些数据的客户端知道。通常情况下我们会将其设置为null或者空字符 "",其实还有其它办法,如果你使用了Jackson的话。接下来我将以一个实际场景来告诉你可以怎么做。

2. Jackson如何忽略字段

这里都以JSON序列化为例。假如我们在业务中需要返回用户信息,已有的POJO是这样的:

import lombok.Data;

/**
* @author felord.cn
*/
@Data
public class UserInfo {
/**
* userid
*/
private String userId;
/**
* 用户名
*/
private String username;
/**
* 密钥串
*/
private String secret;
/**
* 地址信息
*/
private String address;
}

业务场景:第三方通过用户的userId来获取用户的信息,但是密钥串secret显然不能让第三方知道,通常最容易想到的方法是将secret字段设置为null或者""。如果业务需要批量提供用户信息,即List<UserInfo>,我们总不能每次都要遍历一遍吧。Spring Boot内置的Jackson可以很方便的帮我们处理这个问题。

使用@JsonIgnore注解

Jackson提供了一个@JsonIgnore注解,将它标记到需要被忽略的字段上或者对应的getter方法或者setter方法上就可以实现对该字段的屏蔽。就像下面这样标记:

     @JsonIgnore
private String secret;
// 对应json 样例 {"userId":"100000","username":"felord.cn","address":"cn"}

无论是序列化(将POJO转为JSON)还是反序列化((将JSON转为POJO),secret都会被忽略。

使用@JsonIgnoreProperties注解

这个注解比@JsonIgnore更加强大一些,通常该注解标记到POJO之上,它有更多的能力:

  • 忽略多个字段,配置value属性即可。
  • 忽略未知的属性,配置ignoreUnknowntrue,默认不忽略。
  • 允许忽略字段被序列化,配置allowGetterstrue,序列化的时候不会被忽略。
  • 允许忽略字段被反序列化,配置allowSetterstrue,反序列化的时候不会被忽略。

例如我们要忽略UserInfo中的secretaddress,我们可以这样配置:

@JsonIgnoreProperties({"secret", "address"})

使用@JsonProperty注解

需要Jackson版本不低于2.6

这个注解出镜率还是非常高的,通常为了给JSON的字段起别名或者设置默认值使用。比如UserInfo中的userId想对应JSON中的user_id,我们可以:

@JsonProperty(value = "user_id")
private String userId;

在2.6版本以后,这个注解也能实现忽略字段的作用。它有个access属性,用来指定在序列化(“读取”)和反序列化(“写”)期间访问权限(这里的读写是以属性为视角)。它由枚举Access定义:

public enum Access
{
/**
* 无论是序列化还是反序列化都会根据配置自动的处理,默认值。
*/
AUTO, /**
* 意味着该属性只能在进行序列化时读取(通过“ getter”方法访问的值,或者从字段中读取),而在反序列化 * 期间不能写入(设置)。换句话说,这将反映“只读POJO”,其中包含的值可以读取但不能写入。
*/
READ_ONLY, /**
* 意味着该属性只能作为反序列化的一部分写入(设置)(使用“ setter”方法,或分配给Field,或作为 * Creator参数传递),而不会被读取(获取)以进行序列化,即,该属性的值不包括在序列化中。
*/
WRITE_ONLY, /**
* 可读可写,READ_ONLY与WRITE_ONLY的合并效果。
*/
READ_WRITE;
}

从这个注解中我们可以知道,如果你想在POJOJSON时忽略secret字段,就可以这么写:

@JsonProperty( access = JsonProperty.Access.WRITE_ONLY)
private String secret;

使用@JsonIgnoreType注解

这个注解是用来直接忽略类型的,如果上面的UserInfo是另外一个POJO的属性,我们不希望它被序列化和反序列化,那么就可以:

@JsonIgnoreType
public class UserInfo {
// 省略
}

3. 总结

目前大概可知的Jackson有这么四种的忽略属性的方式,它们有各自的使用场景,你可以根据自己的情况选择使用。好了今天的分享就到这里,多多关注:码农小胖哥,获取更多的编程干货。

关注公众号:Felordcn 获取更多资讯

个人博客:https://felord.cn

Java开发中POJO和JSON互转时如何忽略隐藏字段的更多相关文章

  1. paip.java 开发中web server的选择jboss resin tomcat比较..

    paip.java 开发中web server的选择jboss resin tomcat比较.. 作者Attilax  艾龙, EMAIL:1466519819@qq.com 来源:attilax的专 ...

  2. Java开发中常见的危险信号(中)

    本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...

  3. Java开发中文件读取方式总结

    JAVA开发中,免不了要读文件操作,读取文件,首先就需要获取文件的路径. 路径分为绝对路径和相对路径. 在文件系统中,绝对路径都是以盘符开始的,例如C:\abc\1.txt. 什么是相对路径呢?相对路 ...

  4. java开发中遇到的问题及解决方法(持续更新)

    摘自 http://blog.csdn.net/pony12/article/details/38456261 java开发中遇到的问题及解决方法(持续更新) 工作中,以C/C++开发为主,难免与其他 ...

  5. Java开发中常见的危险信号(上)

    本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...

  6. 编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则)

    编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则) 目录 建议1: 不要在常量和变量中出现易混淆的字母 建议2: 莫让常量蜕变成变量 建议3: 三元操作符的类型务 ...

  7. 完整java开发中JDBC连接数据库代码和步骤[申明:来源于网络]

    完整java开发中JDBC连接数据库代码和步骤[申明:来源于网络] 地址:http://blog.csdn.net/qq_35101189/article/details/53729720?ref=m ...

  8. Java 开发中的对象拷贝

    前言 在 Java 开发中,很多时候需要将两个属性基本相同的对象进行属性复制,比如 DO 转 VO等等. 本文主要介绍自己实现的简易拷贝工具类与 Spring 提供的属性拷贝的对比. Spring 提 ...

  9. [ 转载 ] Java开发中的23种设计模式详解(转)

    Java开发中的23种设计模式详解(转)   设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类 ...

随机推荐

  1. vue项目中的字符串每隔4位一个空格

    项目中遇到现实银行卡号的需求所以需要这个方法 我们这里运用 JavaScript replace()方法 replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子 ...

  2. Java 安全之Weblogic 2017-3248分析

    Java 安全之Weblogic 2017-3248分析 0x00 前言 在开头先来谈谈前面的绕过方式,前面的绕过方式分别使用了streamMessageImpl 和MarshalledObject对 ...

  3. 【Redis3.0.x】配置文件

    Redis3.0.x 配置文件 概述 Redis 的配置文件位于Redis安装目录下,文件名为 redis.conf. 可以通过 CONFIG 命令查看或设置配置项. Redis 命令不区分大小写. ...

  4. 【C++】《C++ Primer 》第十六章

    第十六章 模板与泛型编程 面向对象编程和泛型编程都能处理在编写程序时不知道类型的情况. OOP能处理类型在程序允许之前都未知的情况. 泛型编程在编译时就可以获知类型. 一.定义模板 模板:模板是泛型编 ...

  5. NAS基础知识

    一.什么是NAS 1.NAS的定义 NAS(Network Attached Storage:网络附属存储)按字面简单说就是连接在网络上,具备资料存储功能的装置,因此也称为"网络存储器&qu ...

  6. Lambda表达式你会用吗?

    函数式编程 在正式学习Lambda之前,我们先来了解一下什么是函数式编程 我们先看看什么是函数.函数是一种最基本的任务,一个大型程序就是一个顶层函数调用若干底层函数,这些被调用的函数又可以调用其他函数 ...

  7. LeetCode993. 二叉树的堂兄弟节点

    题目 1 class Solution { 2 public: 3 TreeNode* r1;TreeNode* r2; 4 bool isCousins(TreeNode* root, int x, ...

  8. LeetCode404.左叶子之和

    题目 法一.广度优先搜索 1 class Solution { 2 public: 3 int sumOfLeftLeaves(TreeNode* root) { 4 if(root == NULL) ...

  9. Promise.all()使用实例

    一.什么是Promise.all()? 在说这个之前要先说清楚promise.promise就是一个对象,专门用来处理异步操作的. 而Promise.all方法用于将多个 Promise 实例,包装成 ...

  10. 以我的亲身经历,聊聊学python的流程,同时推荐学python的书

    因为干活要用到,所以我大概于19年5月开始学python,大概学了1个月后,我就能干公司的活了,而且这python项目还包含了机器学习等要素,大概3个月后,我还承担了项目里开发机器学习数据分析的任务. ...