JAVA注解的字段脱敏处理

有这样一个场景,系统中可以出现敏感的数据,在打印日志的时候,我们并不希望打印出现,这样,我们使用自己定义注解,来解决这个问题。

定义需要脱敏的字段规则。

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.google.gson.Gson;
import com.ucf.platform.framework.core.annotation.SensitiveInfo;
import com.ucf.platform.framework.core.log.UcfLogger;
import com.ucf.platform.framework.core.log.UcfLoggerFactory;

/**

  • @Title: SensitiveInfoUtils.java
  • @Copyright: Copyright (c) 2011
  • @Description: <br>
  •           敏感信息屏蔽工具&lt;br&gt;
    

*/
public final class SensitiveInfoUtils {

<span class="hljs-keyword">private</span> final <span class="hljs-keyword">static</span> <span class="hljs-title class_">UcfLogger</span> logger = <span class="hljs-title class_">UcfLoggerFactory</span>.<span class="hljs-title function_">getLogger</span>(<span class="hljs-title class_">SensitiveInfoUtils</span>.<span class="hljs-property">class</span>);

<span class="hljs-comment">/**
 * [中文姓名] 只显示第一个汉字,其他隐藏为2个星号&lt;例子:李**&gt;
 * 
 * <span class="hljs-doctag">@param</span> <span class="hljs-variable">name</span>
 * <span class="hljs-doctag">@return</span>
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-title class_">String</span> <span class="hljs-title function_">chineseName</span>(<span class="hljs-params"><span class="hljs-built_in">String</span> fullName</span>) {
    <span class="hljs-keyword">if</span> (<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">isBlank</span>(fullName)) {
        <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>;
    }
    <span class="hljs-title class_">String</span> name = <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">left</span>(fullName, <span class="hljs-number">1</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">rightPad</span>(name, <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">length</span>(fullName), <span class="hljs-string">"*"</span>);
}

<span class="hljs-comment">/**
 * [中文姓名] 只显示第一个汉字,其他隐藏为2个星号&lt;例子:李**&gt;
 * 
 * <span class="hljs-doctag">@param</span> <span class="hljs-variable">familyName</span>
 * <span class="hljs-doctag">@param</span> <span class="hljs-variable">givenName</span>
 * <span class="hljs-doctag">@return</span>
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-title class_">String</span> <span class="hljs-title function_">chineseName</span>(<span class="hljs-params"><span class="hljs-built_in">String</span> familyName, <span class="hljs-built_in">String</span> givenName</span>) {
    <span class="hljs-keyword">if</span> (<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">isBlank</span>(familyName) || <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">isBlank</span>(givenName)) {
        <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>;
    }
    <span class="hljs-keyword">return</span> <span class="hljs-title function_">chineseName</span>(familyName + givenName);
}

<span class="hljs-comment">/**
 * [身份证号] 显示最后四位,其他隐藏。共计18位或者15位。&lt;例子:*************5762&gt;
 * 
 * <span class="hljs-doctag">@param</span> <span class="hljs-variable">id</span>
 * <span class="hljs-doctag">@return</span>
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-title class_">String</span> <span class="hljs-title function_">idCardNum</span>(<span class="hljs-params"><span class="hljs-built_in">String</span> id</span>) {
    <span class="hljs-keyword">if</span> (<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">isBlank</span>(id)) {
        <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>;
    }
    <span class="hljs-title class_">String</span> num = <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">right</span>(id, <span class="hljs-number">4</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">leftPad</span>(num, <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">length</span>(id), <span class="hljs-string">"*"</span>);
}

<span class="hljs-comment">/**
 * [固定电话] 后四位,其他隐藏&lt;例子:****1234&gt;
 * 
 * <span class="hljs-doctag">@param</span> <span class="hljs-variable">num</span>
 * <span class="hljs-doctag">@return</span>
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-title class_">String</span> <span class="hljs-title function_">fixedPhone</span>(<span class="hljs-params"><span class="hljs-built_in">String</span> num</span>) {
    <span class="hljs-keyword">if</span> (<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">isBlank</span>(num)) {
        <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>;
    }
    <span class="hljs-keyword">return</span> <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">leftPad</span>(<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">right</span>(num, <span class="hljs-number">4</span>), <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">length</span>(num), <span class="hljs-string">"*"</span>);
}

<span class="hljs-comment">/**
 * [手机号码] 前三位,后四位,其他隐藏&lt;例子:138******1234&gt;
 * 
 * <span class="hljs-doctag">@param</span> <span class="hljs-variable">num</span>
 * <span class="hljs-doctag">@return</span>
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-title class_">String</span> <span class="hljs-title function_">mobilePhone</span>(<span class="hljs-params"><span class="hljs-built_in">String</span> num</span>) {
    <span class="hljs-keyword">if</span> (<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">isBlank</span>(num)) {
        <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>;
    }
    <span class="hljs-keyword">return</span> <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">left</span>(num, <span class="hljs-number">3</span>).<span class="hljs-title function_">concat</span>(<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">removeStart</span>(<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">leftPad</span>(<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">right</span>(num, <span class="hljs-number">4</span>), <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">length</span>(num), <span class="hljs-string">"*"</span>), <span class="hljs-string">"***"</span>));
}

<span class="hljs-comment">/**
 * [地址] 只显示到地区,不显示详细地址;我们要对个人信息增强保护&lt;例子:北京市海淀区****&gt;
 * 
 * <span class="hljs-doctag">@param</span> <span class="hljs-variable">address</span>
 * <span class="hljs-doctag">@param</span> <span class="hljs-variable">sensitiveSize</span>
 *            敏感信息长度
 * <span class="hljs-doctag">@return</span>
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-title class_">String</span> <span class="hljs-title function_">address</span>(<span class="hljs-params"><span class="hljs-built_in">String</span> address, int sensitiveSize</span>) {
    <span class="hljs-keyword">if</span> (<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">isBlank</span>(address)) {
        <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>;
    }
    int length = <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">length</span>(address);
    <span class="hljs-keyword">return</span> <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">rightPad</span>(<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">left</span>(address, length - sensitiveSize), length, <span class="hljs-string">"*"</span>);
}

<span class="hljs-comment">/**
 * [电子邮箱] 邮箱前缀仅显示第一个字母,前缀其他隐藏,用星号代替,@及后面的地址显示&lt;例子:g**@163.com&gt;
 * 
 * <span class="hljs-doctag">@param</span> <span class="hljs-variable">email</span>
 * <span class="hljs-doctag">@return</span>
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-title class_">String</span> <span class="hljs-title function_">email</span>(<span class="hljs-params"><span class="hljs-built_in">String</span> email</span>) {
    <span class="hljs-keyword">if</span> (<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">isBlank</span>(email)) {
        <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>;
    }
    int index = <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">indexOf</span>(email, <span class="hljs-string">"@"</span>);
    <span class="hljs-keyword">if</span> (index &lt;= <span class="hljs-number">1</span>)
        <span class="hljs-keyword">return</span> email;
    <span class="hljs-keyword">else</span>
        <span class="hljs-keyword">return</span> <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">rightPad</span>(<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">left</span>(email, <span class="hljs-number">1</span>), index, <span class="hljs-string">"*"</span>).<span class="hljs-title function_">concat</span>(<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">mid</span>(email, index, <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">length</span>(email)));
}

<span class="hljs-comment">/**
 * [银行卡号] 前六位,后四位,其他用星号隐藏每位1个星号&lt;例子:6222600**********1234&gt;
 * 
 * <span class="hljs-doctag">@param</span> <span class="hljs-variable">cardNum</span>
 * <span class="hljs-doctag">@return</span>
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-title class_">String</span> <span class="hljs-title function_">bankCard</span>(<span class="hljs-params"><span class="hljs-built_in">String</span> cardNum</span>) {
    <span class="hljs-keyword">if</span> (<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">isBlank</span>(cardNum)) {
        <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>;
    }
    <span class="hljs-keyword">return</span> <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">left</span>(cardNum, <span class="hljs-number">6</span>).<span class="hljs-title function_">concat</span>(<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">removeStart</span>(<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">leftPad</span>(<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">right</span>(cardNum, <span class="hljs-number">4</span>), <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">length</span>(cardNum), <span class="hljs-string">"*"</span>), <span class="hljs-string">"******"</span>));
}

<span class="hljs-comment">/**
 * [公司开户银行联号] 公司开户银行联行号,显示前两位,其他用星号隐藏,每位1个星号&lt;例子:12********&gt;
 * 
 * <span class="hljs-doctag">@param</span> <span class="hljs-variable">code</span>
 * <span class="hljs-doctag">@return</span>
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-title class_">String</span> <span class="hljs-title function_">cnapsCode</span>(<span class="hljs-params"><span class="hljs-built_in">String</span> code</span>) {
    <span class="hljs-keyword">if</span> (<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">isBlank</span>(code)) {
        <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>;
    }
    <span class="hljs-keyword">return</span> <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">rightPad</span>(<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">left</span>(code, <span class="hljs-number">2</span>), <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">length</span>(code), <span class="hljs-string">"*"</span>);
}

<span class="hljs-comment">/**
 * 获取脱敏json串 &lt;注意:递归引用会导致java.lang.StackOverflowError&gt;
 * 
 * <span class="hljs-doctag">@param</span> <span class="hljs-variable">javaBean</span>
 * <span class="hljs-doctag">@return</span>
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-title class_">String</span> <span class="hljs-title function_">getJson</span>(<span class="hljs-params"><span class="hljs-built_in">Object</span> javaBean</span>) {
    <span class="hljs-title class_">String</span> json = <span class="hljs-literal">null</span>;
    <span class="hljs-keyword">if</span> (<span class="hljs-literal">null</span> != javaBean) {
        <span class="hljs-title class_">Class</span>&lt;? <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Object</span>&gt; raw = javaBean.<span class="hljs-title function_">getClass</span>();
        <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">if</span> (raw.<span class="hljs-title function_">isInterface</span>())
                <span class="hljs-keyword">return</span> json;
            <span class="hljs-title class_">Gson</span> g = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Gson</span>();
            <span class="hljs-title class_">Object</span> clone = g.<span class="hljs-title function_">fromJson</span>(g.<span class="hljs-title function_">toJson</span>(javaBean, javaBean.<span class="hljs-title function_">getClass</span>()), javaBean.<span class="hljs-title function_">getClass</span>());
            <span class="hljs-title class_">Set</span>&lt;<span class="hljs-title class_">Integer</span>&gt; referenceCounter = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashSet</span>&lt;<span class="hljs-title class_">Integer</span>&gt;();
            <span class="hljs-title class_">SensitiveInfoUtils</span>.<span class="hljs-title function_">replace</span>(<span class="hljs-title class_">SensitiveInfoUtils</span>.<span class="hljs-title function_">findAllField</span>(raw), clone, referenceCounter);
            json = <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">toJSONString</span>(clone, <span class="hljs-title class_">SerializerFeature</span>.<span class="hljs-property">WriteMapNullValue</span>, <span class="hljs-title class_">SerializerFeature</span>.<span class="hljs-property">WriteNullListAsEmpty</span>);
            referenceCounter.<span class="hljs-title function_">clear</span>();
            referenceCounter = <span class="hljs-literal">null</span>;
        } <span class="hljs-keyword">catch</span> (<span class="hljs-title class_">Throwable</span> e) {
            logger.<span class="hljs-title function_">error</span>(<span class="hljs-string">"SensitiveInfoUtils.getJson() ERROR"</span>, e);
        }
    }
    <span class="hljs-keyword">return</span> json;
}

<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-title class_">Field</span>[] <span class="hljs-title function_">findAllField</span>(<span class="hljs-params">Class&lt;?&gt; clazz</span>) {
    <span class="hljs-title class_">Field</span>[] fileds = clazz.<span class="hljs-title function_">getDeclaredFields</span>();
    <span class="hljs-keyword">while</span> (<span class="hljs-literal">null</span> != clazz.<span class="hljs-title function_">getSuperclass</span>() &amp;&amp; !<span class="hljs-title class_">Object</span>.<span class="hljs-property">class</span>.<span class="hljs-title function_">equals</span>(clazz.<span class="hljs-title function_">getSuperclass</span>())) {
        fileds = (<span class="hljs-title class_">Field</span>[]) <span class="hljs-title class_">ArrayUtils</span>.<span class="hljs-title function_">addAll</span>(fileds, clazz.<span class="hljs-title function_">getSuperclass</span>().<span class="hljs-title function_">getDeclaredFields</span>());
        clazz = clazz.<span class="hljs-title function_">getSuperclass</span>();
    }
    <span class="hljs-keyword">return</span> fileds;
}
<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-built_in">void</span> <span class="hljs-title function_">replace</span>(<span class="hljs-title class_">Field</span>[] fields, <span class="hljs-title class_">Object</span> javaBean, <span class="hljs-title class_">Set</span>&lt;<span class="hljs-title class_">Integer</span>&gt; referenceCounter) throws <span class="hljs-title class_">IllegalArgumentException</span>, <span class="hljs-title class_">IllegalAccessException</span> {
    <span class="hljs-keyword">if</span> (<span class="hljs-literal">null</span> != fields &amp;&amp; fields.<span class="hljs-property">length</span> &gt; <span class="hljs-number">0</span>) {
        <span class="hljs-keyword">for</span> (<span class="hljs-title class_">Field</span> field : fields) {
            field.<span class="hljs-title function_">setAccessible</span>(<span class="hljs-literal">true</span>);
            <span class="hljs-keyword">if</span> (<span class="hljs-literal">null</span> != field &amp;&amp; <span class="hljs-literal">null</span> != javaBean) {
                <span class="hljs-title class_">Object</span> value = field.<span class="hljs-title function_">get</span>(javaBean);
                <span class="hljs-keyword">if</span> (<span class="hljs-literal">null</span> != value) {
                    <span class="hljs-title class_">Class</span>&lt;?&gt; <span class="hljs-keyword">type</span> = value.<span class="hljs-title function_">getClass</span>();
                    <span class="hljs-comment">// 1.处理子属性,包括集合中的</span>
                    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">type</span>.<span class="hljs-title function_">isArray</span>()) {
                        int len = <span class="hljs-title class_">Array</span>.<span class="hljs-title function_">getLength</span>(value);
                        <span class="hljs-keyword">for</span> (int i = <span class="hljs-number">0</span>; i &lt; len; i++) {
                            <span class="hljs-title class_">Object</span> arrayObject = <span class="hljs-title class_">Array</span>.<span class="hljs-title function_">get</span>(value, i);
                            <span class="hljs-title class_">SensitiveInfoUtils</span>.<span class="hljs-title function_">replace</span>(<span class="hljs-title class_">SensitiveInfoUtils</span>.<span class="hljs-title function_">findAllField</span>(arrayObject.<span class="hljs-title function_">getClass</span>()), arrayObject, referenceCounter);
                        }
                    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (value <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Collection</span>&lt;?&gt;) {
                        <span class="hljs-title class_">Collection</span>&lt;?&gt; c = (<span class="hljs-title class_">Collection</span>&lt;?&gt;) value;
                        <span class="hljs-title class_">Iterator</span>&lt;?&gt; it = c.<span class="hljs-title function_">iterator</span>();
                        <span class="hljs-keyword">while</span> (it.<span class="hljs-title function_">hasNext</span>()) {
                            <span class="hljs-title class_">Object</span> collectionObj = it.<span class="hljs-title function_">next</span>();
                            <span class="hljs-title class_">SensitiveInfoUtils</span>.<span class="hljs-title function_">replace</span>(<span class="hljs-title class_">SensitiveInfoUtils</span>.<span class="hljs-title function_">findAllField</span>(collectionObj.<span class="hljs-title function_">getClass</span>()), collectionObj, referenceCounter);
                        }
                    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (value <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Map</span>&lt;?, ?&gt;) {
                        <span class="hljs-title class_">Map</span>&lt;?, ?&gt; m = (<span class="hljs-title class_">Map</span>&lt;?, ?&gt;) value;
                        <span class="hljs-title class_">Set</span>&lt;?&gt; set = m.<span class="hljs-title function_">entrySet</span>();
                        <span class="hljs-keyword">for</span> (<span class="hljs-title class_">Object</span> o : set) {
                            <span class="hljs-title class_">Entry</span>&lt;?, ?&gt; entry = (<span class="hljs-title class_">Entry</span>&lt;?, ?&gt;) o;
                            <span class="hljs-title class_">Object</span> mapVal = entry.<span class="hljs-title function_">getValue</span>();
                            <span class="hljs-title class_">SensitiveInfoUtils</span>.<span class="hljs-title function_">replace</span>(<span class="hljs-title class_">SensitiveInfoUtils</span>.<span class="hljs-title function_">findAllField</span>(mapVal.<span class="hljs-title function_">getClass</span>()), mapVal, referenceCounter);
                        }
                    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (!<span class="hljs-keyword">type</span>.<span class="hljs-title function_">isPrimitive</span>()
                               &amp;&amp; !<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">startsWith</span>(<span class="hljs-keyword">type</span>.<span class="hljs-title function_">getPackage</span>().<span class="hljs-title function_">getName</span>(), <span class="hljs-string">"javax."</span>)
                               &amp;&amp; !<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">startsWith</span>(<span class="hljs-keyword">type</span>.<span class="hljs-title function_">getPackage</span>().<span class="hljs-title function_">getName</span>(), <span class="hljs-string">"java."</span>)
                               &amp;&amp; !<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">startsWith</span>(field.<span class="hljs-title function_">getType</span>().<span class="hljs-title function_">getName</span>(), <span class="hljs-string">"javax."</span>)
                               &amp;&amp; !<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">startsWith</span>(field.<span class="hljs-title function_">getName</span>(), <span class="hljs-string">"java."</span>)
                               &amp;&amp; referenceCounter.<span class="hljs-title function_">add</span>(value.<span class="hljs-title function_">hashCode</span>())) {
                        <span class="hljs-title class_">SensitiveInfoUtils</span>.<span class="hljs-title function_">replace</span>(<span class="hljs-title class_">SensitiveInfoUtils</span>.<span class="hljs-title function_">findAllField</span>(<span class="hljs-keyword">type</span>), value, referenceCounter);
                    }
                }
                <span class="hljs-comment">// 2. 处理自身的属性</span>
                <span class="hljs-title class_">SensitiveInfo</span> annotation = field.<span class="hljs-title function_">getAnnotation</span>(<span class="hljs-title class_">SensitiveInfo</span>.<span class="hljs-property">class</span>);
                <span class="hljs-keyword">if</span> (field.<span class="hljs-title function_">getType</span>().<span class="hljs-title function_">equals</span>(<span class="hljs-title class_">String</span>.<span class="hljs-property">class</span>) &amp;&amp; <span class="hljs-literal">null</span> != annotation) {
                    <span class="hljs-title class_">String</span> valueStr = (<span class="hljs-title class_">String</span>) value;
                    <span class="hljs-keyword">if</span> (<span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">isNotBlank</span>(valueStr)) {
                        <span class="hljs-keyword">switch</span> (annotation.<span class="hljs-title function_">type</span>()) {
                            <span class="hljs-keyword">case</span> <span class="hljs-attr">CHINESE_NAME</span>: {
                                field.<span class="hljs-title function_">set</span>(javaBean, <span class="hljs-title class_">SensitiveInfoUtils</span>.<span class="hljs-title function_">chineseName</span>(valueStr));
                                <span class="hljs-keyword">break</span>;
                            }
                            <span class="hljs-keyword">case</span> <span class="hljs-attr">ID_CARD</span>: {
                                field.<span class="hljs-title function_">set</span>(javaBean, <span class="hljs-title class_">SensitiveInfoUtils</span>.<span class="hljs-title function_">idCardNum</span>(valueStr));
                                <span class="hljs-keyword">break</span>;
                            }
                            <span class="hljs-keyword">case</span> <span class="hljs-attr">FIXED_PHONE</span>: {
                                field.<span class="hljs-title function_">set</span>(javaBean, <span class="hljs-title class_">SensitiveInfoUtils</span>.<span class="hljs-title function_">fixedPhone</span>(valueStr));
                                <span class="hljs-keyword">break</span>;
                            }
                            <span class="hljs-keyword">case</span> <span class="hljs-attr">MOBILE_PHONE</span>: {
                                field.<span class="hljs-title function_">set</span>(javaBean, <span class="hljs-title class_">SensitiveInfoUtils</span>.<span class="hljs-title function_">mobilePhone</span>(valueStr));
                                <span class="hljs-keyword">break</span>;
                            }
                            <span class="hljs-keyword">case</span> <span class="hljs-attr">ADDRESS</span>: {
                                field.<span class="hljs-title function_">set</span>(javaBean, <span class="hljs-title class_">SensitiveInfoUtils</span>.<span class="hljs-title function_">address</span>(valueStr, <span class="hljs-number">4</span>));
                                <span class="hljs-keyword">break</span>;
                            }
                            <span class="hljs-keyword">case</span> <span class="hljs-attr">EMAIL</span>: {
                                field.<span class="hljs-title function_">set</span>(javaBean, <span class="hljs-title class_">SensitiveInfoUtils</span>.<span class="hljs-title function_">email</span>(valueStr));
                                <span class="hljs-keyword">break</span>;
                            }
                            <span class="hljs-keyword">case</span> <span class="hljs-attr">BANK_CARD</span>: {
                                field.<span class="hljs-title function_">set</span>(javaBean, <span class="hljs-title class_">SensitiveInfoUtils</span>.<span class="hljs-title function_">bankCard</span>(valueStr));
                                <span class="hljs-keyword">break</span>;
                            }
                            <span class="hljs-keyword">case</span> <span class="hljs-attr">CNAPS_CODE</span>: {
                                field.<span class="hljs-title function_">set</span>(javaBean, <span class="hljs-title class_">SensitiveInfoUtils</span>.<span class="hljs-title function_">cnapsCode</span>(valueStr));
                                <span class="hljs-keyword">break</span>;
                            }
                        }
                    }
                }
            }
        }
    }
}

//----------------------------------------------------------------------------------------------
public static Method [] findAllMethod(Class<?> clazz){
Method [] methods= clazz.getMethods();
return methods;
}

//----------------------------------------------------------------------------------------------
public static enum SensitiveType {
/**
* 中文名
*/

CHINESE_NAME,

    <span class="hljs-comment">/**
     * 身份证号
     */</span>
    <span class="hljs-variable constant_">ID_CARD</span>,
    <span class="hljs-comment">/**
     * 座机号
     */</span>
    <span class="hljs-variable constant_">FIXED_PHONE</span>,
    <span class="hljs-comment">/**
     * 手机号
     */</span>
    <span class="hljs-variable constant_">MOBILE_PHONE</span>,
    <span class="hljs-comment">/**
     * 地址
     */</span>
    <span class="hljs-variable constant_">ADDRESS</span>,
    <span class="hljs-comment">/**
     * 电子邮件
     */</span>
    <span class="hljs-variable constant_">EMAIL</span>,
    <span class="hljs-comment">/**
     * 银行卡
     */</span>
    <span class="hljs-variable constant_">BANK_CARD</span>,
    <span class="hljs-comment">/**
     * 公司开户银行联号
     */</span>
    <span class="hljs-variable constant_">CNAPS_CODE</span>;
}

}

声明注解:

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import com.ucf.platform.framework.core.util.SensitiveInfoUtils;

/**

  • @Title: SensitiveInfo.java
  • @Copyright: Copyright (c) 2015
  • @Description: <br>
  •           敏感信息注解标记 &lt;br&gt;
    

*/
@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface SensitiveInfo {

<span class="hljs-keyword">public</span> SensitiveInfoUtils.SensitiveType <span class="hljs-title function_">type</span><span class="hljs-params">()</span> ;

}

测试:

public class JavaBeanA {
<span class="hljs-keyword">public</span> <span class="hljs-title class_">JavaBeanA</span>(<span class="hljs-title class_">String</span> name,<span class="hljs-title class_">String</span> id){
    
}

<span class="hljs-meta">@SensitiveInfo</span>(<span class="hljs-keyword">type</span>=<span class="hljs-title class_">SensitiveType</span>.<span class="hljs-property">CHINESE_NAME</span>)
<span class="hljs-keyword">private</span> <span class="hljs-title class_">String</span> name = <span class="hljs-string">"A先生"</span>;

<span class="hljs-keyword">private</span> <span class="hljs-title class_">JavaBeanB</span> b;

<span class="hljs-keyword">private</span> <span class="hljs-title class_">Date</span> date;

<span class="hljs-keyword">private</span> <span class="hljs-title class_">List</span>&lt;<span class="hljs-title class_">JavaBeanB</span>&gt; list;

<span class="hljs-keyword">private</span> <span class="hljs-title class_">Map</span>&lt;<span class="hljs-title class_">String</span>,<span class="hljs-title class_">JavaBeanB</span>&gt; map;

<span class="hljs-keyword">public</span> <span class="hljs-title class_">String</span> <span class="hljs-title function_">getName</span>(<span class="hljs-params"></span>) {
    <span class="hljs-keyword">return</span> name;
}

<span class="hljs-keyword">public</span> <span class="hljs-built_in">void</span> <span class="hljs-title function_">setName</span>(<span class="hljs-params"><span class="hljs-built_in">String</span> name</span>) {
    <span class="hljs-variable language_">this</span>.<span class="hljs-property">name</span> = name;
}

<span class="hljs-keyword">public</span> <span class="hljs-title class_">JavaBeanB</span> <span class="hljs-title function_">getB</span>(<span class="hljs-params"></span>) {
    <span class="hljs-keyword">return</span> b;
}

<span class="hljs-keyword">public</span> <span class="hljs-built_in">void</span> <span class="hljs-title function_">setB</span>(<span class="hljs-params">JavaBeanB b</span>) {
    <span class="hljs-variable language_">this</span>.<span class="hljs-property">b</span> = b;
}

<span class="hljs-keyword">public</span> <span class="hljs-title class_">List</span>&lt;<span class="hljs-title class_">JavaBeanB</span>&gt; <span class="hljs-title function_">getList</span>(<span class="hljs-params"></span>) {
    <span class="hljs-keyword">return</span> list;
}

<span class="hljs-keyword">public</span> <span class="hljs-built_in">void</span> <span class="hljs-title function_">setList</span>(<span class="hljs-params">List&lt;JavaBeanB&gt; list</span>) {
    <span class="hljs-variable language_">this</span>.<span class="hljs-property">list</span> = list;
}

<span class="hljs-keyword">public</span> <span class="hljs-title class_">Map</span>&lt;<span class="hljs-title class_">String</span>, <span class="hljs-title class_">JavaBeanB</span>&gt; <span class="hljs-title function_">getMap</span>(<span class="hljs-params"></span>) {
    <span class="hljs-keyword">return</span> map;
}

<span class="hljs-keyword">public</span> <span class="hljs-built_in">void</span> <span class="hljs-title function_">setMap</span>(<span class="hljs-params"><span class="hljs-built_in">Map</span>&lt;<span class="hljs-built_in">String</span>, JavaBeanB&gt; map</span>) {
    <span class="hljs-variable language_">this</span>.<span class="hljs-property">map</span> = map;
}

<span class="hljs-keyword">public</span> <span class="hljs-title class_">Date</span> <span class="hljs-title function_">getDate</span>(<span class="hljs-params"></span>) {
    <span class="hljs-keyword">return</span> date;
}

<span class="hljs-keyword">public</span> <span class="hljs-built_in">void</span> <span class="hljs-title function_">setDate</span>(<span class="hljs-params"><span class="hljs-built_in">Date</span> date</span>) {
    <span class="hljs-variable language_">this</span>.<span class="hljs-property">date</span> = date;
}

}

public class JavaBeanB {
    @SensitiveInfo(type=SensitiveType.CHINESE_NAME)
    private String name = "B 先生";
    
    private JavaBeanA a;
    
    private Set<JavaBeanA> list;
    
    private Map<String,JavaBeanA> map;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public JavaBeanA getA() {
        return a;
    }
 
    public void setA(JavaBeanA a) {
        this.a = a;
    }
 
    public Set<JavaBeanA> getList() {
        return list;
    }
 
    public void setList(Set<JavaBeanA> list) {
        this.list = list;
    }
 
    public Map<String, JavaBeanA> getMap() {
        return map;
    }
 
    public void setMap(Map<String, JavaBeanA> map) {
        this.map = map;
    }
}
public class SensitiveInfoUtilsTest {
    
    /**
     * [中文姓名] 只显示第一个汉字,其他隐藏为 2 个星号 < 例子:李 **>
     */
    @Test
    public void testChineseNameString() {
        System.out.println(SensitiveInfoUtils.chineseName("李先生"));
    }
 
    /**
     * [中文姓名] 只显示第一个汉字,其他隐藏为 2 个星号 < 例子:李 **>
     */
    @Test
    public void testChineseNameStringString() {
        System.out.println(SensitiveInfoUtils.chineseName("李","雷"));
    }
 
    /**
     * [身份证号] 显示最后四位,其他隐藏。共计 18 位或者 15 位。< 例子:*************5762>
     */
    @Test
    public void testIdCardNum() {
        System.out.println(SensitiveInfoUtils.idCardNum("1103541983073188711"));
    }
 
    /**
     * [固定电话] 后四位,其他隐藏 < 例子:****1234>
     */
    @Test
    public void testFixedPhone() {
        System.out.println(SensitiveInfoUtils.fixedPhone("01077482277"));
    }
 
    /**
     * [手机号码] 前三位,后四位,其他隐藏 < 例子:138******1234>
     */
    @Test
    public void testMobilePhone() {
        System.out.println(SensitiveInfoUtils.mobilePhone("13777446578"));
    }
 
    /**
     * [地址] 只显示到地区,不显示详细地址;我们要对个人信息增强保护 < 例子:北京市海淀区 ****>
     */
    @Test
    public void testAddress() {
        System.out.println(SensitiveInfoUtils.address("北京朝阳区酒仙桥中路 26 号院 4 号楼人人大厦",8));
    }
 
    /**
     * [电子邮箱] 邮箱前缀仅显示第一个字母,前缀其他隐藏,用星号代替,@及后面的地址显示 < 例子:g**@163.com>
     */
    @Test
    public void testEmail() {
        System.out.println(SensitiveInfoUtils.email("66374777@qq.com"));
    }
 
    /**
     * [银行卡号] 前六位,后四位,其他用星号隐藏每位 1 个星号 < 例子:6222600**********1234>
     */
    @Test
    public void testBankCard() {
        System.out.println(SensitiveInfoUtils.bankCard("6228480402565890018"));
    }
 
    /**
     *  [公司开户银行联号] 公司开户银行联行号, 显示前两位,其他用星号隐藏,每位 1 个星号 < 例子:12********>
     */
    @Test
    public void testCnapsCode() {
        System.out.println(SensitiveInfoUtils.cnapsCode("102100029679"));
    }
 
    /**
     * 获取脱敏 json 串 < 注意:递归引用会导致 java.lang.StackOverflowError>
     */
    @Test
    public void testGetJson() {
//        ThreadPoolExecutor consumeExecutor = new ThreadPoolExecutor(30, 30 + 10, 5, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(30 + 10), new ThreadFactory() {
//            @Override
//            public Thread newThread(Runnable r) {
//                Thread myThread = new Thread(r);
//                myThread.setName("TT");
//                return myThread;
//            }
//        }, new ThreadPoolExecutor.CallerRunsPolicy());
//        while (true) {
//            consumeExecutor.execute(new Runnable() {
//                @Override
//                public void run(){}
//            });
//        }
 
        JavaBeanA a1 = new JavaBeanA("","");
        JavaBeanA a2 = new JavaBeanA("","");
        JavaBeanB b1 = new JavaBeanB();
        a1.setB(b1);
//        a1.setDate(new Date());
        
        List<JavaBeanB> a1l = new ArrayList<JavaBeanB>();
        a1l.add(b1);
        a1.setList(a1l);
        Map<String, JavaBeanB> a1m = new HashMap<String, JavaBeanB>();
        a1m.put("b1", b1);
        a1.setMap(a1m);
 
        b1.setA(a2);
        Set<JavaBeanA> b1l = new HashSet<JavaBeanA>();
        b1.setList(b1l);
        Map<String, JavaBeanA> b1m = new HashMap<String, JavaBeanA>();
        b1m.put("a2", a2);
        b1.setMap(b1m);
        long t = System.currentTimeMillis();
        System.out.println(t);
        System.out.println(SensitiveInfoUtils.getJson(a1));
        System.out.println(System.currentTimeMillis()-t);
        System.out.println(JSON.toJSON(a1));
        System.out.println(System.currentTimeMillis()-t);
    
    }
}

测试结果:

李**
李*
***************8711
*******2277
137****6578
北京朝阳区酒仙桥中路26号********
6*******@qq.com
622848*********0018
10**********
1443435915750
{"b":{"a":{"b":null,"date":null,"list":[],"map":null,"name":"A**"},"list":[],"map":{"a2":{"b":null,"date":null,"list":[],"map":null,"name":"A**"}},"name":"B**"},"date":null,"list":[{"a":{"b":null,"date":null,"list":[],"map":null,"name":"A**"},"list":[],"map":{"a2":{"b":null,"date":null,"list":[],"map":null,"name":"A**"}},"name":"B**"}],"map":{"b1":{"a":{"b":null,"date":null,"list":[],"map":null,"name":"A**"},"list":[],"map":{"a2":{"b":null,"date":null,"list":[],"map":null,"name":"A**"}},"name":"B**"}},"name":"A**"}
289
{"b":{"a":{"name":"A 先生"},"list":[],"map":{"a2":{"name":"A 先生"}},"name":"B 先生"},"list":[{"a":{"name":"A 先生"},"list":[],"map":{"a2":{"name":"A 先生"}},"name":"B 先生"}],"map":{"b1":{"a":{"name":"A 先生"},"list":[],"map":{"a2":{"name":"A 先生"}},"name":"B 先生"}},"name":"A 先生"}
300

使用了 google 的 API, 可以使用 maven 在添加, 配置如下:

<!-- gson -->
		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
		</dependency>

说明:在需要脱敏的字段上使用定义好的注解,在具体的使用时用SensitiveInfoUtils.getJson(a1),如果不需要脱敏的输出,尽量不要打印JSON,使用对象的toString()输出。效率更高。