Spring Cloud Gateway -- RequestBody 와 Header 수정

19755 단어 Gateway
Spring Cloud Gateway -- RequestBody 와 Header 수정
  • 서문
  • RequestBody 읽 기 및 수정
  • 헤더 수정
  • 경로 추가
  • 머리말
    현재 프로젝트 에 필요 한 것 이 있 습 니 다. 전단 POST 요청 은 xml 형식 으로 전송 해 야 합 니 다. 백 엔 드 인 터 페 이 스 는 JSON 형식 으로 되 돌아 가 는 XML 형식 이 있 고 네트워크 구조의 수요 로 인해 중간 플랫폼 이 필요 합 니 다.결국 스프링 클 라 우 드 게 이 트 웨 이 를 이용해서전단 통 POST 는 AJAX 로 일괄 요청 을 보 내 고 중간 플랫폼 은 POST 를 XML 형식 으로 변환 하 며 해당 xml 형식의 데 이 터 를 JSON 형식 으로 변환 해 되 돌려 달라 고 요청 했다.
    RequestBody 읽 기 및 수정
    RequestBody 를 읽 는 방법.본인 의 한 가지 추측: 이 방법 은 결함 이 있 을 수 있 습 니 다. Response Body 를 읽 을 때 백 스테이지 에서 돌아 오 는 데 이 터 량 이 많아 서 여러 번 나 누 어 보 낸 것 같 습 니 다. 이 를 조합 해서 처리 해 야 합 니 다 (뒤의 블 로그 에서 말씀 드 리 겠 습 니 다).따라서 여기 가 똑 같은 이치 일 것 이 라 고 추측 하지만 요청 매개 변수 가 많 지 않 기 때문에 모든 것 은 나중에 시간 이 있 든 없 든 테스트 를 하고 있 습 니 다.
        /**
         *             
         * @param serverHttpRequest
         * @return
         */
        private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest){
            //     
            Flux<DataBuffer> body = serverHttpRequest.getBody();
            StringBuilder sb = new StringBuilder();
            body.subscribe(buffer -> {
                byte[] bytes = new byte[buffer.readableByteCount()];
                buffer.read(bytes);
                DataBufferUtils.release(buffer);
                String bodyString = new String(bytes, StandardCharsets.UTF_8);
                sb.append(bodyString);
            });
            return sb.toString();
        }
    

    요청 한 방식 을 판단 한 후 데 이 터 를 XML 형식 으로 변환 하고 다시 전달 해 야 한다.중점
  • 당신 이 무엇 을 수정 하 든 new ServerHttp RequestDecorator 라 는 대상 이 필요 하고 당신 이 대응 하 는 방법 을 호출 합 니 다. 예 를 들 어 제 가 body 를 바 꾸 면 getBody 라 는 방법 을 다시 써 야 합 니 다.이 ServerHttp RequestDecorator 가 제공 하 는 방법 을 구체 적 으로 보시 면 됩 니 다.
  • 바디 를 수정 하고 CONTENT 를 수정 해 야 합 니 다.LENGTH (이하 말씀 드 리 겠 습 니 다)
  •     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            ServerHttpRequest oldRequest= exchange.getRequest();
            URI uri = oldRequest.getURI();
            if("POST".equalsIgnoreCase(oldRequest.getMethodValue())) {
                Object requestBody = resolveBodyFromRequest(oldRequest);
                String xml = "";
                if(requestBody != null){
                    xml = resolveBodyToXML(requestBody.toString());
                }
                // request    ,    
                ServerHttpRequest newRequest = null;
                try {
                    byte[] bytes =  URLEncoder.encode(xml, "UTF-8").replaceAll("\\+", "%20").getBytes(StandardCharsets.UTF_8);
                    DataBuffer bodyDataBuffer = stringBuffer(new String(bytes));
                    Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);
                    newRequest = oldRequest.mutate().uri(uri).build();
                    newRequest = new ServerHttpRequestDecorator(newRequest) {
                        @Override
                        public Flux<DataBuffer> getBody() {
                            return bodyFlux;
                        }
                    };
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                return chain.filter(exchange.mutate().request(newRequest).build());
            }else{
                return chain.filter(exchange);
            }
    
        }
    

    헤더 수정
    바디 를 고 치 는 것 과 같은 이치 입 니 다.CONTENT 수정TYPE 와 CONTENTLENGTH 같은 코드 를 뜯 었 어 요. 잘 보이 기 위해 서.모두 그들 을 맞 붙 였 으 면 좋 겠 다
             //        
                    HttpHeaders headers = new HttpHeaders();
                    headers.putAll(exchange.getRequest().getHeaders());
                    //          ,      CONTENT_LENGTH,       ,       
                    int length = bytes.length;
                    headers.remove(HttpHeaders.CONTENT_LENGTH);
                    headers.setContentLength(length);
                    headers.set(HttpHeaders.CONTENT_TYPE, "text/xml");
    				newRequest = new ServerHttpRequestDecorator(newRequest) {
                        @Override
                        public HttpHeaders getHeaders() {
                            return headers;
                        }
                    };
    

    경로 추가
    이 건 좀 평범 해 요.
    @EnableAutoConfiguration
    @Configuration
    public class ApiLocator {
    
        @Autowired
        private RequestFilter requestFilter;
    
        @Bean
        public RouteLocator myRoutes(RouteLocatorBuilder builder) {
            List list = new ArrayList();
            list.add(requestFilter);
    
            RouteLocatorBuilder.Builder routes = builder.routes();
            RouteLocatorBuilder.Builder serviceProvider = routes
                    .route("route3",
                            r -> r.path(SERVICE)
                                    .filters(f -> {
                                f.filters(list);
                                return f;
                            }).uri(URI));
            RouteLocator routeLocator = serviceProvider.build();
            return routeLocator;
        }
    }
    

    좋은 웹페이지 즐겨찾기