效果图网站接单,重庆一般建一个网站需要多少钱,免费带后台的网站模板,常用的网络营销方式←←←←←←←←←←←← 快#xff01;点关注 为什么要使用RestTemplate#xff1f; 随着微服务的广泛使用#xff0c;在实际的开发中#xff0c;客户端代码中调用RESTful接口也越来越常见。在系统的遗留代码中#xff0c;你可能会看见有一些代码是使用HttpURLConnectio…←←←←←←←←←←←← 快点关注 为什么要使用RestTemplate 随着微服务的广泛使用在实际的开发中客户端代码中调用RESTful接口也越来越常见。在系统的遗留代码中你可能会看见有一些代码是使用HttpURLConnection来调用RESTful接口的类似于下面这样 URL url ...
// 打开连接
HttpURLConnection conn (HttpURLConnection) url.openConnection();
try {conn.setRequestMethod(POST);conn.setDoInput(true);conn.setDoOutput(true);conn.connect();// 发送数据...BufferedWriter bw new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), utf-8));bw.write(str);// 接收数据 ...BufferedReader br new BufferedReader(new InputStreamReader(conn.getInputStream(), utf-8));String line null;while ((line br.readLine()) ! null) {...}
} finally {conn.disconnect();
}
复制代码从上面的代码可以看出使用HttpURLConnection调用RESTful接口是比较麻烦的假如要调用30个接口每个接口都使用类似于上面的代码 进行调用那简直是一场灾难写这么多无聊的样板代码内心绝对是崩溃的。有人可能会想将常用的RESTful操作例如GET、POST、DELETE封装成工具类再调用不是也可以吗这样做确实可行但是要封装成通用的工具类不是那么简单的需要一定的经验。调用RESTful接口还有另外一种选择Apache HttpComponents。虽然使用它发送HTTP请求确实挺方便的但是使用它调用RESTful接口好像也挺麻烦的 直到我遇到了RestTemplate世界顿时都明亮了腰也不酸了腿也不疼了一下子就对接好了10个RESTful接口。写的代码可能变成是这样子的 RestTemplate template ...
// 请求地址
String url ...
// 请求参数
UserParams request ...
// 执行POST请求
User u template.postForObject(url, request, User.class);
...
复制代码上面的调用代码变的简洁了很多是不是很爽啊RestTemplate是spring提供用来调用RESTful接口的类里面提供了大量便捷的方法如下 执行不同的请求只需找到这种请求方式所对应的方法就行上例中的postForObject就是发送的POST请求。如果上面的请求没有找到对应的方法可以使用更加通用的exchange和execute方法。 RestTemplate的可扩展性也很强下面列出比较常用的几种方式 RestTemplate默认使用的是JDK中的HttpURLConnection实现的如果你想要切换到其他的HTTP库例如Apache HttpComponents, Netty和OkHttp只需要调用setRequestFactory方法来进行设置甚至可以使用自己实现的类型只需要继承自ClientHttpRequestFactory。一般情况下使用默认的实现就好RestTemplate默认使用的是DefaultResponseErrorHandler响应错误处理器你可以调用setErrorHandler来定制自己的响应错误处理器。客户端请求拦截器ClientHttpRequestInterceptor实现这个接口并在org.springframework.web.client.RestTemplate#setInterceptors(java.util.List)中进行注册能对请求头和请求体的内容进行修改并能对响应的内容进行修改。下面将会讲解RestTemplate中的doExecute方法所有请求方式最终都会执行这个方法重写此方法能完成一些必要的操作。RestTemplate的妙用 考虑这样一个场景假如说A部门开发的用户相关的微服务接口提供给B部门来使用在使用时需要在请求头中加入基本的认证头信息认证头的格式如下 AuthorizationBasic {token}
复制代码token的格式是base64(username:password)。假如username是zfx密码是123结果是先拼接用户名和密码zfx:123再用utf-8格式获取其字节码进行base64编码的结果为emZ4OjEyMw 假如要调用A部门的接口根据id来获取用户的信息代码如下 String userId 11;
String url http://127.0.0.1:8080/v1/users/{id};RestTemplate restTemplate new RestTemplate();// 基本的认证头信息
String username zfx;
String password 123;
String token Base64Utils.encodeToString((username : password).getBytes(StandardCharsets.UTF_8));
HttpHeaders headers new HttpHeaders();
headers.add(Authorization, Basic token);
HttpEntityVoid requestEntity new HttpEntity(headers);ResponseEntityUser exchange restTemplate.exchange(url, HttpMethod.GET, requestEntity, User.class, userId);
User result exchange.getBody();
复制代码首先先创建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();ListClientHttpRequestInterceptor 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 BearerAuthorizationInterceptimplements ClientHttpRequestInterceptor {Overridepublic 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();ListClientHttpRequestInterceptor 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);
复制代码转载于:https://juejin.im/post/5c8cba09e51d453e2762de2f