Spring Boot微服务:如何为RestTemplate.getForObject添加Bearer Token授权头
如何为RestTemplate的GET请求添加Bearer Token授权头
一、业务代码(OrderServiceImpl类)修改
RestTemplate.getForObject()是简化封装方法,不支持自定义请求头。要添加Bearer Token,需使用exchange()方法,通过HttpEntity携带请求头:
修改后的getOrderDetails方法关键代码:
@Override public OrderResponse getOrderDetails(long orderId, String bearerToken) { // 构造请求头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.set("Authorization", "Bearer " + bearerToken); // 封装请求头到HttpEntity(GET请求无请求体,用Void) HttpEntity<Void> requestEntity = new HttpEntity<>(headers); // 调用产品服务:替换为exchange方法 ProductResponse productResponse = restTemplate.exchange( "http://PRODUCT-SERVICE/product/" + order.getProductId(), HttpMethod.GET, requestEntity, ProductResponse.class ).getBody(); // 调用支付服务:同样使用exchange方法 PaymentResponse paymentResponse = restTemplate.exchange( "http://PAYMENT-SERVICE/payment/order/" + order.getId(), HttpMethod.GET, requestEntity, PaymentResponse.class ).getBody(); // 后续业务逻辑... }
二、测试代码(OrderServiceImplTest类)修改
业务代码改用exchange()后,测试中的Mock和验证逻辑需同步调整:
修改后的test_When_Order_Success方法关键代码:
@DisplayName("Get Order - Success Scenario") @Test void test_When_Order_Success() { String bearerToken = ""; // 构造与业务代码一致的请求头和HttpEntity HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.set("Authorization", "Bearer " + bearerToken); HttpEntity<Void> requestEntity = new HttpEntity<>(headers); // Mocking Order order = getMockOrder(); when(orderRepository.findById(anyLong())) .thenReturn(Optional.of(order)); // Mock exchange方法,匹配完整请求参数 when(restTemplate.exchange( eq("http://PRODUCT-SERVICE/product/" + order.getProductId()), eq(HttpMethod.GET), eq(requestEntity), eq(ProductResponse.class) )).thenReturn(new ResponseEntity<>(getMockProductResponse(), HttpStatus.OK)); when(restTemplate.exchange( eq("http://PAYMENT-SERVICE/payment/order/" + order.getId()), eq(HttpMethod.GET), eq(requestEntity), eq(PaymentResponse.class) )).thenReturn(new ResponseEntity<>(getMockPaymentResponse(), HttpStatus.OK)); // Actual调用 OrderResponse orderResponse = orderService.getOrderDetails(1, bearerToken); // Verification验证exchange调用次数 verify(orderRepository, times(1)).findById(anyLong()); verify(restTemplate, times(1)).exchange( eq("http://PRODUCT-SERVICE/product/" + order.getProductId()), eq(HttpMethod.GET), eq(requestEntity), eq(ProductResponse.class) ); verify(restTemplate, times(1)).exchange( eq("http://PAYMENT-SERVICE/payment/order/" + order.getId()), eq(HttpMethod.GET), eq(requestEntity), eq(PaymentResponse.class) ); // Assert断言逻辑不变 assertNotNull(orderResponse); assertEquals(order.getId(), orderResponse.getOrderId()); }
补充说明
HttpEntity<Void>表示GET请求无请求体,仅携带请求头;若需传递请求体,可替换为对应实体类型。- 测试中需保证Mock的
exchange参数与业务代码完全匹配(包括请求头内容),否则Mock不会生效。 - 对于
test_When_Get_Order_NOT_FOUND_then_Not_Found测试方法,只需按相同逻辑替换getForObject为exchange,并调整对应的Mock和验证即可。
内容的提问来源于stack exchange,提问作者Sercan Noyan Germiyanoğlu
相关产品推荐
相关产品推荐

