https://github.com/alibaba/fastjson/wiki/PropertyProcessable_cn
https://www.cnblogs.com/ariter/p/14254342.html
1、自定义注解用来标识json数据需要处理的属性
import java.lang.annotation.*;/*** 用于标识需要加密的字段*/
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface EncryptionField {}
2、fastJson的值过滤器,对使用【EncryptionField】标注的字段加密
import com.alibaba.fastjson.serializer.ValueFilter;
import com.sinosoft.encrypt.utils.CryptoUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;import java.lang.reflect.Field;
import java.util.Objects;/*** 对使用【EncryptionField】标注的字段加密*/
public class EncryptionFieldFilter implements ValueFilter {/*** 加密key*/@Value("${privacy.crypto.key}")private String encryptKey;public EncryptionFieldFilter() {}@Overridepublic Object process(Object object, String name, Object value) {try {Field field = object.getClass().getDeclaredField(name);if (Objects.isNull(value) || String.class != field.getType() || (field.getAnnotation(EncryptionField.class)) == null) {return value;}if (StringUtils.isEmpty(field.toString())) {return value;}return CryptoUtil.sm4Encrypt(value.toString(), encryptKey);} catch (Exception e) {}return value;}
}
3、在需要处理的属性上增加注解
import com.cbex.partyconstruction.common.annotation.EncryptionField;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;@Data
@Accessors(chain = true)
public class MyPartyManageInfo {@ApiModelProperty(value = "职工姓名")private String name;@ApiModelProperty(value = "证件类型")private String cardType;@ApiModelProperty(value = "证件号码")@EncryptionFieldprivate String cardId;
}
将对象转换成json串
public class Test {public static void main(String[] args) throws Exception {MyPartyManageInfo partyManageInfo = new MyPartyManageInfo();partyManageInfo.setCardId("111111").setCardType("居民身份证").setName("职工");String s = JSONObject.toJSONString(partyManageInfo,new EncryptionFieldFilter());System.out.println("card加密后的Json串是------"+s);}}
结果如下图,证件号码加密了

1、定义类实现PropertyProcessable 接口,处理需要处理的属性值
PropertyProcessable是1.2.35版本开始支持的自定义反序列化接口。
interface PropertyProcessable {// 返回property的类型,如果返回空,则由parser自行推断。Type getType(String name);// 处理属性值void apply(String name, Object value);
}
import com.alibaba.fastjson.parser.deserializer.PropertyProcessable;
import com.sinosoft.encrypt.utils.CryptoUtil;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;import java.lang.reflect.Type;@Data
public class MyPropertyProcessableResolver implements PropertyProcessable {@ApiModelProperty(value = "职工姓名")private String name;@ApiModelProperty(value = "证件类型")private String cardType;@ApiModelProperty(value = "证件号码")private String cardId;public MyPropertyProcessableResolver() {}@Overridepublic Type getType(String name) {return null;}@Overridepublic void apply(String name, Object value) {if(StringUtils.equals("cardId",name)){this.cardId = CryptoUtil.sm4Decrypt(value.toString(), null);}else if(StringUtils.equals("cardType",name)){this.cardType = (String) value;}else if(StringUtils.equals("name",name)){this.name = (String) value;}}
}
2、反序列化
import com.alibaba.fastjson.JSONObject;
import com.cbex.partyconstruction.common.annotation.EncryptionFieldFilter;
import com.cbex.partyconstruction.manage.domain.po.MyPartyManageInfo;
import com.cbex.partyconstruction.manage.domain.po.MyPropertyProcessableResolver;public class Test {public static void main(String[] args) throws Exception {MyPartyManageInfo partyManageInfo = new MyPartyManageInfo();partyManageInfo.setCardId("111111").setCardType("居民身份证").setName("职工");String s = JSONObject.toJSONString(partyManageInfo,new EncryptionFieldFilter());System.out.println("card加密后的Json串是------"+s);MyPropertyProcessableResolver partyManageInfoVo = JSONObject.parseObject(s, MyPropertyProcessableResolver.class);System.out.println("json串转换成对象是------"+partyManageInfoVo);}
}

上一篇:洛谷——P1077 摆花
下一篇:2023-2-10刷题情况