IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> abstractGateway网关过滤请求 -> 正文阅读

[开发测试]abstractGateway网关过滤请求

1.网关配置类增加路由过滤器配置

route:
  - id:sign
    uri:lb://consul注册的服务名称
    order:66
    metadata:
      fallbackBean: defaultFallbackHeadler
    predicates:
      -Path:/sign/*
    filters:
      - chnlnoMac  #过滤器名称,约束大于配置,请求入参的过滤器
      - responseMac #返回报文过滤器

2.配置熔断

可忽略此配置:可自己封装接口

@Component("defaultFallbackHeadler")
public DefaultFallbackHeadler implements IFallbackHandler{
	private static final Logger logger = LoggerFactory.getLOgger(DefaultFallbackHeadler.class);
	
	@Override
	public Object handle(ServerWebExchange exchange,Throwable throwable){
		loggin.info(------此请求出发熔断机制-------);
		JSONObject respInfo = new JSONObject();
		respInfo.put("errorMsg","触发熔断");
		respInfo.put("errorCode","1234");
		return respInfo ;
	}
}

3.对chnlnoMac 设置入参请求过滤器

@Component
public calss ChnlnoMacGatewayFIlterFactory extends AbstractGatewayFilterFactory{

private static final Logger logger = LoggerFactory.getLOgger(ChnlnoMacGatewayFIlterFactory .class);

private final ChnalMacFilter  filter = new ChnalMacFilter();

@Override
public GatewayFIlter apply(Object ovject){
	return filter;
}

private class ChnalMacFilter  implements GatewayFilter,Orderd{
		
		@Override
		public int getOder(){
		//定义过滤器顺序,越小越先执行
		return -4;
		}
		
		//获取入参
		private String getStringBody(Flux<DataBUffer> body){
				AtomicReference<String> ato = new AtomicReference<>();
				body.subscribe(buffer ->{
						CharBuffer charbuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
						DataBUfferUtils.release(buffer);
						ato.set(chaebuffer.toString());
					}
				);
				return ato.get();
		}


		//过滤器
		@Override
		public Meno<Void> filter(ServerWebExchange exchange ,GatewayFilterChain chain){
			try{
				//从上下文对象中获取请求
				ServerHttpRequest request = exchange.getRequest();
				HttpHeaders headers = request.getHeaders();
				//获取请求体
				String reqBody = getStringBody(request.getBody());
				logger.info("请求入参:"+reqBody);
				
				JSONObject bodyObj =null;
				if(reqBody != null ){
					bodyObj = JSONObject.formObject(JSON.parse(reqBody));
					
				}else{
					bodyObj = new JSONObject();
				}
				
				//获取请求路径的最后一位,例如ip:端口/a/b,获取b
				String rawPath request.getURI().getRawPath();
				String b = rawPath.sustring(rawPath.lastIndexOf('/')+1);
				logger.info("b:"+b)

				//http头或者报文体获取参数
				if(headers.coontainsKey(c)){
					String c = headers.getFirst(c);
				}
				if(bodyObj.containsKey(d)){
					String d = (String)bodyObj.get(d);
				}

				
			}catch(Exception e){
				return intercep(exchange,e);
			}
			//请求继续执行
			return chain.filter(exchange);

		}

		protected Mono<Void> intercept(ServerWebExchange exchange,Exception e){
			logger.info("触发异常"+e+",请求为:"+exchange.getRequest().getURI());
			//封装状态码和错误信息
			exchange.getResponse().setStatusCode("500");
			return exchange.getRespnse.writeWith(Mono.error(new ZDYYCLException("1234","错误信息")));
			//注:ZDYYCLException为封装的异常类,继承运行异常runtimeException
		}
}}

4.responseMac返回报文过滤器

@Component
public calss responseMacGatewayFIlterFactory extends AbstractGatewayFilterFactory<object>{
	
	private static final Logger logger = LoggerFactory.getLOgger(responseMacGatewayFIlterFactory.class);
	
	private final responseMacFilter  filter = new responseMacFilter();
	
	@Override
	public GatewayFIlter apply(Object ovject){
		return filter;
	}

	private class filter implements GatewayFilter,Orderd{
			
			@Override
			public int getOder(){
			//定义过滤器顺序,越小越先执行
			return -2;
			}
			

			//过滤器
			@Override
			public Meno<Void> filter(ServerWebExchange exchange ,GatewayFilterChain chain){
				ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(exchange.getResponse()){
					
					@Override
					public Mono<Void> writeWith(Publisher<? extends DataBuffer> body){
							//从上下文对象中获取请求
						ServerHttpRequest request = exchange.getRequest();
						//request头信息
						HttpHeaders headers = request.getHeaders();
						//response头信息
						HttpHeaders headers = getHeaders();
						
						//联机服务成功返回时,并且response body有值
						if(HttpStatus.OK.equals(getStatusCOde()) && body instanceof Flux){
							Flux<? extends DataBuffer> fluxBody = Flux.from(body);			
							return super.writhWith(fluxBody.buffer.map(dataBuffer ->{
								
								//将byte转换为jsonmap
								byte[][] contents = new byte[dataBuffers.size()][];
								int id =0;
								for(DataBuffer databuffer :dataBuffers){
									byte[] content = new byte[DataBUffer.readableByteCount()];
									dataBuffer.read(content);
									DataBufferUtils.release(dataBuffer);
									contents[id++] = content;
								}
								//拼接response报文体
								byte[] dodyBytes = ByteUtils.concatAll(contents);
								String resStr = new String(dodyBytes,"utf-8");
								//注意:此时,可以对返回报文进行更改了
								//更改完成之后,重新生成字节数组
								dodyBytes = resStr.getBytes("utf-8");
								
								logger.info("返回报文:"+resStr );
								//response报文长度变化,需要重新赋值
								header.remove(HttpHeaders.CONTENT_LENGTH);
								header.setContentLength(dodyBytes.length);
								return bufferFactory.wrap(dodyBytes);
							}));	
						}

	
						return super.writeWith(body);
					}
				};
				return chain.filter(exchange.mutate().response(decoratedResponse).build());
}}}

5.额外扩展:

5.1:第四部中,获取response的返回报文body时:

//将byte转换为jsonmap
								byte[][] contents = new byte[dataBuffers.size()][];
								int id =0;
								for(DataBuffer databuffer :dataBuffers){
									byte[] content = new byte[DataBUffer.readableByteCount()];
									dataBuffer.read(content);
									DataBufferUtils.release(dataBuffer);
									contents[id++] = content;
								}
								//拼接response报文体
								byte[] dodyBytes = ByteUtils.concatAll(contents);
								String resStr = new String(dodyBytes,"utf-8");

方法二:

private final Joiner joiner = Joiner.on("");
String jsonStr = joiner.join(dataBuffers.stream.map(dataBUffer ->{
	byte[] content = new byte[dataBUffer.readableByteCount()];
	databuffer.read(content);
	DataBUfferUtils.release(databuffer);
	return new String(content,"utf-8");
}).tpArray(String[] ::new));
//json转map
Map<String,Object> json = JSON.parseObject(jsonStr).getInnerMap;

5.2quest入参过滤器中,在过滤器中,重新组装请求,访问另一个ip,

1。可看情况是否重新添加http头信息
ServerHttpRequest request = exchange.getRequest();
request.mutate().header("key","value");

或者
HttpHeaders headers = new httpHeaders();
headers.putAll(super.getHeaders());
headers.set("key""value");


2.重新组装一个请求访问业务服务;
private final List<HttpMessageReader<?>> messageReaders = HandlerStrategies.withDefaults().messageReaders();

ServerRequest serverRequest = ServerRequest.create(exchange,messageReaders);
final JSONObject finalBodyObj = bodyObj;//bodyObj,request的body体

Mono<byte[]> modifiedBody = serverRequest.bodyToMono(byte[].class).flatMap(body -> {
	byte[] bytes = JSON.toJSONString(finalBodyObj).getBytes(utf-8);
	return Mono.just(bytes);.
	
});

BodyInserter<Mono<byte[]>,ReactiveHttpOutputMessage> bodyInserter = BodyInserter.fromPublisher(modifiedBody,byte[].class);
CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange,headers);//headers例如上面的headers

//将处理后的格式重新发给自己
return bodyInserter.insert(outputMessage,new BodyInserterContext()).then(Mono.defer(() -> {
		//开始组装
		ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(exchange.getrequest()){
			//ip
			@Override
			public URI getURI(){return "再次跳转的访问ip地址路径"}
			@Override
			public HttpHeaders getHeaders(){
				return headers;//可重新组装一个head
			}
			@Override
			Public Flux<DataBuffer> getBody(){
					return outputMessage.getBody();
				}
		};
		return chain.filter(exchange.mutate.request(decorator).build());

})).onErrorResume(Exception.class,e ->{ 
	return intercep(exchange,e);
});




	protected Mono<Void> intercept(ServerWebExchange exchange,Exception e){
				logger.info("触发异常"+e+",请求为:"+exchange.getRequest().getURI());
				//封装状态码和错误信息
				exchange.getResponse().setStatusCode("500");
				return exchange.getRespnse.writeWith(Mono.error(new ZDYYCLException("1234","错误信息")));
				//注:ZDYYCLException为封装的异常类,继承运行异常runtimeException
			}

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-05-09 13:03:57  更:2022-05-09 13:04:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/17 22:25:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码