springboot根据配置屏蔽接口返回字段
很多时候就是为了偷懒,swagger可以屏蔽接口文档中的字段,却不能屏蔽真实返回的数据,故而需要再controller返回的时候再做处理
参考了,做了一些改动
经验证对简单接口,还可以,稍微复杂的嵌套就不行,可以使用@jsonignore,路径为
com.fasterxml.jackson.annotation.jsonignore
<dependency>
<groupid>org.aspectj</groupid>
<artifactid>aspectjweaver</artifactid>
<version>1.9.6</version>
</dependency>1.类的数据域
import lombok.allargsconstructor;
import lombok.data;
import lombok.noargsconstructor;
@noargsconstructor
@allargsconstructor
@data
public class jsonfields {
boolean include = true;
string[] fields = {};
}2.开启的注解
写在controller的方法上
import java.lang.annotation.*;
@target({ elementtype.parameter, elementtype.method})
@retention(retentionpolicy.runtime)
@documented
public @interface jsoninclude {
/**
* 排除
* @return
*/
boolean include() default true;
/**
* 字段类型
* @return
*/
class clazz();
/**
* 过滤的字段名
* @return
*/
string[] fields() default {};
}3.json过滤器
import com.fasterxml.jackson.core.jsongenerator;
import com.fasterxml.jackson.databind.serializerprovider;
import com.fasterxml.jackson.databind.ser.beanpropertyfilter;
import com.fasterxml.jackson.databind.ser.filterprovider;
import com.fasterxml.jackson.databind.ser.propertywriter;
import com.fasterxml.jackson.databind.ser.propertyfilter;
import com.fasterxml.jackson.databind.ser.impl.simplebeanpropertyfilter;
import java.util.hashmap;
import java.util.map;
public class jsonfilter extends filterprovider {
/**
* 对于规则我们采用 threadlocal 封装,防止出现线程安全问题
*/
private static final threadlocal<map<class<?>, jsonfields>> include = new threadlocal<>();
/**
* 清空规则
*/
public static void clear() {
include.remove();
}
/**
* 设置过滤规则
* @param clazz 规则
*/
public static void add(boolean isinclude, class<?> clazz, string... fields) {
map<class<?>, jsonfields> map = include.get();
if (map == null) {
map = new hashmap<>();
include.set(map);
}
jsonfields jsonfields = new jsonfields(isinclude,fields);
map.put(clazz, jsonfields);
}
/**
* 重写规律规则
*/
@override
public propertyfilter findpropertyfilter(object filterid, object valuetofilter) {
return new simplebeanpropertyfilter() {
@override
public void serializeasfield(
object pojo,
jsongenerator jg,
serializerprovider sp,
propertywriter pw
) throws exception {
if (apply(pojo.getclass(), pw.getname())) {
pw.serializeasfield(pojo, jg, sp);
} else if (!jg.canomitfields()) {
pw.serializeasomittedfield(pojo, jg, sp);
}
}
};
}
@deprecated
@override
public beanpropertyfilter findfilter(object filterid) {
throw new unsupportedoperationexception("不支持访问即将过期的过滤器");
}
/**
* 判断该字段是否需要,返回 true 序列化,返回 false 则过滤
* @param type 实体类类型
* @param name 字段名
*/
public boolean apply(class<?> type, string name) {
map<class<?>, jsonfields> map = include.get();
if (map == null) {
return true;
}
jsonfields jsonfields = map.get(type);
string[] fields = jsonfields.getfields();
if (jsonfields.isinclude()){
for (string field : fields) {
if (field.equals(name)) {
return true;
}
}
return false;
} else{
for (string field : fields) {
if (field.equals(name)) {
return false;
}
}
return true;
}
}
}
4.过滤器切面
jsonfilter.clear();解决多线程下面的并发的问题
import lombok.extern.slf4j.slf4j;
import org.aspectj.lang.joinpoint;
import org.aspectj.lang.annotation.aspect;
import org.aspectj.lang.annotation.before;
import org.aspectj.lang.annotation.pointcut;
import org.aspectj.lang.reflect.methodsignature;
import org.springframework.stereotype.component;
import java.lang.reflect.method;
@slf4j
@component
@aspect
public class jsonfilteraop {
@pointcut("@annotation(com.tt.framework.web.filter.jsoninclude)")
public void controlleraspect(){}
/**
* (1)@annotation:用来拦截所有被某个注解修饰的方法
* (2)@within:用来拦截所有被某个注解修饰的类
* (3)within:用来指定扫描的包的范围
*/
@before("controlleraspect()")
public void dobefore(joinpoint joinpoint) throws throwable{
jsonfilter.clear();
//从切面织入点处通过反射机制获取织入点处的方法
methodsignature signature = (methodsignature) joinpoint.getsignature();
//获取切入点所在的方法
method method = signature.getmethod();
jsoninclude jsoninclude = method.getannotation(jsoninclude.class);
jsonfilter.add(jsoninclude.include(),jsoninclude.clazz(),jsoninclude.fields());
}
}5.如何使用
启动类增加此过滤器
@slf4j
@springbootapplication
public class fayserverapplication {
public static void main(string[] args) {
try {
configurableapplicationcontext context = springapplication.run(fayserverapplication.class, args);
objectmapper objectmapper = context.getbean(objectmapper.class);
objectmapper.setfilterprovider(new jsonfilter());
} finally {
log.info("server start finish");
}
}
}include = true包含则表示仅显示包含的数据,include = false则排除这配置的fields,显示没有配置的字段。
没有此注解的则不受影响
@jsoninclude(include = true,clazz = lxrjbhysth.class,fields = {"dg","mz"})
@apioperation("金不换规则")
@getmapping("jbhrule")
public responseresult<list<lxrjbhysth>> jbhrule(string dg){
list<lxrjbhysth> lxrjbhysths = extlxrjbhysthservice.selectbydg(dg);
responseresult<list<lxrjbhysth>> resp = new responseresult<>(true);
resp.setdata(lxrjbhysths);
return resp;
}总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论