Springboot过滤返回对象属性遇到的各种坑
版权声明:本⽂为博主原创⽂章,未经博主允许不得转载。 blog.csdn/simba_1986/article/details/78300175
Spring boot 过滤返回对象属性遇到的各种坑
在很多的应⽤场景中,我们从后台查询出来的对象数据并不想把所有的字段返回到前台,特别是⼀些敏感的字段,如密码,解决这种问题有⼀下⼏种⽅式
1. 可以查询数据库的时候不要查询出来,这⾥我不想讨论这个这种情况了
2. 还有⼀种情况就是在实体中,如果某个字段不要显⽰,则在其get⽅法前加上注解@JsonIgnore
以上两种都不灵活,如果有的地⽅要显⽰这个字段,有的地⽅不要显⽰这个字段,这样就不好办了
那能不能通过⾃定义注解的⽅式,在要返回页⾯前对返回的实体字段进⾏过滤呢?这当然是可以的了
⾸先定义注解,如下所⽰
package com.sf.ams.json;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 描述:
*
* <pre>HISTORY
* ****************************************************************************
*  ID  DATE          PERSON          REASON
*  1    2017年10⽉20⽇      Simba.Hua        Create
* ****************************************************************************
* </pre>
* @author Simba.Hua
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonFieldFilter {
Class<?> type();//对哪个类的属性进⾏过滤
String include() default  "";//包含哪些字段,即哪些字段可以显⽰
String exclude() default "";//不包含哪些字段,即哪些字段不可以显⽰
}
在spring boot中⽤把Object转换成json⽤的是jackson,那么jackson是怎么过滤Object的字段的呢,是通过ObjectMapper,例⼦如下
package com.sf.ams.json;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
/**
* 描述:
*
* <pre>HISTORY
* ****************************************************************************
*  ID  DATE          PERSON          REASON
*  1    2017年10⽉20⽇      Simba.Hua        Create
* ****************************************************************************
* </pre>
* @author Simba.Hua
*/
public class JsonFilterSerializer {
private static final String DYNC_INCLUDE = "DYNC_INCLUDE";//包含的标识
private static final String DYNC_EXCLUDE = "DYNC_EXCLUDE";//过滤的标识
private ObjectMapper mapper = new ObjectMapper();
@JsonFilter(DYNC_EXCLUDE)
interface DynamicExclude{
}
@JsonFilter(DYNC_INCLUDE)
interface DynamicInclude{
}
public void filter(Class<?> clazz , String include , String exclude) {
if (clazz == null) return;
if (include != null && include.length() > 0) {//包含的操作
mapper.setFilterProvider(new SimpleFilterProvider()
.addFilter(DYNC_INCLUDE, SimpleBeanPropertyFilter.filterOutAllExcept(include.split(","))));//多个字段⽤,分割开            mapper.addMixIn(clazz, DynamicInclude.class);
} else if (exclude != null && exclude.length() > 0) {
mapper.setFilterProvider(new SimpleFilterProvider()
.addFilter(DYNC_EXCLUDE, SimpleBeanPropertyFilter.serializeAllExcept(exclude.split(","))));
mapper.addMixIn(clazz, DynamicExclude.class);
}
}
public String toJson(Object object) throws JsonProcessingException{
return mapper.writeValueAsString(object);
}
@Test
public void testFilterJson() throws JsonProcessingException{
JsonFilterSerializer jsonFilter = new JsonFilterSerializer();
jsonFilter.filter(Response.class, null, "status");//Response中有status、failReason、currentIndex三个属性
System.out.Json(new Response("fail","失败了",-1)));
}
}
测试结果如下,status字段没有显⽰,测试成功
在springMVC中返回到页⾯前可以通过实现HandlerMethodReturnValueHandler接⼝,在⽅法handleReturnValue中可以通过MethodParameter类扫描是否含有@JsonFieldFilter 注解,如果有则过滤返回对象指定的字段,代码如下
}
到这似乎只要写⼀个Controller加上注解就可以了,如下
package com.ller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.sf.ams.biz.IDataStoreXmlAnalysisBiz;
import com.ity.SystemInfo;
import com.ity.TreeNode;
import com.sf.ams.json.JsonFieldFilter;
import com.sf.ams.utils.TreeNodeUtil;
/**
* 描述:
*
* <pre>HISTORY
* ****************************************************************************
*  ID  DATE          PERSON          REASON
*  1    2017-09-26      Simba.Hua        Create
* ****************************************************************************
* </pre>
* @author Simba.Hua
*/
@Controller
@RequestMapping("/dataStoreAnalysis")
public class DataStoreAnalysisController {
@Autowired
private IDataStoreXmlAnalysisBiz dataStoreXmlAnalysisBiz;
@RequestMapping("/getSystemDetail")
@ResponseBody
@JsonFieldFilter(type = SystemInfo.class,exclude = "gitPassword")//把gitPassword字段过滤掉
public SystemInfo getSystemDetail(String systemCode){
SystemBySystemCode(systemCode);
}
}
然⽽发现这样写并没有过滤掉字段gitPassword,debug发现代码根本没有进⼊类JsonReturnHandler的 handleReturnValue⽅法,问题出在哪?是不是没有告诉spring boot有JsonReturnHandler这个类,⽽我发现,如果在springmvc中只要在配置⽂件中加⼊以下配置就可以了,但spring boot只能通过注解。
<mvc:annotation-driven >
<mvc:return-value-handlers>
<bean class="com.sf.ams.json.JsonReturnHandler"/>
</mvc:return-value-handlers>
</mvc:annotation-driven>
后来发现在spring boot中需要加⼊配置告诉spring boot有⾃定义的HandlerMethodReturnValueHandler,代码如下
package com.sf.springboot;
import java.util.List;
import t.annotation.Bean;
write的返回值
import t.annotation.ComponentScan;
import t.annotation.Configuration;
import org.hod.support.HandlerMethodReturnValueHandler;
import org.springframework.fig.annotation.EnableWebMvc;
import org.springframework.fig.annotation.ResourceHandlerRegistry;
import org.springframework.fig.annotation.ViewResolverRegistry;
import org.springframework.fig.annotation.WebMvcConfigurerAdapter;
import com.sf.ams.json.JsonReturnHandler;
/**
* 描述:
*
* <pre>HISTORY
* ****************************************************************************
*  ID  DATE          PERSON          REASON
*  1    2017年10⽉20⽇      Simba.Hua        Create
* ****************************************************************************
* </pre>
* @author Simba.Hua
*/
@Configuration
@ComponentScan(basePackages = {"com.sf.ams"},useDefaultFilters = true)
@EnableWebMvc
public class ApplicationConfig extends WebMvcConfigurerAdapter{
@Bean
public JsonReturnHandler jsonReturnHandler(){
return new JsonReturnHandler();//初始化json过滤器
}
@Override
public void addReturnValueHandlers(
List<HandlerMethodReturnValueHandler> returnValueHandlers) {
returnValueHandlers.add(jsonReturnHandler());
}
}
@SpringBootApplication
@Import(value = {ApplicationConfig.class})
public class AutomaticSqlApplication {
public static void main(String[] args) {
SpringApplication.run(AutomaticSqlApplication.class, args);
}
}
配置需继承WebMvcConfigurerAdapter,重写addReturnValueHandlers⽅法,把JsonReturnHandler加⼊进去,继承的作⽤我这⾥就不详细写了,加⼊这个后重启spring boot,访问页⾯的时候直接报如下错

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。