SpringCloud GateWay网关无法返回信息数据与Expect: 100-continue

最近做支付项目从大的项目独立出来所以专门搭建了一个网关。上网查了些资料都说SpringCloud GateWay性能比较好所以就搭建了,其中踩了不了坑,包括JWT权限验证、限流等。但这些搭建都算比较容易网上已经有了很多教程。踩的最坑花时间最长的就是支付交易后,接收交易通知服务处理过后返回响应数据接收不到。下面做的仅做简单模拟。

1.搭建一个简单网关



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.6.RELEASE
         
    
    com.gate
    gateway
    0.0.1-SNAPSHOT
    gateway
    Demo project for Spring Boot

    
        1.8
        1.8
        Greenwich.SR1
    



    
        
            org.springframework.cloud
            spring-cloud-starter-gateway
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
        

        
            io.jsonwebtoken
            jjwt
            0.9.0
        
        
            org.projectlombok
            lombok
        
        
            com.google.guava
            guava
            27.1-jre
            compile
        
    

    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                ${spring-cloud.version}
                pom
                import
            
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


响应拦截,打印响应信息

package com.gate;

import lombok.extern.slf4j.Slf4j;
import org.omg.CORBA.PUBLIC_MEMBER;
import org.reactivestreams.Publisher;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

@Component
@Slf4j
public class ResponseFilter implements GlobalFilter, Ordered {


    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获取返货response
        ServerHttpResponse originalResponse = exchange.getResponse();
        DataBufferFactory bufferFactory = originalResponse.bufferFactory();

        HttpStatus statusCode = originalResponse.getStatusCode();

        if (statusCode ==HttpStatus.OK){
            ServerHttpResponseDecorator decorator = new ServerHttpResponseDecorator(originalResponse){

                @Override
                public Mono writeWith(Publisher body){
                    Flux fluxBody = Flux.from(body);
                    return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
                        DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
                        DataBuffer join = dataBufferFactory.join(dataBuffers);
                        byte[] content = new byte[join.readableByteCount()];
                        join.read(content);

                        DataBufferUtils.release(join);
                        String responseData = new String(content, StandardCharsets.UTF_8);
                        //responseData就是下游系统返回的内容,可以查看修改
                        log.info("响应内容:{}", responseData);
                        byte[] uppedContent = new String(responseData.getBytes(), Charset.forName("UTF-8")).getBytes();
                        return bufferFactory.wrap(uppedContent);

                    }));
                }
            };
            return chain.filter(exchange.mutate().response(decorator).build());
        }
        return chain.filter(exchange);
    }

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

application.yml配置

server:
  port: 8080
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        - id: add_request_parameter_route
          uri: lb://producer
          predicates:
            - Path=/producer/**
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

2.注册中心比较简单可以自己自行搭建

3.搭建一个服务提供者

@RestController
@RequestMapping("/producer")
public class TestController {

    @RequestMapping("/foo")
    public String foo(String foo) {
        return "hello "+foo+"!";
    }

    @PostMapping("/test")
    public Object test(@RequestParam Map paramsMap){
        System.out.println(paramsMap);

        return paramsMap;
    }




}

下面用postMan请求网关。

SpringCloud GateWay网关无法返回信息数据与Expect: 100-continue_第1张图片

服务接收到参数

 

SpringCloud GateWay网关无法返回信息数据与Expect: 100-continue_第2张图片

网关接收到信息

SpringCloud GateWay网关无法返回信息数据与Expect: 100-continue_第3张图片

好了,下面看下怎么让网关接收不到响应信息。

SpringCloud GateWay网关无法返回信息数据与Expect: 100-continue_第4张图片

只需在请求头中加入Expect: 100-continue 这个字段,postman会一直保持请求状态,并且最终无响应参数返回。

原因:可以参考https://www.cnblogs.com/nangcr/p/informational-responses-status-code-100-in-http.html

我之前就是不知道交易通知中竟然传了那么坑的参数,研究了好久。

 

那么怎么解决在SpringCloud GateWay中将头信息Expect去掉呢?

参考:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.1.3.RELEASE/single/spring-cloud-gateway.html#_removerequestheader_gatewayfilter_factory

你可能感兴趣的:(项目问题)