一,应用场景:
Getway网关进行参数校验时,当校验失败时需要返回响应信息,因为Getway基于webFlux实现,需要对返回信息进行封装,如果多个过滤器,这部分代码是重复的,所以抽象出来作为公共部分
实现方式
1,抽象为工具类,我能想到
2,抽象为实现接口,过滤器再实现这个接口,那不还是要在过滤器中实现接口方法,这里不用,可以把公共部分在接口中实现逻辑,用default修饰,实现方法。
在java8以后,接口中可以添加使用default或者static修饰的方法,在这里我们只讨论default方法,default修饰方法只能在接口中使用,在接口种被default标记的方法为普通方法,可以直接写方法体。
二,代码:
1,抽象接口:
/**
* 自定义过滤器父类
*
* @author lr
* @date 2019-07-26 10:52
*/
public interface ParentGatewayFilterFactory {
/**
* 获取响应信息流
*
* @param exchange
* @param responseBean
* @return
*/
default Mono<Void> getFilterResult(ServerWebExchange exchange, ResponseBean responseBean) {
ServerHttpResponse response = exchange.getResponse();
//或封装响应信息为map
response.setStatusCode(HttpStatus.UNAUTHORIZED);
Map<String, Object> map = Maps.newHashMap();
map.put("errCode", "0001");
map.put("errMsg", "参数为空");
ObjectMapper objectMapper = new ObjectMapper();
try {
byte[] bytes = objectMapper.writeValueAsBytes(map);
DataBuffer dataBuffer = response.bufferFactory().wrap(bytes);
return response.writeWith(Mono.just(dataBuffer));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
response.getHeaders().add("Content-Type", MediaType.APPLICATION_JSON_UTF8_VALUE);
response.getHeaders().add("Accept", MediaType.APPLICATION_JSON_UTF8_VALUE);
return response.writeWith(Mono.just(response.bufferFactory().wrap(JSONObject.toJSONString(responseBean).getBytes(Charset.forName("UTF-8")))));
}
/**
* 根据code设置对应的响应信息
*
* @param code
* @param args 参数
* @return
*/
default ResponseBean getResponseBean(String code, Object... args) {
String message = MessageFormat.format(PropertiesUtils.getKey(code), args);
return ResponseBean.builder().code(code).msg(message).build();
}
},
2,过滤器调用
//判断是否存在
for(SystemParamEnum systemParamEnum : values) {
//判读是否有系统参数并且系统参数值不能为空
if(!params.containsKey(systemParamEnum.getValue()) && StringUtils.isEmpty(params.get(systemParamEnum.getValue()))) {
return getFilterResult(exchange, getResponseBean(systemParamEnum.getErrorCode()));
}
}
/**
* 校验平台必须参数即系统参数
* @author lr
* @date 2019-07-26 10:40
*/
public class OpenParamGatewayFilterFactory
extends AbstractGatewayFilterFactory<OpenParamGatewayFilterFactory.Config> implements ParentGatewayFilterFactory {
/**
* 限制时间长度
*/
private final static long LIMIT_TIME_LONG = 5 * 60 *1000;
/**
* 重复请求sign秘钥5分钟过期
*/
private final static long REPEAT_REQUEST_EXPIRE_TIME = 5;
@Autowired
private StringRedisTemplate stringRedisTemplate;
private final static int OPEN_PARAM_FILTER_ORDER = OpenAppInfoGatewayFilterFactory.OPEN_APP_INFO_FILTER_ORDER -1;
public OpenParamGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return new OpenParamGatewayFilter();
}
/**
* 内部内的作用,排序,AbstractGatewayFilterFactory实现ordered没效果
* 原因:获取过滤器调用apply()返回的GatewayFilter,没有实现Ordered接口,无法排序
* 参考org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#loadGatewayFilters(java.lang.String, java.util.List):186行
*/
public class OpenParamGatewayFilter implements GatewayFilter,Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//校验系统参数
MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams();
Map<String, String> params = queryParams.toSingleValueMap();
SystemParamEnum[] values = SystemParamEnum.values();
//判断是否存在
for(SystemParamEnum systemParamEnum : values) {
//判读是否有系统参数并且系统参数值不能为空
if(!params.containsKey(systemParamEnum.getValue()) && StringUtils.isEmpty(params.get(systemParamEnum.getValue()))) {
return getFilterResult(exchange, getResponseBean(systemParamEnum.getErrorCode()));
}
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return OPEN_PARAM_FILTER_ORDER;
}
}
public static class Config{
}
}
最后
以上就是唠叨斑马最近收集整理的关于抽象实现接口,default修饰接口方法的全部内容,更多相关抽象实现接口内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复