OpenFeign calls microservices to use RequestInterceptor or @RequestHeader to pass http request header information

Records: 391

Scenario: When calling the microservice Restful interface based on Spring Cloud OpenFeign, the request header is passed from service A to service B. You can use the RequestInterceptor interface or @RequestHeader annotation to pass the request header information.

Version: JDK 1.8, SpringBoot 2.6.3, springCloud 2021.0.1

1. Use RequestInterceptor to pass request header information

1.1 About RequestInterceptor

RequestInterceptor is an interface, full path: feign.RequestInterceptor.

RequestInterceptor is essentially an interceptor. The interception time is before OpenFeign calls the Restful interface, so the request information can be set.

To use RequestInterceptor, you need to implement its apply(RequestTemplate var1). In other words, inject the request header into the RequestTemplate object in the apply method,

1.2 Implement the RequestInterceptor interface

(1) Code

@Slf4j
@Configuration
public class FeignConfiguration implements RequestInterceptor {
  @Override
  public void apply(RequestTemplate requestTemplate) {
    // 1. Get information from the request header from the front end
    RequestAttributes reqAttributes = RequestContextHolder. currentRequestAttributes();
    HttpServletRequest request = ((ServletRequestAttributes) reqAttributes).getRequest();
    String cityCode = request. getHeader("cityCode");
    requestTemplate.header("cityCode", cityCode);
    // 2. Set custom request header information
    requestTemplate.header("cityNo", "0571");
  }
}

(2) Analysis

feign.RequestTemplate, feign’s request template class, including request related information.

org.springframework.web.context.request.RequestContextHolder, get the request header tool class.

org.springframework.web.context.request.RequestAttributes, including request attribute information, is an interface that needs to be converted into an implementation class: org.springframework.web.context.request.ServletRequestAttributes. Take the value again.

1.3 Application of RequestInterceptor in OpenFeign interface

Applying RequestInterceptor to the OpenFeign interface means introducing the RequestInterceptor interface implementation class FeignConfiguration.

(1) Code

@FeignClient(contextId = "cityFeignService",
        value = "hub-example-301-nacos",
        fallbackFactory = CityFeignServiceFallbackFactory.class,
        configuration = {FeignConfiguration. class})
public interface CityFeignService {
    @PostMapping("/hub-301-nacos/hub/example/city/queryCityByCityId")
    ResultObj<CityDTO> queryCityByCityId(String cityId);
}

(2) Analysis

@FeignClient, feign client identification annotation.

contextId, specify the unique identifier of the interface.

fallbackFactory, specifies the interface callback function.

configuration = {FeignConfiguration.class}, which is the configuration information when executing the feign interface call. This example is to intercept the request header and set the request header information.

value = “hub-example-301-nacos”, the name of the microservice that provides the Restful interface, must have been registered, this example uses Nacos registration.

1.4 Restful interface provided by Weibo

(1) Code

@RestController
@RequestMapping("/hub/example/city")
@RefreshScope
@Slf4j
public class CityController {
    @Autowired
    private HttpServletRequest request;
    @PostMapping("/queryCityByCityId")
    public ResultObj<CityDTO> queryCityByCityId(String cityId) {
        log.info("cityCode = " + request.getHeader("cityCode"));
        log.info("cityNo = " + request.getHeader("cityNo"));
        CityDTO cityDTO = new CityDTO();
        cityDTO.setCityId(cityId != null ? Long.parseLong(cityId) : 1L);
        cityDTO.setCityName("Hangzhou");
        cityDTO.setUpdateTime(new Date());
        return ResultObj.data(200, cityDTO, "executed successfully");
    }
}

(2) Analysis

The Restful interface provided by the microservice is consistent with the common interface and does not need to be changed.

Injecting javax.servlet.http.HttpServletRequest is to take out the request header information for verification.

2. Use @RequestHeader to pass request header information

2.1 About @RequestHeader

Annotate the full path of RequestHeader: org.springframework.web.bind.annotation.RequestHeader.

Annotate RequestHeader, which is intercepted and configured by the Spring framework.

2.2 Apply @RequestHeader to the OpenFeign interface

Applying @RequestHeader to the OpenFeign interface is to apply the annotation to the parameters of the OpenFeign interface method.

(1) Code

@FeignClient(contextId = "cityFeignService",
        value = "hub-example-301-nacos",
        fallbackFactory = CityFeignServiceFallbackFactory.class,
        configuration = {FeignConfiguration. class})
public interface CityFeignService {
    @PostMapping("/hub-301-nacos/hub/example/city/queryCityByCityName")
    ResultObj<CityDTO> queryCityByCityName(@RequestParam("cityName") String cityName,
                                      @RequestHeader MultiValueMap<String, String> headers);
}

(2) Analysis

@RequestHeader, add @RequestHead to the method to mark this parameter as request header information.

MultiValueMap headers, the data type of the request header.

(3) Note

When using the @RequestHeader annotation, other parameters of the OpenFeign method must use @RequestParam to specify the parameter name, otherwise the microservice will not receive the value.

@RequestParam(“cityName”) String cityName, the cityName in double quotes must be consistent with the formal parameter name of the Restful interface to be called.

2.3 Call OpenFeign interface

When using @RequestHeader to pass parameters, you need to manually assemble the parameter MultiValueMap type parameter before calling the OpenFeign interface.

(1) Code

@Service
public class CityServiceImpl implements CityService {
  @Autowired
  private CityFeignService cityFeignService;
  @Override
  public ResultObj<CityDTO> queryCityByCityName(String cityName) {
    // incoming request header
    MultiValueMap<String, String> headers = new HttpHeaders();
    headers.add("cityNo", "0571");
    return cityFeignService.queryCityByCityName(cityName, headers);
  }
}

(2) Analysis

Generally, the OpenFeign interface is injected into the Service service layer, and the parameters are assembled before calling the interface method.

2.4 Restful interface provided by Weibo

(1) Code

@RestController
@RequestMapping("/hub/example/city")
@RefreshScope
@Slf4j
public class CityController {
  @Autowired
  private HttpServletRequest request;
  @PostMapping("/queryCityByCityName")
  public ResultObj<CityDTO> queryCityByCityName(String cityName) {
    log.info("cityNo = " + request.getHeader("cityNo"));
    log.info("cityName = " + cityName);
    CityDTO cityDTO = new CityDTO();
    cityDTO.setCityId(1L);
    cityDTO.setCityName(cityName);
    cityDTO.setUpdateTime(new Date());
    log.info("cityDTO: " + cityDTO.toString());
    return ResultObj.data(200, cityDTO, "executed successfully");
  }
}

(2) Analysis

The Restful interface provided by the microservice is consistent with the common interface and does not need to be changed.

Injecting javax.servlet.http.HttpServletRequest is to take out the request header information for verification.

3. Several classes

Full class path:

java.util.Map.
org.springframework.util.MultiValueMap.
org.springframework.http.HttpHeaders. 

Inheritance relationship:

public interface Map<K,V>.
public interface MultiValueMap<K, V> extends Map<K, List<V>>.
public class HttpHeaders implements MultiValueMap<String, String>, Serializable. 

Above, thanks.

March 24, 2023

The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge. Network skill treeHomepageOverview 28751 people are studying systematically