ServerHttpResponse返回Json数据

此ServerHttpResponse指的是org.springframework.http.server.reactive.ServerHttpResponse;
就是gateway当中使用ServerWebExchange得到的一个response。

ServerHttpResponse.writeWith()

某些条件下,我希望在gateway的全局过滤器中直接返回请求,而不进行转发,比如做ip限制这样的功能。

然而GlobalFilter的处理方法中只提供了一个``ServerWebExchange和一个GatewayFilterChain,然后可以从ServerWebExchange中调用getResponse()方法得到一个ServerHttpResponse`。显然,要想直接返回数据,我们应该在这个response上做工作。刚开始的代码是这样的:

package cn.sticki.gateway.filter;

import lombok.extern.slf4j.Slf4j;
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.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * ip访问限制过滤器
 *
 * @author 阿杆
 */
@Slf4j
@Component
public class IpLimitFilter implements GlobalFilter, Ordered {

	@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 这里可以获取到ServerHttpRequest和ServerHttpResponse
		ServerHttpRequest request = exchange.getRequest();
		ServerHttpResponse response = exchange.getResponse();
        // do something ...
        // 放行
		return chain.filter(exchange);
	}

	@Override
	public int getOrder() {
		return -10;
	}

}
写入数据到ServerHttpResponse

这东西对我来说并不常用,常用的一般是 HttpResponse或者 HttpServerResponse,往 ServerHttpResponse 里面写入数据我压根都不会。这里我卡了好久,各种地方搜,然后还去查了spring gateway的官方文档,都没找到,主要还是自己太菜了,代码不会写,资料还查不到。。。

后来在某个公众号上找到了,有点小复杂,然后根据自己的需求进行了转化,核心代码如下:

ServerHttpResponse response = exchange.getResponse();			
response.setStatusCode(HttpStatus.LOCKED);
DataBufferFactory bufferFactory = response.bufferFactory();
ObjectMapper objectMapper = new ObjectMapper();
DataBuffer wrap = bufferFactory.wrap(objectMapper.writeValueAsBytes(new RestResult<>(408, "访问频繁,请稍后再试")));
return response.writeWith(Mono.fromSupplier(() -> wrap));

完整代码如下(业务逻辑已经被我删掉了):

package cn.sticki.gateway.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
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.core.io.buffer.DataBufferFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
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 javax.annotation.Resource;
import java.io.IOException;

import static cn.sticki.gateway.utils.RedisConstants.GATEWAY_IPLIMIT_KEY;
import static cn.sticki.gateway.utils.RedisConstants.GATEWAY_IPLIMIT_TTL;

/**
 * @author 阿杆
 */
@Slf4j
@Component
public class IpLimitFilter implements GlobalFilter, Ordered {

	@SneakyThrows(IOException.class)
	@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		ServerHttpRequest request = exchange.getRequest();
		ServerHttpResponse response = exchange.getResponse();
		// 打印访问情况
		log.info("{} {} {} {}", request.getRemoteAddress(), request.getMethod(), response.getStatusCode(), request.getPath());
        // 业务逻辑已经被我删掉了,请根据自己的需求进行修改
        if(...){
			response.setStatusCode(HttpStatus.LOCKED);
			DataBufferFactory bufferFactory = response.bufferFactory();
			ObjectMapper objectMapper = new ObjectMapper();
			log.info("ip limit : {} {}", ip, exchange.getRequest().getPath());
            // 要写入的数据对象,会自动转为json格式
			DataBuffer wrap = bufferFactory.wrap(objectMapper.writeValueAsBytes(...); 
			return response.writeWith(Mono.fromSupplier(() -> wrap));
		} else {
			// 放行
			return chain.filter(exchange);
		}
	}

	@Override
	public int getOrder() {
		return -10;
	}
}

在这里插入图片描述

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿杆.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值