首先先创建RestTemplate的实例,在实际的开发中,最好不要每次都创建RestTemplate的实例,最好在spring中以单例的方式来配置,要使用的地方直接注入。用base64来编码了用户名和密码,然后在请求头中进行设置。restTemplate.exchange执行请求,并获取返回的结果。上面的代码其实并不难,但是这样写会不会有啥问题呢!假如说,叫你对接A部门的根据机构id来获取机构信息的接口,你岂不是又要把上面的代码再重新复制一下吗?这样不是很麻烦,代码会很臃肿。
spring提供了ClientHttpRequestInterceptor这个类,适合用来处理这种情况,加入基本的认证头信息,可以使用spring提供的这个类:BasicAuthorizationInterceptor。使用配置的方式来配置RestTemplate:
@Configuration public class RestTemplateConfig { @Value("${zfx.username}") private String username; @Value("${zfx.password}") private String password; @Bean("basicAuthRestTemplate") public RestTemplate createBasicAuthRestTemplate() { RestTemplate restTemplate = new RestTemplate(); List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>(); interceptors.add(new BasicAuthorizationInterceptor(username, password)); restTemplate.setInterceptors(interceptors); return restTemplate; } }上面的代码在创建basicAuthRestTemplate时,会加入基本的认证头信息的拦截器,来设置基本认证头信息。
再次调用上面的接口时,代码可以这样写:
@Autowired RestTemplate basicAuthRestTemplate; ... String userId = "11"; String url = "http://127.0.0.1:8080/v1/users/{id}"; User result = basicAuthRestTemplate.getForObject(url, User.class, userId);代码一下子简洁了这么多,假如说要调用根据机构id来获取机构信息的接口呢?如下:
@Autowired RestTemplate basicAuthRestTemplate; ... String orgId = "11"; String url = "http://127.0.0.1:8080/v1/orgs/{id}"; Org result = basicAuthRestTemplate.getForObject(url, Org.class, orgId);代码一下子简洁了很多,对接这些接口的程序员不用再关心认证是怎么一回事,认证这件事对于他们完全是透明的,他们只需要专注于编写他们自己的逻辑代码就可以了。ClientHttpRequestInterceptor的实现也很简单,代码如下:
@Override public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { String token = Base64Utils.encodeToString( (this.username + ":" + this.password).getBytes(StandardCharsets.UTF_8)); request.getHeaders().add("Authorization", "Basic " + token); return execution.execute(request, body); }在intercept方法中加入了基本的认证头信息。
假如说,有一天认证方式变了,改成OAuth2.0了,那么我们只需要实现自己的请求拦截器就行了,如下:
public class BearerAuthorizationIntercept implements ClientHttpRequestInterceptor { @Override public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { String token = 这些写获取token的逻辑; request.getHeaders().add("Authorization", "Bearer " + token); return execution.execute(request, body); } }然后配置restTemplate:
@Bean("bearerAuthRestTemplate") public RestTemplate createBearerAuthRestTemplate() { RestTemplate restTemplate = new RestTemplate(); List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>(); interceptors.add(new BearerAuthorizationIntercept()); restTemplate.setInterceptors(interceptors); return restTemplate; }那么只需要注入bearerAuthRestTemplate,就能使用他了:
@Autowired RestTemplate bearerAuthRestTemplate; ... String userId = "11"; String url = "http://127.0.0.1:8080/v1/users/{id}"; User result = bearerAuthRestTemplate.getForObject(url, User.class, userId);