欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

使用SpringBoot跨系统调用接口的方案

程序员文章站 2022-11-17 12:51:22
一、简介项目开发中存在系统之间互调问题,又不想用dubbo,这里提供几种springboot方案:1、使用feign进行消费(推荐)2、使用原始httpclient请求3、使用resttemplate...

一、简介

项目开发中存在系统之间互调问题,又不想用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");
 }
}

补充:springboot关于系统之间的远程互相调用

1、springboot关于系统之间的远程互相调用

可以采用resttemplate方式发起rest http调用,提供有get、post等方式。

1、1远程工具类

此处使用post方式,参考下面封装的httpclient类 1.1

/**
 * created by @kai on 2018/12/24/024.
 * time: 13:54
 * desc: 远程连接工具类
 */
@service
public class httpclient {
​
 /**
 * 根据远程地址发起访问-参数类型为form表单
 * @param url 远程地址
 * @param method 远程方法
 * @param params  方法参数
 * @return
 */
 public object client(string url,httpmethod method,multivaluemap<string,string> params){
  resttemplate resttemplate = new resttemplate();
  httpheaders headers = new httpheaders();
  headers.add("content-type", "application/x-www-form-urlencoded");
  httpentity<multivaluemap<string, string>> httpentity = new httpentity<>(params, headers);
  responseentity<string> responseentity = resttemplate.postforentity(url,httpentity,string.class);
  string body = responseentity.getbody();
  jsonobject jsonobject = jsonobject.parseobject(body);
  return jsonobject.get("data");
 }
​
 /**
 * 根据远程地址发起访问-参数类型为json
 * @param url 远程地址
 * @param method 远程方法
 * @param params  方法参数
 * @return
 */
 public object clientjson(string url,httpmethod method,map<string,object> params){
  resttemplate resttemplate = new resttemplate();
  httpheaders headers = new httpheaders();
  headers.setcontenttype(mediatype.application_json_utf8);
  cn.hutool.json.jsonobject jsonobject = jsonutil.parsefrommap(params);
  httpentity<cn.hutool.json.jsonobject> httpentity = new httpentity<>(jsonobject, headers);
  responseentity<string> responseentity = resttemplate.postforentity(url,httpentity,string.class);
  string body = responseentity.getbody();
  jsonobject jsonobjectresult = jsonobject.parseobject(body);
  return jsonobjectresult.get("data");
 }
​
}

[ 1.1​]

1、2远程参数说明

工具类中提供了远程过程中传递参数的两种格式:

其中 headers.add("content-type", "application/x-www-form-urlencoded") 为form表单格式,支持键值对数据传输;

当参数类型为form表单时,数据需要封装成multivaluemap<string,string>格式,前台使用controller接受时,可以直接使用 multivaluemap 变量接收,参照代码如下 1.2

/**
 * 保存分组策略对象
 * @param
 * @return
 */
@requestmapping(value = "/savedocgrouppolicy",method = requestmethod.post)
public apiresult savegrouppolicy(@requestparam multivaluemap<string,string> parammap,@valid groupstrategyio groupstrategyio){
 integer userid = shiroutil.getexamuserid();
 list<string> userlist = new arraylist<>();
 userlist.add(userid+"");
 parammap.put("userid",userlist);
 object jsonobject = httpclient.client(examconfigconstants.url+"/exam/configpolicy/savedocgrouppolicy", httpmethod.post, parammap);
 return apiresult.success(jsonobject);
}

[ 1.2] 接受参数为form对象

headers.setcontenttype(mediatype.application_json_utf8) 

为json数据格式

当参数为json格式时,远程服务器接受参数需加上注解@requestbody,对于复杂参数可以使用对象接受,将对象转为map,对数据进行加工,再将map转化为jsonobject,参照代码如下:1.3

/**
 * 保存试卷策略
 * @param paperstrategyio 试卷策略对象
 * @return
 */
@requestmapping(value = "/savepaperconfig")
public apiresult savepaperconfig(@requestbody paperstrategyio paperstrategyio){
 map<string, object> parammap = beanutil.beantomap(paperstrategyio);
 integer userid = shiroutil.getexamuserid();
 parammap.put("userid",userid);
 object jsonobject = httpclient.clientjson(examconfigconstants.url+"/exam/paper/savepaperconfigwithmap", httpmethod.post, parammap);
 return apiresult.success(jsonobject);
}

[ 1.3​] 接收参数为复杂json串

2、后记

关于resttemplate还有很多可调用的api,可以查看官方网站了解

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。