Spring Boot实现系统间接口调用

Spring Boot实现跨系统接口调用
一、概述

在开发过程中经常会需要和其他系统进行对接,或者调用一些外部的第三方接口来获取所需要的数据信息,这个时候我们就需要跨系统去调用接口,本文基于spring boot项目整理三种方案。

1、使用httpClient请求;
2、使用RestTemplate方法;
3、使用Fegin进行消费;

1、使用httpClient请求

需要先在maven的pom.xml中添加httpClient依赖

<dependency>
   <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>

代码如下:

package com.henry.transport;

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;

/**
 * 使用httpclient调用外部接口
 */
public class HttpClient {
    /**
     * get 请求
     * @return
     */
    public static String doHttpGet(String url, List<NameValuePair> params){
        String result = null;
        //1.获取httpclient
       CloseableHttpClient httpClient = HttpClients.createDefault();
       //接口返回结果
        CloseableHttpResponse response = null;
        String paramStr = null;
        try {
            paramStr = EntityUtils.toString(new UrlEncodedFormEntity(params));
            //拼接参数
            StringBuffer sb = new StringBuffer();
            sb.append(url);
            sb.append("?");
            sb.append(paramStr);
            //2.创建get请求
            HttpGet httpGet = new HttpGet(sb.toString());
            //3.设置请求和传输超时时间
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).build();
            httpGet.setConfig(requestConfig);
            /*此处可以添加一些请求头信息,例如:
            httpGet.addHeader("content-type","text/xml");*/
            //4.提交参数
            response = httpClient.execute(httpGet);
            //5.得到响应信息
            int statusCode = response.getStatusLine().getStatusCode();
            //6.判断响应信息是否正确
            if(HttpStatus.SC_OK != statusCode){
                //终止并抛出异常
                httpGet.abort();
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }
            //7.转换成实体类
            HttpEntity entity = response.getEntity();
            if(null != entity){
                result = EntityUtils.toString(entity);
            }
            EntityUtils.consume(entity);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //8.关闭所有资源连接
            if(null != response){
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(null != httpClient){
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    /**
     * http post 请求
     */
    public static String doPost(String url, List<NameValuePair> params){
        String result = null;
        //1. 获取httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        try {
            //2. 创建post请求
            HttpPost httpPost = new HttpPost(url);

            //3.设置请求和传输超时时间
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).build();
            httpPost.setConfig(requestConfig);

            //4.提交参数发送请求
            UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(params);
            /*此处可以设置传输时的编码格式,和数据格式
            urlEncodedFormEntity.setContentEncoding("UTF-8");
            urlEncodedFormEntity.setContentType("application/json");*/
            httpPost.setEntity(urlEncodedFormEntity);

            response = httpClient.execute(httpPost);

            //5.得到响应信息
            int statusCode = response.getStatusLine().getStatusCode();
            //6. 判断响应信息是否正确
            if(HttpStatus.SC_OK != statusCode){
                //结束请求并抛出异常
                httpPost.abort();
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }
            //7. 转换成实体类
            HttpEntity entity = response.getEntity();
            if(null != entity){
                result = EntityUtils.toString(entity,"UTF-8");
            }
            EntityUtils.consume(entity);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //8. 关闭所有资源连接
            if(null != response){
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(null != httpClient){
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }
}

测试请求结果:

package com.henry.transport;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        String url = "https://restapi.amap.com/v3/ip";
        List<NameValuePair> list = new ArrayList<>();
        list.add(new BasicNameValuePair("key","075b6eddd825148a674dfa8a8558****"));
        String resultGet = HttpClient.doHttpGet(url,list);
        System.out.println("get请求" + resultGet);
        String resultPost = HttpClient.doPost(url,list);
        System.out.println("post请求" + resultPost);

    }
}

控制台打印结果:
get请求{“status”:“1”,“info”:“OK”,“infocode”:“10000”,“province”:“江苏省”,“city”:“南京市”,“adcode”:“320100”,“rectangle”:“经纬度坐标”}
post请求{“status”:“1”,“info”:“OK”,“infocode”:“10000”,“province”:“江苏省”,“city”:“南京市”,“adcode”:“320100”,“rectangle”:“经纬度坐标”}

2、使用RestTemplate方法

此处就用使用get和post请求。
2.1 get请求:
有getForObject(…)和getForEntity(…)两个方法都可以进行请求调用,区别在于,getForObject(…)是直接返回预期的对象,即返回体中的body对象,而getForEntity(…)则是返回ResponseEntity 封装类,里面包含HTTP请求的头信息对象。

package com.henry.transport;

import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;

public class Test {
    public static void main(String[] args) {
        RestTemplate restTemplate = new RestTemplate();
        //方法一:getForEntity(String var1, Class<T> var2),没有参数
        String url = "https://restapi.amap.com/v3/ip?key=075b6eddd825148a674dfa8a8558ac62";
        String trans = restTemplate.getForObject(url,String.class);
        System.out.println(trans);

        //方法一:getForEntity(String var1, Class<T> var2, Object... var3),url中用占位符,传入参数
        //该方法提供了三个参数,其中var1为请求的地址(即url),var2为请求响应body的包装类型,var3为url中的参数绑定
        url = "https://restapi.amap.com/v3/ip?key={?}";
        trans = restTemplate.getForObject(url,String.class,"075b6eddd825148a674dfa8a8558ac62");
        System.out.println(trans);

        //方法二:getForEntity(String var1, Class<T> var2, Map<String, ?> var3),map传参
        url = "https://restapi.amap.com/v3/ip?key={key}";
        Map<String,Object> map = new HashMap<>();
        map.put("key","075b6eddd825148a674dfa8a8558ac62");
        trans = restTemplate.getForObject(url,String.class,map);
        System.out.println(trans);

        //方法三:getForEntity(URI var1, Class<T> var2),uri传参
        URI uri = URI.create("https://restapi.amap.com/v3/ip?key=075b6eddd825148a674dfa8a8558ac62");
        trans = restTemplate.getForObject(uri,String.class);
        System.out.println(trans);
    }
}

2.2 post请求:
post请求方式与get请求方式相似,只是在参数中增加了request参数,request对象会作为httpEntity进行处理。
postForObject(…):

1.postForObject(String url,Object request,Class responseType,Object... uriVariables)
2.postForObject(String url,Object request,Class responseType,Map uriVariables)
3.postForObject(URI url,Object request,Class responseType)

postForEntity(…):

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

第三种方法是postForLocation函数

1.postForObject(String url,Object request,Class responseType,Object... uriVariables)
2.postForObject(String url,Object request,Class responseType,Map uriVariables)
3.postForObject(URI url,Object request,Class responseType)

3、使用Fegin进行消费(推荐)(常用于微服务间服务调用)


3.1 首先需要在maven项目的pom.xml中添加fegin依赖。如果需要用JSON传递,也要引入JSON相关的依赖,本文使用alibaba的fastjson依赖。该处可能会由于Spring boot版本出现@EnableFeignClients找不到的问题,具体请看:Spring Boot下使用Feign提示找不到注解@EnableFeignClients的原因及解决方法

扫描二维码关注公众号,回复: 10001251 查看本文章
<dependency>
   <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>2.1.2.RELEASE</version>
</dependency>
<dependency>
   <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>RELEASE</version>
</dependency>

3.2 在service层编写用来消费的接口

@FeignClient(url = "${map.url}",name = "mapurl")
public interface GaoDeMapService {
    @RequestMapping(value = "/v3/ip",method = RequestMethod.GET)
    JSONObject getMap(@RequestParam("ip") String ip,
                      @RequestParam("key") String key);
}

此处@FeignClient表中这是消费者,url中的${map.url}是配置在application.properties中的IP地址和端口号

server.port=8010
map.url = https://restapi.amap.com

RequestMapping中的 “/v3/ip”表示被调用的服务端的接口地址名称;
method表中请求的方式:get或者post都可以;
注意:@RequestParam(“key”)注解后面表示参数名的属性值 key不可以缺少,即()中的值不可缺少,否则可能会报错

Caused by: java.lang.IllegalStateException: RequestParam.value() was empty on parameter 0

3.3 在Spring Boot启动类上添加注释@EnableFeignClients,开启fegin

@SpringBootApplication
@EnableFeignClients
public class TransportApplication {
    public static void main(String[] args) {
        SpringApplication.run(TransportApplication.class, args);
    }
}

3.4 在代码中调用接口即可
本文是以调用高德地图API为例

@RestController
public class TestController {
    @Autowired
    GaoDeMapService gaoDeMapService;

    @RequestMapping("/test2")
    public JSONObject test2( String ip,String key){
        return gaoDeMapService.getMap(ip,key);
    }
}

最后启动项目,在浏览器中数据地址即可获得返回结果

å¨è¿éæå¥å¾çæè¿°

参考文献:

springboot调用外部接口FeignClient
Spring学习笔记之RestTemplate使用小结

发布了47 篇原创文章 · 获赞 223 · 访问量 37万+

猜你喜欢

转载自blog.csdn.net/ccblogger/article/details/103684004
今日推荐