目前主流的请求方式基本都是JSON格式传递数据和返回数据,所以本文已json格式来实现该需求。JSON序列化方式使用的是springboot默认的jackson。
之前有一个项目的需求要针对不同的用户权限来判断是否展示用户的完整手机号,我最终选择了在序列化的时候来进行过滤,jackson可以在类的属性上指定序列化的实现类,所以可以通过在序列化的输入输出类上增加注解指定自定义序列化方法,然后在该方法内实现过滤功能。
jackson指定序列化实现方式:
import java.io.IOException;
import org.apache.commons.lang3.StringUtils;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
public class MobileJsonSerialize extends JsonSerializer<String> {
// 是否显示完整手机参数
private static ThreadLocal<Boolean> showMobile = new ThreadLocal<>();
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
//是否显示完整手机
Boolean showStatus = showMobile.get();
if (showStatus != null && showStatus) {
gen.writeString(value);
} else {
if (StringUtils.isEmpty(value) || (value.length() != 11)) {
gen.writeString(value);
}
gen.writeString(value.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
}
}
public static void setShowMobile(Boolean showMobileStatus) {
showMobile.set(showMobileStatus);
}
public static void removeShowMobile() {
showMobile.remove();
}
}
序列化类使用方法:
如下通过JsonSerialize注解来制定自己写的序列化方式
public class DemoVo {
private Long id;
private String name;
@JsonSerialize(using = MobileJsonSerialize.class)
private String mobile;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
}
因为需求是根据人的权限来判断是否需要显示,所以我将判断参数放在了MobileJsonSerialize内,里面有个ThreadLocal来做线程间隔离,设置显示权限ThreadLocal可以在拦截器内进行用户是否登陆校验的时候顺带将该参数设置进去。当然ThreadLocal不是必须的,可自行选择传递值的方式。
需要注意的是,因为springMVC的请求处理是一个线程池,所以每次请求需要在拦截器开头调用removeShowMobile方法,防止ThreadLocal带来的污染,因为你不知道这个线程上次一处理的请求是哪个用户,所以需要每次都强制清空,防止由if判断造成权限污染。