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
(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