SpringBoot跨系统调用接口方案
参考:Spring Boot实现跨系统接口调用
一、简介
项目开发中存在系统之间互调问题,又不想用dubbo,这里提供几种springboot方案:
1、使用Feign进行消费(推荐)
2、使用原始httpClient请求
3、使用RestTemplate方法
二、方案
方案一:使用Feign进行消费(推荐)
1、在maven中添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.2</version>
</dependency>
2、启动类上加上@EnableFeignClients
@EnableHystrix
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {"com.aaa.aurora"})
@SpringBootApplication
@EnableTransactionManagement
@ComponentScan(basePackages = "com.aaa.aurora")
@ImportResource(locations= {"classpath:spring.xml","spring-security.xml"})
@MapperScan("com.aaa.aurora.mapper")
public class AuroraWebApplication {
public static void main(String[] args) {
SpringApplication.run(AuroraWebApplication.class, args);
}
}
3、编写service接口
@FeignClient(url = "${pangu.url}",name = "panguUrl")
public interface PanGuService {
@RequestMapping(value = "/pangu/restful/check",method = RequestMethod.POST)
JSONObject check(@RequestParam(name="queryEngine") String queryEngine, @RequestParam(name="querySql") String querySql, @RequestParam(name="jobNo") String jobNo);
}
其中:pangu.url是配置在application.properties中的ip及端口
pangu.url = 192.168.1.3:8080
/pangu/restful/check是要调的接口名
4、代码中调用
@Autowired
private PanGuService panGuService;
JSONObject jsonObject = null;
try {
jsonObject = panGuService.auroraPriviledge(PRESTO_DRIVER, query.get("sql"), user.getWorkNo());
} catch (Exception e) {
throw new Exception("请求系统异常");
}
if (PANGU_FAIL.equals(jsonObject.get("code"))) {
LOG.info(jsonObject.get("msg").toString());
throw new BusinessException(jsonObject.get("msg").toString());
}
方案二:使用原始httpClient请求
使用HttpClient发送请求、接收响应很简单,一般需要如下几步即可。
1. 创建HttpClient对象。
2. 创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。
3. 如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HttpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。
4. 调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。
5. 调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
6. 释放连接。无论执行方法是否成功,都必须释放连接。
public JSONObject doPost(String queryEngine, String querySql, String jobNo) {
JSONObject jsonObject = null;
//1.创建httpClient对象
CloseableHttpClient client = HttpClients.createDefault();
//2.创建请求方法的实例,并指定请求URL
String url = "http://192.168.1.11:8080";
HttpPost post = new HttpPost(url);
post.setHeader("Content-Type", "application/json;charset=utf8");
//3.参数
AuroraPriviledge auroraPriviledge = new AuroraPriviledge();
auroraPriviledge.setQueryEngine(queryEngine);
auroraPriviledge.setQuerySql(querySql);
auroraPriviledge.setJobNo(jobNo);
String jsonString = JSON.toJSONString(auroraPriviledge);
StringEntity entity = new StringEntity(jsonString, "UTF-8");
post.setEntity(entity);
//4.调用execute,返回response
CloseableHttpResponse response = null;
try {
response = client.execute(post);
HttpEntity responseEntity = response.getEntity();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (client != null) {
client.close();
}
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return jsonObject;
}
方案三:使用RestTemplate方法
1.get请求:getForObject(...)和getForEntity(...)两个方法,区别在于前者直接返回预期的对象,即返回体中的body对象,后者返回的是ResponseEntity封装类,里面包含了HTTP请求的头信息。
2.post请求:与get请求类似,只是多一个request参数,request对象会作为httpEntity进行处理。
package com.yyy.aurora;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
/**
* Description
*
* @author Bob
* @date 2020/4/15
**/
public class TestRest {
public static void main(String[] args) {
RestTemplate restTemplate = new RestTemplate();
//get请求
//方法一:getForEntity(String url, Class<T> responseType, Object... uriVariables),没有参数
String url = "https://restapi.amap.com/v3/ip?key=075b6eddd825148a674dfa8a8558ac62";
ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);
System.out.println(forEntity);
// <200,{"status":"1","info":"OK","infocode":"10000","province":"上海市","city":"上海市","adcode":"310000","rectangle":"120.8397067,30.77980118;122.1137989,31.66889673"},{Server=[Tengine], Date=[Sat, 18 Apr 2020 02:47:38 GMT], Content-Type=[application/json;charset=UTF-8], Content-Length=[167], Connection=[close], X-Powered-By=[ring/1.0.0], gsid=[011130051098158717805837600019751129378], sc=[0.071], Access-Control-Allow-Origin=[*], Access-Control-Allow-Methods=[*], Access-Control-Allow-Headers=[DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,key,x-biz,x-info,platinfo,encr,enginever,gzipped,poiid]}>
String s = restTemplate.getForObject(url, String.class);
System.out.println(s);
// {"province":"上海市","city":"上海市","adcode":"310000","infocode":"10000","rectangle":"120.8397067,30.77980118;122.1137989,31.66889673","status":"1","info":"OK"}
//方法一:getForEntity(String url, Class<T> responseType, Object... uriVariables),url中用占位符,传入参数
//该方法提供了三个参数,其中var1为请求的地址(即url),var2为请求响应body的包装类型,var3为url中的参数绑定
url = "https://restapi.amap.com/v3/ip?key={?}";
forEntity = restTemplate.getForEntity(url, String.class, "075b6eddd825148a674dfa8a8558ac62");
//方法二:getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables),map传参
url = "https://restapi.amap.com/v3/ip?key={key}";
Map<String, Object> map = new HashMap<>();
map.put("key", "075b6eddd825148a674dfa8a8558ac62");
forEntity = restTemplate.getForEntity(url, String.class, map);
//方法三:getForEntity(URI url, Class<T> responseType),uri传参
URI uri = URI.create("https://restapi.amap.com/v3/ip?key=075b6eddd825148a674dfa8a8558ac62");
forEntity = restTemplate.getForEntity(uri, String.class);
//post请求,与get请求类型,只是多一个必填request对象
//postForEntity(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables)
forEntity = restTemplate.postForEntity(url, null, String.class, "075b6eddd825148a674dfa8a8558ac62");
s = restTemplate.postForObject(url, null, String.class, "075b6eddd825148a674dfa8a8558ac62");
}
}
完整的post请求:
try{
SimpleClientHttpRequestFactory rf = new SimpleClientHttpRequestFactory();
//设置请求超时
rf.setConnectTimeout(3000);
rf.setReadTimeout(30000);e
RestTemplate restTemplate = new RestTemplate(rf);
HttpHeaders headers = new HttpHeaders();
//请求type
headers.setContentType(MediaType.APPLICATION_JSON);
//返回type
headers.add("accept",MediaType.APPLICATION_JSON.toString());
String url = "http://ip:port/rest/11111";
Map<String,Object> map = new HashMap<>();
map.put("no","426335367373");
HttpEntity<String> httpEntity = new HttpEntity<String>(JSONObject.toJSONString(map),headers);
String result = restTemplate.postForObject(url,httpEntity,String.class);
log.info("res:{}",JSONObject.toJSONString(result))
}catch (Exception e){
log.error(e);
}
避免每次都要new restTemplate,可以用下面注入的方式:
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(3000); // ms
factory.setConnectTimeout(30000); // ms
return factory;
}
}
service中直接注入即可:
@Autowired
private RestTemplate restTemplate;
参考:
Spring-Boot 访问外部接口的几种方案总结_polo2044的博客-CSDN博客_springboot调用外部接口
Spring Boot实现跨系统接口调用_henry_ying的博客-CSDN博客
HttpClient详细使用示例_justry_deng的博客-CSDN博客_httpclient
HttpClient用法--这一篇全了解(内含例子)_Franco蜡笔小强的博客-CSDN博客_httpclient
Springboot之restTemplate配置及使用_L-960的博客-CSDN博客_springboot配置resttemplate
更多推荐
所有评论(0)