在spring boot启动类加上 (这里不加貌似也可以生效)
@Import(value = { ApplicationConfig.class })
@SpringBootApplication
@EnableTransactionManagement
@MapperScan("com.apih5.mybatis.dao")
@Import(value = { ApplicationConfig.class })
// @EnableCaching // 开启缓存,需要显示的指定
@EnableApolloConfig
public class Apih5Application {
private static final Logger logger = LoggerFactory.getLogger(Apih5Application.class);
public static void main(String[] args) {
String version = SpringBootVersion.getVersion();
System.out.println(version);
String implementationVersion = SpringApplication.class.getPackage().getImplementationVersion();
System.out.println(implementationVersion);
System.out.println(Thread.currentThread().getContextClassLoader().getResource(""));
if (args != null && args.length > 0 && StrUtil.isNotEmpty(args[0])) {
String path = System.getProperty("user.dir");
String applicationTest = path + "/src/main/resources/application-test.yml";
String dbconfig = path + "/src/main/resources/workflow-conf/properties/dbconfig.properties";
write(applicationTest, read(applicationTest, args[0]));
write(dbconfig, read(dbconfig, args[0]));
String targetApplicationTest = path + "/target/classes/application-test.yml";
String targetDbconfig = path + "/target/classes/workflow-conf/properties/dbconfig.properties";
write(targetApplicationTest, read(applicationTest, args[0]));
write(targetDbconfig, read(dbconfig, args[0]));
// appid
if (args.length > 1) {
String appid = path + "/src/main/resources/META-INF/app.properties";
write(appid, readAppId(appid, args[1]));
}
}
SpringApplication application = new SpringApplication(Apih5Application.class);
application.setBannerMode(Banner.Mode.OFF);
application.run(args);
LoggerUtils.printLogger(logger, "--------------APIH5 启动完成----------------");
}
ApplicationConfig类如下:
package com.apih5.framework.components;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//三个注解貌似不加也可以
@Configuration
@ComponentScan(basePackages = { "com.apih5.controller" }, useDefaultFilters = true)
// @ComponentScan(basePackages = { "com.apih5.framework.components" },
// useDefaultFilters = true)
@EnableWebMvc
// public class ApplicationConfig extends WebMvcConfigurerAdapter{//过期类
// public class ApplicationConfig extends WebMvcConfigurationSupport {//不生效
public class ApplicationConfig implements WebMvcConfigurer {// 生效
@Bean
public JsonReturnHandler jsonReturnHandler() {
return new JsonReturnHandler();// 初始化json过滤器
}
@Override
public void addReturnValueHandlers(List returnValueHandlers) {
returnValueHandlers.add(jsonReturnHandler());
}
// @Override
// public void addResourceHandlers(ResourceHandlerRegistry registry) {
// registry.addResourceHandler("/**").addResourceLocations("/");// 所有
// }
//
// @Override
// public void configureViewResolvers(ViewResolverRegistry registry) {
// registry.jsp("/WEB-INF/jsp/", ".jsp");
// }
}
JsonReturnHandler类如下:
package com.apih5.framework.components;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;
import com.apih5.framework.annotation.JsonFieldFilter;
import com.apih5.framework.components.JsonFilterSerializer;
public class JsonReturnHandler implements HandlerMethodReturnValueHandler {
@Override
public void handleReturnValue(Object returnObject, MethodParameter paramter, ModelAndViewContainer container,
NativeWebRequest request) throws Exception {
container.setRequestHandled(true);
JsonFilterSerializer serializer = new JsonFilterSerializer();
if (paramter.hasMethodAnnotation(JsonFieldFilter.class)) {// 如果有JsonFieldFilter注解,则过滤返回的对象returnObject
JsonFieldFilter jsonFilter = paramter.getMethodAnnotation(JsonFieldFilter.class);
serializer.filter(jsonFilter.type() == null ? returnObject.getClass() : jsonFilter.type(),
jsonFilter.include(), jsonFilter.exclude());// 调用过滤方法
}
HttpServletResponse response = request.getNativeResponse(HttpServletResponse.class);
response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
response.getWriter().write(serializer.toJson(returnObject));
}
@Override
public boolean supportsReturnType(MethodParameter methodParameter) {
return methodParameter.hasMethodAnnotation(JsonFieldFilter.class);
}
}
JsonFilterSerializer类如下:
package com.apih5.framework.components;
import org.junit.Test;
import com.apih5.framework.entity.Response;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
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, "failReason", null);
// Response中有status、failReason、currentIndex三个属性
System.out.println(jsonFilter.toJson(new Response("test", "成功", -1)));
}
}
自定义注解 JsonFieldFilter如下:
package com.apih5.framework.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* * 描述: * *
*
*
* HISTORY * **************************************************************************** *
* ID DATE PERSON REASON * 1 2018年11月22日 cx Create
* * ****************************************************************************
* *
*
*
* * @author cx
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonFieldFilter {
Class> type();// 对哪个类的属性进行过滤
String include() default "";// 包含哪些字段,即哪些字段可以显示
String exclude() default "";// 不包含哪些字段,即哪些字段不可以显示
}
Junit测试需要类如下:
package com.apih5.framework.entity;
public class Response {
private String status;
private String failReason;
private int currentIndex;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getFailReason() {
return failReason;
}
public void setFailReason(String failReason) {
this.failReason = failReason;
}
public int getCurrentIndex() {
return currentIndex;
}
public void setCurrentIndex(int currentIndex) {
this.currentIndex = currentIndex;
}
public Response(String status, String failReason, int currentIndex) {
super();
this.status = status;
this.failReason = failReason;
this.currentIndex = currentIndex;
}
}
最后测试controller如下:
注意点:
1、用@Controller 替代 @RestController;
2、在不需要过滤字段 @JsonFieldFilter(type = ***.class, include = "***")的接口上面使用@ResponseBody注解,但是在需要 过 滤字段的接口上一定不要用@ResponseBody注解,否则过滤失效。
package com.apih5.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import com.apih5.framework.annotation.JsonFieldFilter;
import com.apih5.framework.annotation.RequireToken;
import com.apih5.framework.entity.ResponseEntity;
import com.apih5.mybatis.pojo.ZxHwGxProcess;
import com.apih5.service.ZxHwGxProcessService;
@Controller
public class ZxHwGxProcessController {
@Autowired(required = true)
private ZxHwGxProcessService zxHwGxProcessService;
@ApiOperation(value = "******", notes = "*****")
@ApiImplicitParam(name = "zxHwGxProcess", value = "entity", dataType = "ZxHwGxProcess")
@RequireToken
// @ResponseBody
@PostMapping("/countZxHwGxProcessNumByStatus")
@JsonFieldFilter(type = ZxHwGxProcess.class, include = "rootLevelId,rootLevelName,totalNum")
public ResponseEntity countZxHwGxProcessNumByStatus(@RequestBody(required = false) ZxHwGxProcess zxHwGxProcess) {
return zxHwGxProcessService.countZxHwGxProcessNumByStatus(zxHwGxProcess);
}
}
参考文章链接:https://blog.csdn.net/simba_1986/article/details/78300175
http://blog.51cto.com/12066352/2093750
https://www.cnblogs.com/shuaifing/p/8119664.html