FastJson序列化和反序列化时处理数据
- 序列化时处理数据
- 反序列化时处理json数据中的值
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() {
}
@Override
public 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 = "证件号码")
@EncryptionField
private 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);
}
}
结果如下图,证件号码加密了
反序列化时处理json数据中的值
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() {
}
@Override
public Type getType(String name) {
return null;
}
@Override
public 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);
}
}