• SpringBoot 调用外部接口的三种方式


    1、简介

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

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

    1.  /*
    2.      * @description get方式获取入参,插入数据并发起流程
    3.      * @author lyx
    4.      * @params documentId
    5.      * @return String
    6.      */
    7.     //
    8.     @RequestMapping("/submit/{documentId}")
    9.     public String submit1(@PathVariable String documentId) throws ParseException {
    10.         //此处将要发送的数据转换为json格式字符串
    11.         Map<String,Object> map =task2Service.getMap(documentId);
    12.         String jsonStr = JSON.toJSONString(map, SerializerFeature.WRITE_MAP_NULL_FEATURES,SerializerFeature.QuoteFieldNames);
    13.         JSONObject jsonObject = JSON.parseObject(jsonStr);
    14.         JSONObject sr = task2Service.doPost(jsonObject);
    15.         return sr.toString();
    16.     }
    1. /*
    2.      * @description 使用原生httpClient调用外部接口
    3.      * @author lyx
    4.      * @date 2022/8/24 16:08
    5.      * @params date
    6.      * @return JSONObject
    7.      */
    8.     public static JSONObject doPost(JSONObject date) {
    9.         String assessToken="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ4ZGFwYXBwaWQiOiIzNDgxMjU4ODk2OTI2OTY1NzYiLCJleHAiOjE2NjEyMjY5MDgsImlhdCI6MTY2MTIxOTcwOCwieGRhcHRlbmFudGlkIjoiMzAwOTgxNjA1MTE0MDUyNjA5IiwieGRhcHVzZXJpZCI6IjEwMDM0NzY2MzU4MzM1OTc5NTIwMCJ9.fZAO4kJSv2rSH0RBiL1zghdko8Npmu_9ufo6Wex_TI2q9gsiLp7XaW7U9Cu7uewEOaX4DTdpbFmMPvLUtcj_sQ";
    10.         CloseableHttpClient client = HttpClients.createDefault();
    11.         // 要调用的接口url
    12.         String url = "http://39.103.201.110:30661 /xdap-open/open/process/v1/submit";
    13.         HttpPost post = new HttpPost(url);
    14.         JSONObject jsonObject = null;
    15.         try {
    16.             //创建请求体并添加数据
    17.             StringEntity s = new StringEntity(date.toString());
    18.             //此处相当于在header里头添加content-type等参数
    19.             s.setContentType("application/json");
    20.             s.setContentEncoding("UTF-8");
    21.             post.setEntity(s);
    22.             //此处相当于在Authorization里头添加Bear token参数信息
    23.             post.addHeader("Authorization""Bearer " +assessToken);
    24.             HttpResponse res = client.execute(post);
    25.             String response1 = EntityUtils.toString(res.getEntity());
    26.             if (res.getStatusLine()
    27.                     .getStatusCode() == HttpStatus.SC_OK) {
    28.                 // 返回json格式:
    29.                 String result = EntityUtils.toString(res.getEntity());
    30.                 jsonObject = JSONObject.parseObject(result);
    31.             }
    32.         } catch (Exception e) {
    33.             throw new RuntimeException(e);
    34.         }
    35.         return jsonObject;
    36.     }

    3、方式二:使用RestTemplate方法

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

    插播一条,如果你近期准备面试跳槽,建议在ddkk.com在线刷题,涵盖 1万+ 道 Java 面试题,几乎覆盖了所有主流技术面试题,还有市面上最全的技术栈500套,精品系列教程,免费提供。

    • Get请求

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

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

    getForEntity(Stringurl,Class responseType,Object…urlVariables)

    getForEntity(URI url,Class responseType)

    • Get--getForEntity(URI url,Class responseType)

    1. //该方法使用URI对象来替代之前的url和urlVariables参数来指定访问地址和参数绑定。URI是JDK java.net包下的一个类,表示一个统一资源标识符(Uniform Resource Identifier)引用。参考如下:
    2. RestTemplate restTemplate=new RestTemplate();
    3. UriComponents 
    4. uriComponents=UriComponentsBuilder.fromUriString("http://USER-SERVICE/user?name={name}")
    5. .build()
    6. .expand("dodo")
    7. .encode();
    8. URI uri=uriComponents.toUri();
    9. ResponseEntityresponseEntity=restTemplate.getForEntity(uri,String.class).getBody();
    • Get--getForEntity(Stringurl,Class responseType,Object…urlVariables)

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

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

    getForObject(String url,Class responseType,Object...urlVariables)
    getForObject(String url,Class responseType,Map urlVariables)
    getForObject(URI url,Class responseType)

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

    • Post 请求

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

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

    postForEntity(String url,Object request,Class responseType,Object... uriVariables) postForEntity(String url,Object request,Class responseType,Map uriVariables) postForEntity(URI url,Object request,Class responseType)

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

    1.   /*
    2.      * @description post方式获取入参,插入数据并发起流程
    3.      * @author lyx
    4.      * @date 2022/8/24 16:07
    5.      * @params
    6.      * @return
    7.      */
    8.     @PostMapping("/submit2")
    9.     public Object insertFinanceCompensation(@RequestBody JSONObject jsonObject) {
    10.         String documentId=jsonObject.get("documentId").toString();
    11.         return task2Service.submit(documentId);
    12.     }
    1. /*
    2.      * @description 使用restTimeplate调外部接口
    3.      * @author lyx
    4.      * @date 2022/8/24 16:02
    5.      * @params documentId
    6.      * @return String
    7.      */
    8.     public String submit(String documentId){
    9.         String assessToken="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ4ZGFwYXBwaWQiOiIzNDgxMjU4ODk2OTI2OTY1NzYiLCJleHAiOjE2NjEyMjY5MDgsImlhdCI6MTY2MTIxOTcwOCwieGRhcHRlbmFudGlkIjoiMzAwOTgxNjA1MTE0MDUyNjA5IiwieGRhcHVzZXJpZCI6IjEwMDM0NzY2MzU4MzM1OTc5NTIwMCJ9.fZAO4kJSv2rSH0RBiL1zghdko8Npmu_9ufo6Wex_TI2q9gsiLp7XaW7U9Cu7uewEOaX4DTdpbFmMPvLUtcj_sQ";
    10.         RestTemplate restTemplate = new RestTemplate();
    11.         //创建请求头
    12.         HttpHeaders httpHeaders = new HttpHeaders();
    13.         //此处相当于在Authorization里头添加Bear token参数信息
    14.         httpHeaders.add(HttpHeaders.AUTHORIZATION, "Bearer " + assessToken);
    15.         //此处相当于在header里头添加content-type等参数
    16.         httpHeaders.add(HttpHeaders.CONTENT_TYPE,"application/json");
    17.         Map<StringObject> map = getMap(documentId);
    18.         String jsonStr = JSON.toJSONString(map);
    19.         //创建请求体并添加数据
    20.         HttpEntity<Map> httpEntity = new HttpEntity<Map>(map, httpHeaders);
    21.         String url = "http://39.103.201.110:30661/xdap-open/open/process/v1/submit";
    22.         ResponseEntity<String> forEntity = restTemplate.postForEntity(url,httpEntity,String.class);//此处三个参数分别是请求地址、请求体以及返回参数类型
    23.         return forEntity.toString();
    24.     }

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

    • 在maven项目中添加依赖

    1. <dependency>
    2.     <groupId>org.springframework.cloud</groupId>
    3.     <artifactId>spring-cloud-starter-feign</artifactId>
    4.     <version>1.2.2.RELEASE</version>
    5. </dependency>
    • 启动类上加上@EnableFeignClients

    1. @SpringBootApplication
    2. @EnableFeignClients
    3. @ComponentScan(basePackages = {"com.definesys.mpaas""com.xdap.*" ,"com.xdap.*"})
    4. public class MobilecardApplication {
    5.     public static void main(String[] args) {
    6.         SpringApplication.run(MobilecardApplication.class, args);
    7.     }
    8. }
    • 此处编写接口模拟外部接口供feign调用外部接口方式使用

    定义controller

    1.     @Autowired
    2.     PrintService printService;
    3.  
    4.     @PostMapping("/outSide")
    5.     public String test(@RequestBody TestDto testDto) {
    6.         return printService.print(testDto);
    7.     }

    定义service

    1. @Service
    2. public interface PrintService {
    3.     public String print(TestDto testDto);
    4. }

    定义serviceImpl

    1. public class PrintServiceImpl implements PrintService {
    2.     @Override
    3.     public String print(TestDto testDto) {
    4.         return "模拟外部系统的接口功能"+testDto.getId();
    5.     }
    6. }
    • 构建Feigin的Service

    定义service

    1. //此处name需要设置不为空,url需要在.properties中设置
    2. @Service
    3. @FeignClient(url = "${outSide.url}", name = "service2")
    4. public interface FeignService2 {
    5.     @RequestMapping(value = "/custom/outSide", method = RequestMethod.POST)
    6.     @ResponseBody
    7.     public String getMessage(@Valid @RequestBody TestDto testDto);
    8. }

    定义controller

    1.     @Autowired
    2.     FeignService2 feignService2;
    3.     //测试feign调用外部接口入口
    4.     @PostMapping("/test2")
    5.     public String test2(@RequestBody TestDto testDto) {
    6.         return feignService2.getMessage(testDto);
    7.     }
    • postman测试

    图片

     

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

    补充如下:

    添加Header解决方法

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

    定义config

    1. @Configuration
    2. public class FeignConfig implements RequestInterceptor {
    3.     @Override
    4.     public void apply(RequestTemplate requestTemplate) {
    5.         //添加token
    6.         requestTemplate.header("token""eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ4ZGFwYXBwaWQiOiIzNDgxMjU4ODk2OTI2OTY1NzYiLCJleHAiOjE2NjEyMjY5MDgsImlhdCI6MTY2MTIxOTcwOCwieGRhcHRlbmFudGlkIjoiMzAwOTgxNjA1MTE0MDUyNjA5IiwieGRhcHVzZXJpZCI6IjEwMDM0NzY2MzU4MzM1OTc5NTIwMCJ9.fZAO4kJSv2rSH0RBiL1zghdko8Npmu_9ufo6Wex_TI2q9gsiLp7XaW7U9Cu7uewEOaX4DTdpbFmMPvLUtcj_sQ");
    7.     }
    8. }

    定义service

    1. @Service
    2. @FeignClient(url = "${outSide.url}",name = "feignServer", configuration = FeignDemoConfig.class)
    3. public interface TokenDemoClient {
    4.     @RequestMapping(value = "/custom/outSideAddToken", method = RequestMethod.POST)
    5.     @ResponseBody
    6.     public String getMessage(@Valid @RequestBody TestDto testDto);
    7. }

    定义controller

    1. //测试feign调用外部接口入口,加上token
    2.     @PostMapping("/testToken")
    3.     public String test4(@RequestBody TestDto testDto) {
    4.         return tokenDemoClient.getMessage(testDto);
    5.     }

  • 相关阅读:
    http(下)
    thinkphp+mysql校园篮球比赛网站vue+elementui
    基于SpringBoot医院信息管理系统源码
    web前端期末大作业网课设计与实现 _简单DIV布局旅游网页——简洁的旅游酒店公寓(15页)HTML+CSS+JavaScript
    docker安装mysql、clickhouse、oracle等各种数据库汇总
    【数据结构】串(三)—— KMP 算法
    操作教程:EasyDSS如何将MP4点播文件转化成RTSP视频流?
    【前置句与倒装句练习题】否定词放句首的倒装
    istio系列:第五章-ServiceEntry内到外的通讯配置
    【算法题】从数量最多的堆取走礼物
  • 原文地址:https://blog.csdn.net/yuechuzhixing/article/details/133704114