作者:Chelsea


【资料图】

来源:blog.csdn.net/Chelsea__/article/details/126689495

1、简介

SpringBoot不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。在Spring-Boot项目开发中,存在着本模块的代码需要访问外面模块接口,或外部url链接的需求, 比如在apaas开发过程中需要封装接口在接口中调用apaas提供的接口(像发起流程接口submit等等)下面也是提供了三种方式(不使用dubbo的方式)供我们选择

2、方式一:使用原始httpClient请求

/**@descriptionget方式获取入参,插入数据并发起流程*@authorlyx*@date2022/8/2416:05*@paramsdocumentId*@returnString*///@RequestMapping(\"/submit/{documentId}\")publicStringsubmit1(@PathVariableStringdocumentId)throwsParseException{//此处将要发送的数据转换为json格式字符串Mapmap=task2Service.getMap(documentId);StringjsonStr=JSON.toJSONString(map,SerializerFeature.WRITE_MAP_NULL_FEATURES,SerializerFeature.QuoteFieldNames);JSONObjectjsonObject=JSON.parseObject(jsonStr);JSONObjectsr=task2Service.doPost(jsonObject);returnsr.toString();}

/**@description使用原生httpClient调用外部接口*@authorlyx*@date2022/8/2416:08*@paramsdate*@returnJSONObject*/publicstaticJSONObjectdoPost(JSONObjectdate){StringassessToken=\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ4ZGFwYXBwaWQiOiIzNDgxMjU4ODk2OTI2OTY1NzYiLCJleHAiOjE2NjEyMjY5MDgsImlhdCI6MTY2MTIxOTcwOCwieGRhcHRlbmFudGlkIjoiMzAwOTgxNjA1MTE0MDUyNjA5IiwieGRhcHVzZXJpZCI6IjEwMDM0NzY2MzU4MzM1OTc5NTIwMCJ9.fZAO4kJSv2rSH0RBiL1zghdko8Npmu_9ufo6Wex_TI2q9gsiLp7XaW7U9Cu7uewEOaX4DTdpbFmMPvLUtcj_sQ\";CloseableHttpClientclient=HttpClients.createDefault();//要调用的接口urlStringurl=\"http://39.103.201.110:30661/xdap-open/open/process/v1/submit\";HttpPostpost=newHttpPost(url);JSONObjectjsonObject=null;try{//创建请求体并添加数据StringEntitys=newStringEntity(date.toString());//此处相当于在header里头添加content-type等参数s.setContentType(\"application/json\");s.setContentEncoding(\"UTF-8\");post.setEntity(s);//此处相当于在Authorization里头添加Beartoken参数信息post.addHeader(\"Authorization\",\"Bearer\"+assessToken);HttpResponseres=client.execute(post);Stringresponse1=EntityUtils.toString(res.getEntity());if(res.getStatusLine().getStatusCode()==HttpStatus.SC_OK){//返回json格式:Stringresult=EntityUtils.toString(res.getEntity());jsonObject=JSONObject.parseObject(result);}}catch(Exceptione){thrownewRuntimeException(e);}returnjsonObject;}

3、方式二:使用RestTemplate方法

Spring-Boot开发中,RestTemplate同样提供了对外访问的接口API,这里主要介绍Get和Post方法的使用。

Get请求

提供了getForObjectgetForEntity两种方式,其中getForEntity如下三种方法的实现:

Get--getForEntity,存在以下两种方式重载

1.getForEntity(Stringurl,ClassresponseType,Object…urlVariables)2.getForEntity(URIurl,ClassresponseType)

Get--getForEntity(URI url,Class responseType)

//该方法使用URI对象来替代之前的url和urlVariables参数来指定访问地址和参数绑定。URI是JDK java.net包下的一个类,表示一个统一资源标识符(Uniform Resource Identifier)引用。参考如下:RestTemplaterestTemplate=newRestTemplate();UriComponentsuriComponents=UriComponentsBuilder.fromUriString(\"http://USER-SERVICE/user?name={name}\").build().expand(\"dodo\").encode();URIuri=uriComponents.toUri();ResponseEntityresponseEntity=restTemplate.getForEntity(uri,String.class).getBody();

Get--getForEntity(Stringurl,Class responseType,Object…urlVariables)

//该方法提供了三个参数,其中url为请求的地址,responseType为请求响应body的包装类型,urlVariables为url中的参数绑定,该方法的参考调用如下://http://USER-SERVICE/user?name={name)RestTemplaterestTemplate=newRestTemplate();Mapparams=newHashMap<>();params.put(\"name\",\"dada\");//ResponseEntityresponseEntity=restTemplate.getForEntity(\"http://USERSERVICE/user?name={name}\",String.class,params);

Get--getForObject,存在以下三种方式重载

1.getForObject(Stringurl,ClassresponseType,Object...urlVariables)2.getForObject(Stringurl,ClassresponseType,MapurlVariables)3.getForObject(URIurl,ClassresponseType)

getForObject方法可以理解为对getForEntity的进一步封装,它通过HttpMessageConverterExtractor对HTTP的请求响应体body内容进行对象转换,实现请求直接返回包装好的对象内容。

Post 请求

Post请求提供有postForEntitypostForObjectpostForLocation三种方式,其中每种方式都有三种方法,下面介绍postForEntity的使用方法。

Post--postForEntity,存在以下三种方式重载

1.postForEntity(Stringurl,Objectrequest,ClassresponseType,Object...uriVariables)2.postForEntity(Stringurl,Objectrequest,ClassresponseType,MapuriVariables)3.postForEntity(URIurl,Objectrequest,ClassresponseType)

如下仅演示第二种重载方式

/**@descriptionpost方式获取入参,插入数据并发起流程*@authorlyx*@date2022/8/2416:07*@params*@return*/@PostMapping(\"/submit2\")publicObjectinsertFinanceCompensation(@RequestBodyJSONObjectjsonObject){StringdocumentId=jsonObject.get(\"documentId\").toString();returntask2Service.submit(documentId);}
/**@description使用restTimeplate调外部接口*@authorlyx*@date2022/8/2416:02*@paramsdocumentId*@returnString*/publicStringsubmit(StringdocumentId){StringassessToken=\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ4ZGFwYXBwaWQiOiIzNDgxMjU4ODk2OTI2OTY1NzYiLCJleHAiOjE2NjEyMjY5MDgsImlhdCI6MTY2MTIxOTcwOCwieGRhcHRlbmFudGlkIjoiMzAwOTgxNjA1MTE0MDUyNjA5IiwieGRhcHVzZXJpZCI6IjEwMDM0NzY2MzU4MzM1OTc5NTIwMCJ9.fZAO4kJSv2rSH0RBiL1zghdko8Npmu_9ufo6Wex_TI2q9gsiLp7XaW7U9Cu7uewEOaX4DTdpbFmMPvLUtcj_sQ\";RestTemplaterestTemplate=newRestTemplate();//创建请求头HttpHeadershttpHeaders=newHttpHeaders();//此处相当于在Authorization里头添加Beartoken参数信息httpHeaders.add(HttpHeaders.AUTHORIZATION,\"Bearer\"+assessToken);//此处相当于在header里头添加content-type等参数httpHeaders.add(HttpHeaders.CONTENT_TYPE,\"application/json\");Mapmap=getMap(documentId);StringjsonStr=JSON.toJSONString(map);//创建请求体并添加数据HttpEntityhttpEntity=newHttpEntity(map,httpHeaders);Stringurl=\"http://39.103.201.110:30661/xdap-open/open/process/v1/submit\";ResponseEntityforEntity=restTemplate.postForEntity(url,httpEntity,String.class);//此处三个参数分别是请求地址、请求体以及返回参数类型returnforEntity.toString();}

4、方式三:使用Feign进行消费

在maven项目中添加依赖

org.springframework.cloudspring-cloud-starter-feign1.2.2.RELEASE

启动类上加上@EnableFeignClients

@SpringBootApplication@EnableFeignClients@ComponentScan(basePackages={\"com.definesys.mpaas\",\"com.xdap.*\",\"com.xdap.*\"})publicclassMobilecardApplication{publicstaticvoidmain(String[]args){SpringApplication.run(MobilecardApplication.class,args);}}

此处编写接口模拟外部接口供feign调用外部接口方式使用

定义controller

@AutowiredPrintServiceprintService;@PostMapping(\"/outSide\")publicStringtest(@RequestBodyTestDtotestDto){returnprintService.print(testDto);}

定义service

@ServicepublicinterfacePrintService{publicStringprint(TestDtotestDto);}

定义serviceImpl

publicclassPrintServiceImplimplementsPrintService{@OverridepublicStringprint(TestDtotestDto){return\"模拟外部系统的接口功能\"+testDto.getId();}}

构建Feigin的Service

定义service

//此处name需要设置不为空,url需要在.properties中设置@Service@FeignClient(url=\"${outSide.url}\",name=\"service2\")publicinterfaceFeignService2{@RequestMapping(value=\"/custom/outSide\",method=RequestMethod.POST)@ResponseBodypublicStringgetMessage(@Valid@RequestBodyTestDtotestDto);}

定义controller

@AutowiredFeignService2feignService2;//测试feign调用外部接口入口@PostMapping(\"/test2\")publicStringtest2(@RequestBodyTestDtotestDto){returnfeignService2.getMessage(testDto);}

postman测试

此处因为我使用了所在项目,所以需要添加一定的请求头等信息,关于Feign的请求头添加也会在后续补充

补充如下:

添加Header解决方法

将token等信息放入Feign请求头中,主要通过重写RequestInterceptor的apply方法实现

定义config

@ConfigurationpublicclassFeignConfigimplementsRequestInterceptor{@Overridepublicvoidapply(RequestTemplaterequestTemplate){//添加tokenrequestTemplate.header(\"token\",\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ4ZGFwYXBwaWQiOiIzNDgxMjU4ODk2OTI2OTY1NzYiLCJleHAiOjE2NjEyMjY5MDgsImlhdCI6MTY2MTIxOTcwOCwieGRhcHRlbmFudGlkIjoiMzAwOTgxNjA1MTE0MDUyNjA5IiwieGRhcHVzZXJpZCI6IjEwMDM0NzY2MzU4MzM1OTc5NTIwMCJ9.fZAO4kJSv2rSH0RBiL1zghdko8Npmu_9ufo6Wex_TI2q9gsiLp7XaW7U9Cu7uewEOaX4DTdpbFmMPvLUtcj_sQ\");}}

定义service

@Service@FeignClient(url=\"${outSide.url}\",name=\"feignServer\",configuration=FeignDemoConfig.class)publicinterfaceTokenDemoClient{@RequestMapping(value=\"/custom/outSideAddToken\",method=RequestMethod.POST)@ResponseBodypublicStringgetMessage(@Valid@RequestBodyTestDtotestDto);}

定义controller

//测试feign调用外部接口入口,加上token@PostMapping(\"/testToken\")publicStringtest4(@RequestBodyTestDtotestDto){returntokenDemoClient.getMessage(testDto);}

推荐内容