SpringBoot不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。在Spring-Boot项目开发中,存在着本模块的代码需要访问外面模块接口,或外部url链接的需求。
调用外部接口是指在应用程序中与其他系统、服务或服务端点进行通信,以获取数据或执行某些操作。这种通信可以通过 HTTP、HTTPS、SOAP、gRPC 等协议来实现。
调用外部接口通常涉及以下几个步骤:
创建请求:根据接口文档或约定,构造请求的 URL、请求方法(如 GET、POST、PUT、DELETE 等)、请求头、请求参数等信息。
发送请求:使用合适的客户端工具(如 RestTemplate、WebClient、Feign 等)发送请求。这些工具提供了便捷的 API 来发送请求并将响应结果返回给你。
处理响应:根据接口的响应格式(如 JSON、XML 等),解析响应内容并提取需要的数据。你可以使用解析库(如 Jackson、Gson、JAXB 等)来处理响应内容。
错误处理:在调用外部接口时,可能会遇到各种错误情况,如网络连接失败、接口返回错误码等。你需要适当处理这些错误情况,例如进行重试、回退、记录日志等操作。
在调用外部接口时,还需要注意以下事项:
接口安全性:如果接口需要身份验证或授权,你需要提供相应的凭据(如 API 密钥、令牌)或配置安全设置,以确保请求能够被正确处理。
异步调用和并发性:如果你的应用程序需要高并发或异步处理,你可以考虑使用基于消息队列、异步任务或多线程等技术,在后台进行接口调用,以提高系统的性能和可伸缩性。
监控和日志记录:对于重要的接口调用,建议设置适当的监控和日志记录,以便及时发现问题并进行故障排查。
总之,调用外部接口是实现应用程序与其他系统集成的重要方式,它能够使你的应用程序获取到外部数据,实现复杂的业务逻辑,并与其他系统进行交互。选择合适的调用方式和合理处理错误情况,能够保证接口调用的可靠性和性能。
/** 1. 跨域请求工具类 */ public class HttpClientUtils { public static String doGet(String url, Mapparam) { // 创建Httpclient对象 CloseableHttpClient httpclient = HttpClients.createDefault(); String resultString = ""; CloseableHttpResponse response = null; try { // 创建uri URIBuilder builder = new URIBuilder(url); if (param != null) { for (String key : param.keySet()) { builder.addParameter(key, param.get(key)); } } URI uri = builder.build(); // 创建http GET请求 HttpGet httpGet = new HttpGet(uri); // 执行请求 response = httpclient.execute(httpGet); // 判断返回状态是否为200 if (response.getStatusLine().getStatusCode() == 200) { resultString = EntityUtils.toString(response.getEntity(), "UTF-8"); } } catch (Exception e) { e.printStackTrace(); } finally { try { if (response != null) { response.close(); } httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } return resultString; } public static String doGet(String url) { return doGet(url, null); } public static String doPost(String url, Map param) { // 创建Httpclient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse response = null; String resultString = ""; try { // 创建Http Post请求 HttpPost httpPost = new HttpPost(url); // 创建参数列表 if (param != null) { List paramList = new ArrayList<>(); for (String key : param.keySet()) { paramList.add(new BasicNameValuePair(key, param.get(key))); } // 模拟表单 UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList); httpPost.setEntity(entity); } // 执行http请求 response = httpClient.execute(httpPost); resultString = EntityUtils.toString(response.getEntity(), "utf-8"); } catch (Exception e) { e.printStackTrace(); } finally { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } return resultString; } public static String doPost(String url) { return doPost(url, null); } public static String doPostJson(String url, String json) { // 创建Httpclient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse response = null; String resultString = ""; try { // 创建Http Post请求 HttpPost httpPost = new HttpPost(url); // 创建请求内容 StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON); httpPost.setEntity(entity); // 执行http请求 response = httpClient.execute(httpPost); resultString = EntityUtils.toString(response.getEntity(), "utf-8"); } catch (Exception e) { e.printStackTrace(); } finally { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } return resultString; } }
RestTemplate 是 Spring 框架提供的用于访问 RESTful 服务的客户端工具类。它封装了常见的 HTTP 请求操作,提供了简单易用的 API,这里主要介绍Get和Post方法的使用。
在 RestTemplate 中,getForEntity 方法有多个重载形式,可以根据需要选择合适的方法进行 GET 请求。提供了getForObject 、getForEntity两种方式。
以下是 getForEntity 方法的三种形式:
1. getForEntity(String url, ClassresponseType, Object... uriVariables); 2. getForEntity(String url, Class responseType, Map uriVariables); 3. getForEntity(URI url, Class responseType);
以下是对每个方法的说明和示例:
getForEntity(String url, Class
该方法提供了三个参数,其中url为请求的地址,responseType为请求响应body的包装类型,urlVariables为url中的参数绑定
示例:
RestTemplate restTemplate = new RestTemplate(); ResponseEntityresponse = restTemplate.getForEntity("http://example.com/api/users/{id}", User.class, 1); User user = response.getBody();
getForEntity(String url, Class
示例:
RestTemplate restTemplate = new RestTemplate(); MapuriVariables = new HashMap<>(); uriVariables.put("id", 1); ResponseEntity response = restTemplate.getForEntity("http://example.com/api/users/{id}", User.class, uriVariables); User user = response.getBody();
getForEntity(URI url, Class
示例:
RestTemplate restTemplate = new RestTemplate(); URI url = new URI("http://example.com/api/users/1"); ResponseEntityresponse = restTemplate.getForEntity(url, User.class); User user = response.getBody();
或者
RestTemplate restTemplate=new RestTemplate(); UriComponents uriComponents=UriComponentsBuilder.fromUriString("http://example.com/api/users/{id}") .build() .expand(1) .encode(); URI uri=uriComponents.toUri(); ResponseEntityresponse = restTemplate.getForEntity(uri, User.class); User user = response.getBody();
以下是 getForEntity 方法的三种形式:
1. getForObject(String url, ClassresponseType, Object... uriVariables); 2. getForObject(String url, Class responseType, Map uriVariables); 3. getForObject(URI url, Class responseType);
这段代码是 RestTemplate 类中的 getForObject 方法的重写实现。它用于发送 GET 请求,并返回一个指定类型的对象,而不是完整的响应实体。
以下是对每个方法的说明和示例:
getForObject(String url, Class
示例:
RestTemplate restTemplate = new RestTemplate(); User user = restTemplate.getForObject("http://example.com/api/users/{id}", User.class, 1);
getForObject(String url, Class
示例:
RestTemplate restTemplate = new RestTemplate(); MapuriVariables = new HashMap<>(); uriVariables.put("id", 1); User user = restTemplate.getForObject("http://example.com/api/users/{id}", User.class, uriVariables);
getForObject(URI url, Class
示例:
RestTemplate restTemplate = new RestTemplate(); URI url = new URI("http://example.com/api/users/1"); User user = restTemplate.getForObject(url, User.class);
getForObject 和 getForEntity 是 RestTemplate 类中用于发送 GET 请求并获取响应的两个方法。它们在功能上有一些相似之处,但也有一些区别。
相同点:
区别:
选择使用哪个方法取决于你对响应的需求:
示例:
RestTemplate restTemplate = new RestTemplate(); // 使用 getForObject 方法 User user1 = restTemplate.getForObject("http://example.com/api/users/1", User.class); // 使用 getForEntity 方法 ResponseEntityresponseEntity = restTemplate.getForEntity("http://example.com/api/users/1", User.class); User user2 = responseEntity.getBody(); HttpStatus statusCode = responseEntity.getStatusCode(); HttpHeaders headers = responseEntity.getHeaders();
总之,getForObject 和 getForEntity 都是用于发送 GET 请求并获取响应的方法,选择使用哪个方法取决于你对响应的需求。
Post请求提供有postForEntity、postForObject和postForLocation三种方式,其中每种方式都有三种方法,下面介绍postForEntity的使用方法。
以下是 postForEntity 方法的三种形式:
1. postForEntity(String url, @Nullable Object request,ClassresponseType, Object... uriVariables); 2. postForEntity(String url, @Nullable Object request,Class responseType, Map uriVariables); 3. postForEntity(URI url, @Nullable Object request, Class responseType);
这段代码是 RestTemplate 类中的 postForEntity 方法的重写实现。它用于发送 POST 请求,并返回一个包含完整响应信息的 ResponseEntity 对象,而不仅仅是响应体内容。
下面是对每个重写方法的详细说明和示例:
postForEntity(String url, @Nullable Object request, Class
示例:
RestTemplate restTemplate = new RestTemplate(); User userRequest = new User("John", "Doe"); ResponseEntityresponseEntity = restTemplate.postForEntity("http://example.com/api/users", userRequest, User.class, 1); User user = responseEntity.getBody(); HttpStatus statusCode = responseEntity.getStatusCode(); HttpHeaders headers = responseEntity.getHeaders();
postForEntity(String url, @Nullable Object request, Class
示例:
RestTemplate restTemplate = new RestTemplate(); User userRequest = new User("John", "Doe"); MapuriVariables = new HashMap<>(); uriVariables.put("id", 1); ResponseEntity responseEntity = restTemplate.postForEntity("http://example.com/api/users/{id}", userRequest, User.class, uriVariables); User user = responseEntity.getBody(); HttpStatus statusCode = responseEntity.getStatusCode(); HttpHeaders headers = responseEntity.getHeaders();
postForEntity(URI url, @Nullable Object request, Class
示例:
RestTemplate restTemplate = new RestTemplate(); User userRequest = new User("John", "Doe"); URI url = new URI("http://example.com/api/users"); ResponseEntityresponseEntity = restTemplate.postForEntity(url, userRequest, User.class); User user = responseEntity.getBody(); HttpStatus statusCode = responseEntity.getStatusCode(); HttpHeaders headers = responseEntity.getHeaders();
注:
request 和 uriVariables 是用于构造 POST 请求的两个不同的参数,它们在不同的作用域中起作用。
request 参数:
- request 参数表示发送 POST 请求时的请求体内容。
- 它可以是任意类型的对象,根据实际的请求需求来决定具体的类型。通常情况下,request 参数会作为请求体的内容进行发送。
- 如果你的 POST 请求不需要请求体,可以将 request 参数设置为 null。
uriVariables 参数:
- uriVariables 参数表示可选的路径参数,用于替换 URL 中的占位符。
- 它是一个可变参数,可以传递多个参数值。参数值的顺序必须与 URL 中占位符的顺序一致。
- 在发送 POST 请求时,将路径参数与 URL 进行替换,以获得最终的请求 URL。
综上所述,request 和 uriVariables 是两个用于构建 POST
请求不同参数,分别代表请求体的内容和路径参数。需要根据具体的需求来使用它们。如果需要发送请求体,将内容放在 request
参数中;如果需要替换 URL 中的占位符,将参数值传递给 uriVariables 参数。
以下是 postForObject 方法的三种形式:
1. postForObject(String url, @Nullable Object request, ClassresponseType,Object... uriVariables); 2. postForObject(String url, @Nullable Object request, Class responseType,Map uriVariables); 3. postForObject(URI url, @Nullable Object request, Class responseType);
这是 RestTemplate 类中关于 POST 请求的三个 postForObject 方法的实现。下面将详细解释每个方法及其示例用法:
postForObject(String url, @Nullable Object request, Class
示例:
String url = "http://example.com/api/users/{id}"; User request = new User("John", "Doe"); ClassresponseType = User.class; Object[] uriVariables = { 1 }; User user = restTemplate.postForObject(url, request, responseType, uriVariables);
postForObject(String url, @Nullable Object request, Class
示例:
String url = "http://example.com/api/users/{id}"; User request = new User("John", "Doe"); ClassresponseType = User.class; Map uriVariables = new HashMap<>(); uriVariables.put("id", 1); User user = restTemplate.postForObject(url, request, responseType, uriVariables);
postForObject(URI url, @Nullable Object request, Class
示例:
URI url = new URI("http://example.com/api/users"); User request = new User("John", "Doe"); ClassresponseType = User.class; User user = restTemplate.postForObject(url, request, responseType);
以下是 postForLocation 方法的三种形式:
1. postForLocation(String url, @Nullable Object request, Object... uriVariables); 2. postForLocation(String url, @Nullable Object request, MapuriVariables); 3. postForLocation(URI url, @Nullable Object request);
这是 RestTemplate 类中关于 POST 请求并获取 Location 头部信息的三个 postForLocation 方法的实现。下面将详细解释每个方法及其示例用法:
postForLocation(String url, @Nullable Object request, Object... uriVariables)
示例:
String url = "http://example.com/api/users"; User request = new User("John", "Doe"); Object[] uriVariables = { 1 }; URI location = restTemplate.postForLocation(url, request, uriVariables);
postForLocation(String url, @Nullable Object request, Map
示例:
String url = "http://example.com/api/users"; User request = new User("John", "Doe"); MapuriVariables = new HashMap<>(); uriVariables.put("id", 1); URI location = restTemplate.postForLocation(url, request, uriVariables);
postForLocation(URI url, @Nullable Object request)
示例:
URI url = new URI("http://example.com/api/users"); User request = new User("John", "Doe"); URI location = restTemplate.postForLocation(url, request);
postForEntity、postForObject 和 postForLocation 都是 RestTemplate 类中用于发送 POST 请求的方法,它们之间存在一些联系和区别。
联系:
区别:
返回值类型:
使用场景:
总结:
这三个方法都用于发送 POST 请求,根据需要返回不同的信息。如果需要完整的响应信息,包括响应状态码、头部信息和响应体,可以使用 postForEntity;如果只需要响应体内容,可以使用 postForObject;如果仅关注响应头部中的 Location 信息,可以使用 postForLocation。
Feign 是一个声明式的、基于接口的 HTTP 客户端,它简化了使用 Spring Cloud 进行远程服务调用的过程。通过 Feign,可以以声明式的方式定义和调用远程服务接口,而无需手动编写实现代码。
在使用 Feign 进行消费时,需要完成以下几个步骤:
创建 Feign 客户端接口:定义一个接口,使用 @FeignClient 注解指定服务名称和服务地址。该接口中定义了需要调用的远程服务接口的方法及其相关信息,例如 HTTP 方法、URL 路径、请求参数和请求体等。
启用 Feign 客户端:在 Spring Boot 应用程序的启动类或配置类上添加 @EnableFeignClients 注解,以启用 Feign 客户端功能。
使用 Feign 客户端接口:通过注入 Feign 客户端接口对象,即可使用该接口中定义的方法进行远程服务调用。Feign 会根据接口定义自动实现具体的调用逻辑,并处理请求和响应。
Feign 的工作原理如下:
Feign 还具备以下特性:
总而言之,Feign 提供了一种简单且优雅的方式来定义和调用远程服务接口,它屏蔽了底层的 HTTP 请求细节,使得远程服务调用更加便捷和灵活。同时,通过与 Spring Cloud 的集成,Feign 还可以享受到负载均衡、服务发现等分布式系统支持。
使用 Feign 进行消费时,需要进行以下步骤:
添加 Feign 依赖:在项目的构建文件中添加 Feign 相关的依赖,例如 Maven 的 pom.xml 文件:
org.springframework.cloud spring-cloud-starter-openfeign
启用 Feign 客户端:在 Spring Boot 应用程序的启动类或配置类上添加 @EnableFeignClients 注解,以启用 Feign 客户端功能。
@SpringBootApplication @EnableFeignClients @ComponentScan(basePackages = {"com.definesys.mpaas", "com.xdap.*" ,"com.xdap.*"}) public class MobilecardApplication { public static void main(String[] args) { SpringApplication.run(MobilecardApplication.class, args); } }
创建 Feign 客户端接口:创建一个接口,使用 @FeignClient 注解指定服务名称和服务地址。定义需要调用的 HTTP 方法、URL 路径、请求参数和请求体等信息。例如:
//此处name需要设置不为空,url需要在.properties中设置,也可直接写url @FeignClient(name = "example-service",url = "${outSide.url}") public interface ExampleClient { @GetMapping("/api/users/{id}") User getUser(@PathVariable("id") Long id); @PostMapping("/api/users") User createUser(@RequestBody User user); }
调用 Feign 客户端接口:通过注入 Feign 客户端接口对象,即可使用其定义的方法进行远程服务调用。例如:
@RestController public class ExampleController { private final ExampleClient exampleClient; public ExampleController(ExampleClient exampleClient) { this.exampleClient = exampleClient; } @GetMapping("/users/{id}") public User getUser(@PathVariable Long id) { return exampleClient.getUser(id); } @PostMapping("/users") public User createUser(@RequestBody User user) { return exampleClient.createUser(user); } }
配置 Feign 客户端:可以通过配置文件来配置 Feign 客户端的行为,例如设置连接超时时间、请求重试等。在 application.properties 或 application.yml 文件中添加相关配置。
以上是使用 Feign 进行消费的基本步骤。Feign 可以根据接口定义自动生成符合服务提供方 API 规范的客户端实现,并且内部集成了负载均衡和服务发现等功能,简化了远程服务调用的过程。
在使用 Feign 进行远程服务调用时,可以通过添加 Header 来传递额外的请求信息。下面介绍两种常见的方式来添加 Header。
使用 @RequestHeader 注解:在 Feign 客户端接口的方法参数上使用 @RequestHeader 注解,指定要添加的 Header 的名称和值。例如:
@GetMapping("/api/users/{id}") User getUser(@PathVariable("id") Long id, @RequestHeader("Authorization") String token);
在调用该方法时,将会在请求头中添加一个名为 “Authorization” 的 Header,其值为传入的 token 参数的值。
使用 Interceptor 拦截器:可以自定义一个 Interceptor 实现 RequestInterceptor 接口,在 apply() 方法中添加需要的 Header。例如:
public class CustomHeaderInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { template.header("Authorization", "Bearer your_token"); } }
然后,在 Feign 客户端接口上使用 @FeignClient 注解的 configuration 属性指定使用的拦截器类。例如:
@FeignClient(name = "example-service", url = "http://example.com", configuration = CustomHeaderInterceptor.class) public interface ExampleClient { // ... }
这样,在每次使用该 Feign 客户端接口进行远程调用时,都会在请求头中自动添加上述定义的 Header。
以上是两种常见的添加 Header 的方法。根据实际需求和场景,可以选择适合的方式来添加自定义的 Header 信息。
Spring Boot 调用外部接口的方式有多种,常见的有以下三种方式:RestTemplate、Feign 和 WebClient。它们之间存在一些联系和区别。
RestTemplate:
Feign:
WebClient:
这三种方式在实际使用中有一些联系和区别:
选择使用哪种方式需要根据具体的需求和场景来决定。在 Spring Boot 中,可以根据项目的特点和要求,灵活选择适合的方式进行外部接口调用。