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)證對(duì)簡(jiǎ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 { /** * 對(duì)于規(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)文章
JAVA實(shí)現(xiàn)心跳檢測(cè)(長(zhǎng)連接)
本文主要介紹了JAVA實(shí)現(xiàn)心跳檢測(cè)(長(zhǎng)連接),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-032020最新IDEA SpringBoot整合Dubbo的實(shí)現(xiàn)(zookeeper版)
這篇文章主要介紹了2020最新IDEA SpringBoot整合Dubbo(zookeeper版),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09IntelliJ IDEA2020.1版本更新pom文件自動(dòng)導(dǎo)包的方法
這篇文章主要介紹了IntelliJ IDEA2020.1版本更新pom文件自動(dòng)導(dǎo)包的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06使用ScheduledThreadPoolExecutor踩過最痛的坑
這篇文章主要介紹了使用ScheduledThreadPoolExecutor踩過最痛的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08Hibernate Validation自定義注解校驗(yàn)的實(shí)現(xiàn)
這篇文章主要介紹了Hibernate Validation自定義注解校驗(yàn)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04Java設(shè)置Access-Control-Allow-Origin允許多域名訪問的實(shí)現(xiàn)方法
這篇文章主要介紹了Java設(shè)置Access-Control-Allow-Origin允許多域名訪問的實(shí)現(xiàn)方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-10-10SpringCloud Alibaba使用Seata處理分布式事務(wù)的技巧
在傳統(tǒng)的單體項(xiàng)目中,我們使用@Transactional注解就能實(shí)現(xiàn)基本的ACID事務(wù)了,隨著微服務(wù)架構(gòu)的引入,需要對(duì)數(shù)據(jù)庫進(jìn)行分庫分表,每個(gè)服務(wù)擁有自己的數(shù)據(jù)庫,這樣傳統(tǒng)的事務(wù)就不起作用了,那么我們?nèi)绾伪WC多個(gè)服務(wù)中數(shù)據(jù)的一致性呢?跟隨小編一起通過本文了解下吧2021-06-06