使用SpringBoot跨系统调用接口的方案
一、简介
项目开发中存在系统之间互调问题,又不想用dubbo,这里提供几种springboot方案:
1、使用Feign进行消费(推荐)
2、使用原始httpClient请求
3、使用RestTemplate方法
二、方案
方案一:使用Feign进行消费(推荐)
1、在maven中添加依赖
org.springframework.cloud spring-cloud-starter-openfeign 2.2.2
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") publicclassAuroraWebApplication{ publicstaticvoidmain(String[]args){ SpringApplication.run(AuroraWebApplication.class,args); } }
3、编写service接口
@FeignClient(url="${pangu.url}",name="panguUrl") publicinterfacePanGuService{ @RequestMapping(value="/pangu/restful/check",method=RequestMethod.POST) JSONObjectcheck(@RequestParam(name="queryEngine")StringqueryEngine,@RequestParam(name="querySql")StringquerySql,@RequestParam(name="jobNo")StringjobNo); }
其中:pangu.url是配置在application.properties中的ip及端口
pangu.url=192.168.1.3:8080 /pangu/restful/check是要调的接口名
4、代码中调用
@Autowired privatePanGuServicepanGuService; JSONObjectjsonObject=null; try{ jsonObject=panGuService.auroraPriviledge(PRESTO_DRIVER,query.get("sql"),user.getWorkNo()); }catch(Exceptione){ thrownewException("请求系统异常"); } if(PANGU_FAIL.equals(jsonObject.get("code"))){ LOG.info(jsonObject.get("msg").toString()); thrownewBusinessException(jsonObject.get("msg").toString()); }
方案二:使用原始httpClient请求
使用HttpClient发送请求、接收响应很简单,一般需要如下几步即可。
1.创建HttpClient对象。
2.创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。
3.如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HttpParamsparams)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntityentity)方法来设置请求参数。
4.调用HttpClient对象的execute(HttpUriRequestrequest)发送请求,该方法返回一个HttpResponse。
5.调用HttpResponse的getAllHeaders()、getHeaders(Stringname)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
6.释放连接。无论执行方法是否成功,都必须释放连接。
publicJSONObjectdoPost(StringqueryEngine,StringquerySql,StringjobNo){ JSONObjectjsonObject=null; //1.创建httpClient对象 CloseableHttpClientclient=HttpClients.createDefault(); //2.创建请求方法的实例,并指定请求URL Stringurl="http://192.168.1.11:8080"; HttpPostpost=newHttpPost(url); post.setHeader("Content-Type","application/json;charset=utf8"); //3.参数 AuroraPriviledgeauroraPriviledge=newAuroraPriviledge(); auroraPriviledge.setQueryEngine(queryEngine); auroraPriviledge.setQuerySql(querySql); auroraPriviledge.setJobNo(jobNo); StringjsonString=JSON.toJSONString(auroraPriviledge); StringEntityentity=newStringEntity(jsonString,"UTF-8"); post.setEntity(entity); //4.调用execute,返回response CloseableHttpResponseresponse=null; try{ response=client.execute(post); HttpEntityresponseEntity=response.getEntity(); }catch(IOExceptione){ e.printStackTrace(); }catch(Exceptione){ e.printStackTrace(); }finally{ try{ if(client!=null){ client.close(); } if(response!=null){ response.close(); } }catch(IOExceptione){ e.printStackTrace(); } } returnjsonObject; }
方案三:使用RestTemplate方法
1.get请求:getForObject(...)和getForEntity(...)两个方法,区别在于前者直接返回预期的对象,即返回体中的body对象,后者返回的是ResponseEntity封装类,里面包含了HTTP请求的头信息。
2.post请求:与get请求类似,只是多一个request参数,request对象会作为httpEntity进行处理。
packagecom.yyy.aurora; importorg.springframework.http.ResponseEntity; importorg.springframework.web.client.RestTemplate; importjava.net.URI; importjava.util.HashMap; importjava.util.Map; /** *Description * *@authorBob *@date2020/4/15 **/ publicclassTestRest{ publicstaticvoidmain(String[]args){ RestTemplaterestTemplate=newRestTemplate(); //get请求 //方法一:getForEntity(Stringurl,ClassresponseType,Object...uriVariables),没有参数 Stringurl="https://restapi.amap.com/v3/ip?key=075b6eddd825148a674dfa8a8558ac62"; ResponseEntity 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,18Apr202002:47:38GMT],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]}> Strings=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(Stringurl,Class 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(Stringurl,Class responseType,Map uriVariables),map传参 url="https://restapi.amap.com/v3/ip?key={key}"; Map map=newHashMap<>(); map.put("key","075b6eddd825148a674dfa8a8558ac62"); forEntity=restTemplate.getForEntity(url,String.class,map); //方法三:getForEntity(URIurl,Class responseType),uri传参 URIuri=URI.create("https://restapi.amap.com/v3/ip?key=075b6eddd825148a674dfa8a8558ac62"); forEntity=restTemplate.getForEntity(uri,String.class); //post请求,与get请求类型,只是多一个必填request对象 //postForEntity(Stringurl,@NullableObjectrequest,Class responseType,Object...uriVariables) forEntity=restTemplate.postForEntity(url,null,String.class,"075b6eddd825148a674dfa8a8558ac62"); s=restTemplate.postForObject(url,null,String.class,"075b6eddd825148a674dfa8a8558ac62"); } }
补充:SpringBoot关于系统之间的远程互相调用
1、SpringBoot关于系统之间的远程互相调用
可以采用RestTemplate方式发起RestHttp调用,提供有get、post等方式。
1、1远程工具类
此处使用Post方式,参考下面封装的HttpClient类1.1
/** *Createdby@kaion2018/12/24/024. *Time:13:54 *Desc:远程连接工具类 */ @Service publicclassHttpClient{ /** *根据远程地址发起访问-参数类型为form表单 *@paramurl远程地址 *@parammethod远程方法 *@paramparams方法参数 *@return */ publicObjectclient(Stringurl,HttpMethodmethod,MultiValueMapparams){ RestTemplaterestTemplate=newRestTemplate(); HttpHeadersheaders=newHttpHeaders(); headers.add("Content-Type","application/x-www-form-urlencoded"); HttpEntity >httpEntity=newHttpEntity<>(params,headers); ResponseEntity responseEntity=restTemplate.postForEntity(url,httpEntity,String.class); Stringbody=responseEntity.getBody(); JSONObjectjsonObject=JSONObject.parseObject(body); returnjsonObject.get("data"); } /** *根据远程地址发起访问-参数类型为JSON *@paramurl远程地址 *@parammethod远程方法 *@paramparams方法参数 *@return */ publicObjectclientJson(Stringurl,HttpMethodmethod,Map params){ RestTemplaterestTemplate=newRestTemplate(); HttpHeadersheaders=newHttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON_UTF8); cn.hutool.json.JSONObjectjsonObject=JSONUtil.parseFromMap(params); HttpEntity httpEntity=newHttpEntity<>(jsonObject,headers); ResponseEntity responseEntity=restTemplate.postForEntity(url,httpEntity,String.class); Stringbody=responseEntity.getBody(); JSONObjectjsonObjectResult=JSONObject.parseObject(body); returnjsonObjectResult.get("data"); } }
[1.1]
1、2远程参数说明
工具类中提供了远程过程中传递参数的两种格式:
其中headers.add("Content-Type","application/x-www-form-urlencoded")为form表单格式,支持键值对数据传输;
当参数类型为form表单时,数据需要封装成MultiValueMap
/** *保存分组策略对象 *@param *@return */ @RequestMapping(value="/saveDocGroupPolicy",method=RequestMethod.POST) publicApiResultsaveGroupPolicy(@RequestParamMultiValueMapparamMap,@ValidGroupStrategyIOgroupStrategyIO){ IntegeruserId=ShiroUtil.getExamUserId(); List userList=newArrayList<>(); userList.add(userId+""); paramMap.put("userId",userList); ObjectjsonObject=httpClient.client(ExamConfigConstants.url+"/exam/configPolicy/saveDocGroupPolicy",HttpMethod.POST,paramMap); returnApiResult.success(jsonObject); }
[1.2]接受参数为form对象
headers.setContentType(MediaType.APPLICATION_JSON_UTF8)
为json数据格式
当参数为json格式时,远程服务器接受参数需加上注解@RequestBody,对于复杂参数可以使用对象接受,将对象转为Map,对数据进行加工,再将map转化为JSONObject,参照代码如下:1.3
/** *保存试卷策略 *@parampaperStrategyIO试卷策略对象 *@return */ @RequestMapping(value="/savePaperConfig") publicApiResultsavePaperConfig(@RequestBodyPaperStrategyIOpaperStrategyIO){ MapparamMap=BeanUtil.beanToMap(paperStrategyIO); IntegeruserId=ShiroUtil.getExamUserId(); paramMap.put("userId",userId); ObjectjsonObject=httpClient.clientJson(ExamConfigConstants.url+"/exam/paper/savePaperConfigWithMap",HttpMethod.POST,paramMap); returnApiResult.success(jsonObject); }
[1.3]接收参数为复杂json串
2、后记
关于RestTemplate还有很多可调用的API,可以查看官方网站了解
http://spring.io/blog/2009/03/27/rest-in-spring-3-resttemplate
以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。