记录:391
场景:基于Spring Cloud OpenFeign调用微服务Restful接口时,请求头从A服务传递到B服务,可以使用RequestInterceptor接口或者@RequestHeader注解传递请求头信息。
版本:JDK 1.8,SpringBoot 2.6.3,springCloud 2021.0.1
1.使用RequestInterceptor传递请求头信息
1.1关于RequestInterceptor
RequestInterceptor是一个接口,全路径:feign.RequestInterceptor。
RequestInterceptor本质上就是一个拦截器,拦截时机是在OpenFeign调用Restful接口前拦截,因此可以设置请求信息。
使用RequestInterceptor,需实现它的apply(RequestTemplate var1)。换句话说,就是在apply方法中向RequestTemplate对象中注入请求头,
1.2实现RequestInterceptor接口
(1)代码
@Slf4j
@Configuration
public class FeignConfiguration implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
// 1.从前端过来的请求头取信息
RequestAttributes reqAttributes = RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes) reqAttributes).getRequest();
String cityCode = request.getHeader("cityCode");
requestTemplate.header("cityCode", cityCode);
// 2.设置自定义请求头信息
requestTemplate.header("cityNo", "0571");
}
}
(2)解析
feign.RequestTemplate,feign的请求模板类,包括请求相关信息。
org.springframework.web.context.request.RequestContextHolder,取请求头工具类。
org.springframework.web.context.request.RequestAttributes,包含请求属性信息,是接口,需转换为实现类:org.springframework.web.context.request.ServletRequestAttributes。再取值。
1.3在OpenFeign接口应用RequestInterceptor
在OpenFeign接口应用RequestInterceptor,也就是引入RequestInterceptor接口实现类FeignConfiguration。
(1)代码
@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)解析
@FeignClient,feign客户端标识注解。
contextId,指定接口唯一标识。
fallbackFactory,指定接口回调函数。
configuration = {FeignConfiguration.class},就是执行feign接口调用时的配置信息,本例就是拦截请求头并设置请求头信息。
value = "hub-example-301-nacos",提供Restful接口的微服务名称,必须已经注册,本例使用Nacos注册。
1.4微服提供的Restful接口
(1)代码
@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("杭州");
cityDTO.setUpdateTime(new Date());
return ResultObj.data(200, cityDTO, "执行成功");
}
}
(2)解析
微服务提供的Restful接口和普通接口一致,无需改动。
注入javax.servlet.http.HttpServletRequest,是为了取出请求头信息做验证。
2.使用@RequestHeader传递请求头信息
2.1关于@RequestHeader
注解RequestHeader全路径:org.springframework.web.bind.annotation.RequestHeader。
注解RequestHeader,由Spring框架做拦截和配置。
2.2在OpenFeign接口应用@RequestHeader
在OpenFeign接口应用@RequestHeader,是把注解作用在OpenFeign接口方法参数上。
(1)代码
@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)解析
@RequestHeader,在方法上加上@RequestHead标记此参数是请求头信息。
MultiValueMap<String, String> headers,请求头传入的数据类型。
(3)注意
当使用@RequestHeader注解时,OpenFeign方法的其它参数必须使用@RequestParam指定参数名称,否则微服务会接收不到值。
@RequestParam("cityName") String cityName,双引号中的cityName必须和要被调用的Restful接口形参名称一致。
2.3调用OpenFeign接口
使用@RequestHeader传递参数时,需在调用OpenFeign接口前置手动组装参数MultiValueMap类型参数。
(1)代码
@Service
public class CityServiceImpl implements CityService {
@Autowired
private CityFeignService cityFeignService;
@Override
public ResultObj<CityDTO> queryCityByCityName(String cityName) {
// 传入请求头
MultiValueMap<String, String> headers = new HttpHeaders();
headers.add("cityNo", "0571");
return cityFeignService.queryCityByCityName(cityName, headers);
}
}
(2)解析
一般是在Service服务层注入OpenFeign接口,在调用接口方法前先组装参数。
2.4微服提供的Restful接口
(1)代码
@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, "执行成功");
}
}
(2)解析
微服务提供的Restful接口和普通接口一致,无需改动。
注入javax.servlet.http.HttpServletRequest,是为了取出请求头信息做验证。
3.几个类
类全路径:
java.util.Map。
org.springframework.util.MultiValueMap。
org.springframework.http.HttpHeaders。
继承关系:
public interface Map<K,V>。
public interface MultiValueMap<K, V> extends Map<K, List<V>>。
public class HttpHeaders implements MultiValueMap<String, String>, Serializable。
以上,感谢。文章来源:https://www.toymoban.com/news/detail-628651.html
2023年3月24日文章来源地址https://www.toymoban.com/news/detail-628651.html
到了这里,关于OpenFeign调用微服务使用RequestInterceptor或@RequestHeader传递http请求头信息的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!