springboot如何根據(jù)配置屏蔽接口返回字段
springboot根據(jù)配置屏蔽接口返回字段
很多時(shí)候就是為了偷懶,swagger可以屏蔽接口文檔中的字段,卻不能屏蔽真實(shí)返回的數(shù)據(jù),故而需要再controller返回的時(shí)候再做處理
參考了springboot2 jackson實(shí)現(xiàn)動(dòng)態(tài)返回類字段,做了一些改動(dòng)
經(jīng)驗(yàn)證對簡單接口,還可以,稍微復(fù)雜的嵌套就不行,可以使用@JsonIgnore,路徑為
com.fasterxml.jackson.annotation.JsonIgnore
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>1.類的數(shù)據(jù)域
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 {
/**
* 對于規(guī)則我們采用 ThreadLocal 封裝,防止出現(xiàn)線程安全問題
*/
private static final ThreadLocal<Map<Class<?>, JsonFields>> include = new ThreadLocal<>();
/**
* 清空規(guī)則
*/
public static void clear() {
include.remove();
}
/**
* 設(shè)置過濾規(guī)則
* @param clazz 規(guī)則
*/
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);
}
/**
* 重寫規(guī)律規(guī)則
*/
@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 實(shí)體類類型
* @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();解決多線程下面的并發(fā)的問題
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:用來攔截所有被某個(gè)注解修飾的方法
* (2)@within:用來攔截所有被某個(gè)注解修飾的類
* (3)within:用來指定掃描的包的范圍
*/
@Before("controllerAspect()")
public void doBefore(JoinPoint joinPoint) throws Throwable{
JsonFilter.clear();
//從切面織入點(diǎn)處通過反射機(jī)制獲取織入點(diǎn)處的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//獲取切入點(diǎn)所在的方法
Method method = signature.getMethod();
JsonInclude jsonInclude = method.getAnnotation(JsonInclude.class);
JsonFilter.add(jsonInclude.include(),jsonInclude.clazz(),jsonInclude.fields());
}
}5.如何使用
啟動(dòng)類增加此過濾器
@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包含則表示僅顯示包含的數(shù)據(jù),include = false則排除這配置的fields,顯示沒有配置的字段。
沒有此注解的則不受影響
@JsonInclude(include = true,clazz = LxrJbhYsth.class,fields = {"dg","mz"})
@ApiOperation("金不換規(guī)則")
@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;
}總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
2020最新IDEA SpringBoot整合Dubbo的實(shí)現(xiàn)(zookeeper版)
這篇文章主要介紹了2020最新IDEA SpringBoot整合Dubbo(zookeeper版),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
IntelliJ IDEA2020.1版本更新pom文件自動(dòng)導(dǎo)包的方法
這篇文章主要介紹了IntelliJ IDEA2020.1版本更新pom文件自動(dòng)導(dǎo)包的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
使用ScheduledThreadPoolExecutor踩過最痛的坑
這篇文章主要介紹了使用ScheduledThreadPoolExecutor踩過最痛的坑及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08
Hibernate Validation自定義注解校驗(yàn)的實(shí)現(xiàn)
這篇文章主要介紹了Hibernate Validation自定義注解校驗(yàn)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
Java設(shè)置Access-Control-Allow-Origin允許多域名訪問的實(shí)現(xiàn)方法
這篇文章主要介紹了Java設(shè)置Access-Control-Allow-Origin允許多域名訪問的實(shí)現(xiàn)方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-10-10
SpringCloud Alibaba使用Seata處理分布式事務(wù)的技巧
在傳統(tǒng)的單體項(xiàng)目中,我們使用@Transactional注解就能實(shí)現(xiàn)基本的ACID事務(wù)了,隨著微服務(wù)架構(gòu)的引入,需要對數(shù)據(jù)庫進(jìn)行分庫分表,每個(gè)服務(wù)擁有自己的數(shù)據(jù)庫,這樣傳統(tǒng)的事務(wù)就不起作用了,那么我們?nèi)绾伪WC多個(gè)服務(wù)中數(shù)據(jù)的一致性呢?跟隨小編一起通過本文了解下吧2021-06-06

