需求:项目中网关全局过滤器想要返回json数据
上代码
目录结构
1.返回json数据
自己写了一个工具类:ResponseUtils
package xyz.yeidi.practice.gateway.utils;
import com.alibaba.fastjson.JSONObject;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import java.nio.charset.StandardCharsets;
/**
* @Author: Poke
* @Description: TODO
* @DateTime: 2022/1/13 10:06
**/
public class ResponseUtils {
public static DataBuffer getResponseBuffer(ServerHttpResponse response, Object data){
JSONObject jsonObject = new JSONObject();
jsonObject.put("status", HttpStatus.UNAUTHORIZED.value());
jsonObject.put("data", data);
//把json对象转换成字节数组
byte[] bits = jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8);
//把字节数据转换成一个DataBuffer
return response.bufferFactory().wrap(bits);
}
}
过滤器中的使用
//查看redis的黑名单中是否含有此用户ip
if(StringUtils.isNotBlank(ipCount) && Integer.parseInt(ipCount) > limit){
// 拒绝访问,返回
// 状态码
log.debug("IP:" + clientIp + " 在⿊名单中,将被拒绝访问! ");
DataBuffer wrap = ResponseUtils.getResponseBuffer(response, Results.newFailedResponse(ErrorCode.UNAUTHORIZED.getCode(), "拒绝访问"));
return response.writeWith(Mono.just(wrap));
}
全部代码
package xyz.yeidi.practice.gateway.filter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import xyz.yeidi.practice.constant.RedisConstant;
import xyz.yeidi.practice.enums.ErrorCode;
import xyz.yeidi.practice.gateway.utils.ResponseUtils;
import xyz.yeidi.practice.redis.service.RedisService;
import xyz.yeidi.practice.rpc.Results;
import javax.print.DocFlavor;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.Optional;
/**
* @Author: Poke
* @Description: 黑名单过滤器
* @DateTime: 2022/1/6 13:38
**/
@Slf4j
@Component
public class BlackListFilter implements GlobalFilter, Ordered {
@Autowired
private RedisService redisService;
@Value("${redis.limit}")
private Integer limit;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
//获取用户ip
String clientIp = Objects.requireNonNull(request.getRemoteAddress()).getHostString();
log.info("访问用户ip为:"+clientIp);
String key = RedisConstant.BLACK_IP+clientIp;
String ipCount = Optional.ofNullable(redisService.get(key)).map(String::valueOf).orElse(StringUtils.EMPTY);
//访问量加一,如果为空的话会自动创建 clientIp - 1
Long count = redisService.increment(key, RedisConstant.ONE);
if(1 == count ){
//设置过期时间为1天
Boolean expire = redisService.expire(key, 60*24);
if(Boolean.TRUE.equals(expire)){
log.info("设置过期时间成功");
}else{
log.error("设置过期时间失败");
}
}
//查看redis的黑名单中是否含有此用户ip
if(StringUtils.isNotBlank(ipCount) && Integer.parseInt(ipCount) > limit){
// 拒绝访问,返回
// 状态码
log.debug("IP:" + clientIp + " 在⿊名单中,将被拒绝访问! ");
DataBuffer wrap = ResponseUtils.getResponseBuffer(response, Results.newFailedResponse(ErrorCode.UNAUTHORIZED.getCode(), "拒绝访问"));
return response.writeWith(Mono.just(wrap));
}
// 合法请求,放⾏,执⾏后续的过滤器
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
2.后来测试发现返回的数据中会有中文乱码的情况
增加处理中文乱码的过滤器
package xyz.yeidi.practice.gateway.filter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* @Author: Poke
* @Description: 统一解决中文乱码问题
* @DateTime: 2022/1/13 15:59
**/
public class UnifiedCodeFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpResponse response = exchange.getResponse();
response.getHeaders().add("Content-Type","application/json;charset=UTF-8");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return Integer.MIN_VALUE;
}
}
测试结果没有问题了: