Spring-cloud-gateway: how to copy headers when using a feignclient?

Created on 29 Mar 2019  路  6Comments  路  Source: spring-cloud/spring-cloud-gateway

this is the way to resolve the problem in zuul:

@Component
public class FeignRequestInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert attributes != null;
        HttpServletRequest request = attributes.getRequest();
        Enumeration<String> headerNames = request.getHeaderNames();
        if (headerNames != null) {
            while (headerNames.hasMoreElements()) {
                String name = headerNames.nextElement();
                String values = request.getHeader(name);
                requestTemplate.header(name, values);
            }
        }
    }
}

but in gateway there is no way to use HttpServletRequest, Can someone give me a code sample?

feedback-provided question

Most helpful comment

You shouldn't use feign in spring-cloud-gateway, replace it with org.springframework.web.reactive.function.client.WebClient.

Example Bean Config:

    @Bean
    public WebClient webClient(LoadBalancerExchangeFilterFunction loadBalancerExchangeFilterFunction){
        return WebClient.builder()
                .filter(loadBalancerExchangeFilterFunction)
                .build();
    }

Example request:

webClient.post().uri(url)
         .headers((httpHeaders -> httpHeaders.putAll(exchange.getRequest().getHeaders())))
         .contentType(MediaType.APPLICATION_FORM_URLENCODED)
         .body(BodyInserters.fromFormData(param))
         .accept(MediaType.APPLICATION_JSON_UTF8)
         .retrieve()
         .bodyToMono(String.class)
         .doOnNext(body->{
             //do with responseBody
         })

All 6 comments

You shouldn't use feign in spring-cloud-gateway, replace it with org.springframework.web.reactive.function.client.WebClient.

Example Bean Config:

    @Bean
    public WebClient webClient(LoadBalancerExchangeFilterFunction loadBalancerExchangeFilterFunction){
        return WebClient.builder()
                .filter(loadBalancerExchangeFilterFunction)
                .build();
    }

Example request:

webClient.post().uri(url)
         .headers((httpHeaders -> httpHeaders.putAll(exchange.getRequest().getHeaders())))
         .contentType(MediaType.APPLICATION_FORM_URLENCODED)
         .body(BodyInserters.fromFormData(param))
         .accept(MediaType.APPLICATION_JSON_UTF8)
         .retrieve()
         .bodyToMono(String.class)
         .doOnNext(body->{
             //do with responseBody
         })

@chenggangpro wow! your answer is just in time! thank you for your help!!

@chenggangpro the next question is: how to copy headers in a global interceptor or configuration? could you please give me some suggestions? thanks a lot:)

Copy header to what?

@ryanjbaxter actually i want to transmit session to micro-service, here's my code below:

@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private AuthFeign authFeign;

    @GetMapping("/get")
    public User get(ServerWebExchange exchange) {
        sessionId = Objects.requireNonNull(exchange.getSession().block()).getId();
        return authFeign.getUser(sessionId);
    }
}

@FeignClient(value = "auth")
public interface AuthFeign {

    @GetMapping("/user/get")
    User getUser(@RequestHeader(HttpHeaders.AUTHORIZATION) String sessionId);
}

if i don't user @RequestHeader, the session and headers in exchange will not be passed to micro-service.

Please ask feign specific questions on stack overflow or gitter

Was this page helpful?
0 / 5 - 0 ratings

Related issues

NickolaiBarysevich picture NickolaiBarysevich  路  6Comments

bijukunjummen picture bijukunjummen  路  3Comments

pravinkumarb84 picture pravinkumarb84  路  7Comments

thirunar picture thirunar  路  6Comments

zjengjie picture zjengjie  路  6Comments