侧边栏壁纸
博主头像
孔子说JAVA博主等级

成功只是一只沦落在鸡窝里的鹰,成功永远属于自信且有毅力的人!

  • 累计撰写 292 篇文章
  • 累计创建 132 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

SpringBoot多种方式调用第三方接口实例

孔子说JAVA
2022-08-09 / 0 评论 / 0 点赞 / 1,303 阅读 / 28,049 字 / 正在检测是否收录...

实际项目开发中免不了要跟其他系统交互,系统之间互调问题,如果是自己本系统的还好,可以通过打jar包引用的方式放到本项目中直接调用,如果是其他系统的就需要通过远程接口调用。SpringBoot可以有多种方式选择,如传统的HttpClient方式,SpringBoot的RestTemplate方法,使用Feign进行消费等。

1、原始HttpClient方式

在没有springboot之前,HttpClient是一个很好的选择。HttpClient是Apache中的一个开源的项目。它实现了HTTP标准中Client端的所有功能,使用它能够很容易地进行HTTP信息的传输。HttpClient的主要功能:

  • 实现了所有 HTTP 的方法(GET、POST、PUT、HEAD、DELETE、HEAD、OPTIONS 等)
  • 支持 HTTPS 协议
  • 支持代理服务器(Nginx)
  • 支持自动(跳转)转向 等等
  • HttpCLient最关键的方法是执行HTTP请求的方法execute。只要把HTTP请求传入,就可以得到HTTP响应。

使用HttpClient请求一个Http请求的步骤为:

  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. 处理response。调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
  6. 关闭HttpClient,无论执行方法是否成功,都必须释放连接。

1.1 引入httpclient依赖

首先引入httpClient的maven依赖:

引入httpcomponents的httpclient

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

也可以使用fegin包下面的httpclient

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
</dependency>

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-jackson</artifactId>
</dependency>

1.2 HttpClient Get方式请求接口

/**
 * 封装HTTP GET方法
 *
 * @param url 请求地址
 * @param paramMap 请求参数
 * @param charset 编码
 * @return
 * @throws ClientProtocolException
 * @throws IOException
*/
public static String doGet(String url, Map<String, String> paramMap, String charset) throws ClientProtocolException, IOException {
    List<NameValuePair> formparams = setHttpParams(paramMap);
    String param = URLEncodedUtils.format(formparams, charset);
    String urlParam = url + "?" + param;
    return doGet(urlParam, charset);
}

/**
 * 封装HTTP GET方法
 *
 * @param url 请求地址
 * @param charset 编码
 *
 * @return
 * @throws ClientProtocolException
 * @throws IOException
*/
public static String doGet(String url, String charset) throws ClientProtocolException, IOException{
    HttpClient httpClient = HttpClients.createDefault();
//		HttpGet httpGet = new HttpGet(url);
    HttpGet httpGet = new HttpGet();
    //设置请求和传输超时时间
    RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000)
        .setConnectTimeout(60000).setConnectionRequestTimeout(60000).build();
    httpGet.setConfig(requestConfig);
    httpGet.setURI(URI.create(url));
    httpGet.setHeader("Accept", DEFAULT_HEADER_ACCEPT);
    httpGet.setHeader("Content-Type", DEFAULT_GET_HEADER_CONTENT_TYPE);
    httpGet.setHeader("User-Agent", DEFAULT_HEADER_USER_AGENT);
    HttpResponse response = httpClient.execute(httpGet);
    HttpEntity entity = response.getEntity();
    String result = null;
    if(entity != null){
        result = EntityUtils.toString(entity,charset);
    }
    httpGet.abort();
    return result;
}

1.3 HttpClient Post方式请求接口

/**
 * 封装HTTP POST方法
 *
 * @param url 请求地址
 * @param paramMap 请求参数Map
 * @param charset 编码
 *
 * @return
 * @throws IOException
 */
public static String doPost(String url, Map<String, String> paramMap, String charset) throws ClientProtocolException, IOException{
    List<NameValuePair> formparams = setHttpParams(paramMap);
    UrlEncodedFormEntity param = new UrlEncodedFormEntity(formparams, charset);
    return doPost(url, param, charset);
}

/**
 * 封装HTTP POST方法
 *
 * @param url 请求地址
 * @param data 请求参数(如JSON串)
 * @param charset 编码
 *
 * @return
 * @throws ClientProtocolException
 * @throws IOException
 */
public static String post(String url, String data, String charset) throws ClientProtocolException, IOException {
    StringEntity entity = new StringEntity(URLEncoder.encode(data, charset));
    return doPost(url, entity, charset);
}

/**
 * 设置请求参数
 *
 * @param
 * @return
 */
private static List<NameValuePair> setHttpParams(Map<String, String> paramMap) {
    List<NameValuePair> formparams = new ArrayList<NameValuePair>();
    Set<Map.Entry<String, String>> set = paramMap.entrySet();
    for (Map.Entry<String, String> entry : set) {
        formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
    }
    return formparams;
}
    
/**
 * 封装HTTP POST方法
 *
 * @param url 请求地址
 * @param entity 请求参数实体
 * @param charset 编码
 *
 * @return
 * @throws ClientProtocolException
 * @throws IOException
 */
private static String doPost(String url, HttpEntity entity, String charset) throws ClientProtocolException, IOException{
    // CloseableHttpClient
    HttpClient httpClient = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost(url);
    //设置请求和传输超时时间
    RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000)
        .setConnectTimeout(60000).setConnectionRequestTimeout(60000).build();
    httpPost.setConfig(requestConfig);
    httpPost.setEntity(entity);
    HttpResponse response = httpClient.execute(httpPost);
    httpPost.setHeader("Accept", DEFAULT_HEADER_ACCEPT);
    httpPost.setHeader("Content-Type", DEFAULT_POST_HEADER_CONTENT_TYPE);
    httpPost.setHeader("User-Agent", DEFAULT_HEADER_USER_AGENT);
    HttpEntity entity = response.getEntity();
    String result = null;
    if(entity != null){
        result = EntityUtils.toString(entity,charset);
    }
    httpPost.abort();
    return result;
}

1.4 CloseableHttpClient Get方式请求接口

示例1:

/**
 * GET---有参测试 (方式一:手动在url后面加上参数)
 *
 */
@Test
public void doGetTestWayOne() {
		// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
 
		// 参数
		StringBuffer params = new StringBuffer();
		try {
			// 字符数据最好encoding以下;这样一来,某些特殊字符才能传过去(如:某人的名字就是“&”,不encoding的话,传不过去)
			params.append("name=" + URLEncoder.encode("&", "utf-8"));
			params.append("&");
			params.append("age=24");
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
 
		// 创建Get请求
		HttpGet httpGet = new HttpGet("http://localhost:12345/doGetControllerTwo" + "?" + params);
		// 响应模型
		CloseableHttpResponse response = null;
		try {
			// 配置信息
			RequestConfig requestConfig = RequestConfig.custom()
					// 设置连接超时时间(单位毫秒)
					.setConnectTimeout(5000)
					// 设置请求超时时间(单位毫秒)
					.setConnectionRequestTimeout(5000)
					// socket读写超时时间(单位毫秒)
					.setSocketTimeout(5000)
					// 设置是否允许重定向(默认为true)
					.setRedirectsEnabled(true).build();
 
			// 将上面的配置信息 运用到这个Get请求里
			httpGet.setConfig(requestConfig);
 
			// 由客户端执行(发送)Get请求
			response = httpClient.execute(httpGet);
 
			// 从响应模型中获取响应实体
			HttpEntity responseEntity = response.getEntity();
			System.out.println("响应状态为:" + response.getStatusLine());
			if (responseEntity != null) {
				System.out.println("响应内容长度为:" + responseEntity.getContentLength());
				System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				// 释放资源
				if (httpClient != null) {
					httpClient.close();
				}
				if (response != null) {
					response.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
}

示例2:

/**
 * GET---有参测试 (方式二:将参数放入键值对类中,再放入URI中,从而通过URI得到HttpGet实例)
 *
 */
@Test
public void doGetTestWayTwo() {
		// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
 
		// 参数
		URI uri = null;
		try {
			// 将参数放入键值对类NameValuePair中,再放入集合中
			List<NameValuePair> params = new ArrayList<>();
			params.add(new BasicNameValuePair("name", "&"));
			params.add(new BasicNameValuePair("age", "18"));
			// 设置uri信息,并将参数集合放入uri;
			// 注:这里也支持一个键值对一个键值对地往里面放setParameter(String key, String value)
			uri = new URIBuilder().setScheme("http").setHost("localhost")
					              .setPort(12345).setPath("/doGetControllerTwo")
					              .setParameters(params).build();
		} catch (URISyntaxException e1) {
			e1.printStackTrace();
		}
		// 创建Get请求
		HttpGet httpGet = new HttpGet(uri);
 
		// 响应模型
		CloseableHttpResponse response = null;
		try {
			// 配置信息
			RequestConfig requestConfig = RequestConfig.custom()
					// 设置连接超时时间(单位毫秒)
					.setConnectTimeout(5000)
					// 设置请求超时时间(单位毫秒)
					.setConnectionRequestTimeout(5000)
					// socket读写超时时间(单位毫秒)
					.setSocketTimeout(5000)
					// 设置是否允许重定向(默认为true)
					.setRedirectsEnabled(true).build();
 
			// 将上面的配置信息 运用到这个Get请求里
			httpGet.setConfig(requestConfig);
 
			// 由客户端执行(发送)Get请求
			response = httpClient.execute(httpGet);
 
			// 从响应模型中获取响应实体
			HttpEntity responseEntity = response.getEntity();
			System.out.println("响应状态为:" + response.getStatusLine());
			if (responseEntity != null) {
				System.out.println("响应内容长度为:" + responseEntity.getContentLength());
				System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				// 释放资源
				if (httpClient != null) {
					httpClient.close();
				}
				if (response != null) {
					response.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
}

1.5 CloseableHttpClient Post方式请求接口

POST无参:

/**
 * POST---无参测试
 *
 */
@Test
public void doPostTestOne() {
 
		// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
 
		// 创建Post请求
		HttpPost httpPost = new HttpPost("http://localhost:12345/doPostControllerOne");
		// 响应模型
		CloseableHttpResponse response = null;
		try {
			// 由客户端执行(发送)Post请求
			response = httpClient.execute(httpPost);
			// 从响应模型中获取响应实体
			HttpEntity responseEntity = response.getEntity();
 
			System.out.println("响应状态为:" + response.getStatusLine());
			if (responseEntity != null) {
				System.out.println("响应内容长度为:" + responseEntity.getContentLength());
				System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				// 释放资源
				if (httpClient != null) {
					httpClient.close();
				}
				if (response != null) {
					response.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
}

POST有参(普通参数):

POST传递普通参数时,方式与GET一样即可,这里以直接在url后缀上参数的方式示例。

/**
 * POST---有参测试(普通参数)
 *
 */
@Test
public void doPostTestFour() {
 
		// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
 
		// 参数
		StringBuffer params = new StringBuffer();
		try {
			// 字符数据最好encoding以下;这样一来,某些特殊字符才能传过去(如:某人的名字就是“&”,不encoding的话,传不过去)
			params.append("name=" + URLEncoder.encode("&", "utf-8"));
			params.append("&");
			params.append("age=24");
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
 
		// 创建Post请求
		HttpPost httpPost = new HttpPost("http://localhost:12345/doPostControllerFour" + "?" + params);
 
		// 设置ContentType(注:如果只是传普通参数的话,ContentType不一定非要用application/json)
		httpPost.setHeader("Content-Type", "application/json;charset=utf8");
 
		// 响应模型
		CloseableHttpResponse response = null;
		try {
			// 由客户端执行(发送)Post请求
			response = httpClient.execute(httpPost);
			// 从响应模型中获取响应实体
			HttpEntity responseEntity = response.getEntity();
 
			System.out.println("响应状态为:" + response.getStatusLine());
			if (responseEntity != null) {
				System.out.println("响应内容长度为:" + responseEntity.getContentLength());
				System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				// 释放资源
				if (httpClient != null) {
					httpClient.close();
				}
				if (response != null) {
					response.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
}

POST有参(对象参数):

/**
 * POST---有参测试(对象参数)
 *
 */
@Test
	public void doPostTestTwo() {
 
		// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
 
		// 创建Post请求
		HttpPost httpPost = new HttpPost("http://localhost:12345/doPostControllerTwo");
		User user = new User();
		user.setName("潘晓婷");
		user.setAge(18);
		user.setGender("女");
		user.setMotto("姿势要优雅~");
		// 我这里利用阿里的fastjson,将Object转换为json字符串;
		// (需要导入com.alibaba.fastjson.JSON包)
		String jsonString = JSON.toJSONString(user);
 
		StringEntity entity = new StringEntity(jsonString, "UTF-8");
 
		// post请求是将参数放在请求体里面传过去的;这里将entity放入post请求体中
		httpPost.setEntity(entity);
 
		httpPost.setHeader("Content-Type", "application/json;charset=utf8");
 
		// 响应模型
		CloseableHttpResponse response = null;
		try {
			// 由客户端执行(发送)Post请求
			response = httpClient.execute(httpPost);
			// 从响应模型中获取响应实体
			HttpEntity responseEntity = response.getEntity();
 
			System.out.println("响应状态为:" + response.getStatusLine());
			if (responseEntity != null) {
				System.out.println("响应内容长度为:" + responseEntity.getContentLength());
				System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				// 释放资源
				if (httpClient != null) {
					httpClient.close();
				}
				if (response != null) {
					response.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
}

2、SpringBoot的RestTemplate方式

Spring框架提供的RestTemplate类可用于在应用中调用rest服务,它简化了与http服务的通信方式,统一了RESTful的标准,封装了http链接, 我们只需要传入url及返回值类型即可。相较于之前常用的HttpClient,RestTemplate是一种更优雅的调用RESTful服务的方式。

  • RestTemplate默认依赖JDK提供http连接的能力(HttpURLConnection),如果有需要的话也可以通过setRequestFactory方法替换为例如 Apache HttpComponents、Netty或OkHttp等其它HTTP library。

  • RestTemplate提供有get、post等方式。RestTemplate官方网站

    • get请求:getForObject(…)和getForEntity(…)两个方法,区别在于前者直接返回预期的对象,即返回体中的body对象,后者返回的是ResponseEntity封装类,里面包含了HTTP请求的头信息。
    • post请求:与get请求类似,只是多一个request参数,request对象会作为httpEntity进行处理。
RestTemplate restTemplate = new RestTemplate();

// 方法一: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);

// 方法二: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");

通过rest接口调用远程服务步骤:

2.1 调用和被调用的接口

1)需要调用三方服务的类

@RestController
@RequestMapping("demo")

public class DemoController {

    @GetMapping("getUser")
    public void getUser(@RequestParam("name")String name){
        //此处需要远程调用第三方服务 获取user对象
    }

    @GetMapping("saveUser")
    public void getUser(){
        UserDto userDto = new UserDto();
        userDto.setName("resttemplate");
        userDto.setAge(17);
        userDto.setBirthday(new Date());
        //此处需要远程调用第三方服务 将user对象发送给第三方
    }
}

2)第三方服务

@RestController
@RequestMapping("api")

//此类是模拟第三方提供服务的
public class ApiController {

    //模拟获取数据
    @GetMapping("get")
    public UserDto get(@RequestParam("username")String username){
        System.out.println("从数据库中查询username【"+username+"】的数据");
        UserDto userDto = new UserDto();
        userDto.setName("springboot");
        userDto.setAge(18);
        userDto.setBirthday(new Date());

        return userDto;
    }

    //模拟接收数据保存到数据库
    @GetMapping("save")
    public UserDto save(@RequestBody UserDto userDto) throws JsonProcessingException {
        System.out.println(new ObjectMapper().writeValueAsString(userDto));
        //TODO:保存到数据库
        return userDto;
    }
}

假设第三方服务的两个接口分别为:localhost:8080/demo/api/get 和 localhost:8080/demo/api/save。

2.2 使用RestTemplate进行远程调用

在Application中声明一个RestTemplate。

@Bean
public RestTemplate restTemplate(){
    return new RestTemplate();
}

在DemoController中使用@Resource注入进来。

image-1660010390398

实际生产实例中还会涉及到超时,如果第三方响应太慢了,则不再等待。RestTemplate也可以做到,我们不是在Application中声明了一个RestTemplate吗?,只需要将如下代码替换即可。

@Bean
public SimpleClientHttpRequestFactory httpClientFactory() {
    SimpleClientHttpRequestFactory httpRequestFactory = new SimpleClientHttpRequestFactory();
    httpRequestFactory.setReadTimeout(1000*5);//读取超时
    httpRequestFactory.setConnectTimeout(1000*5);//链接超时

    return httpRequestFactory;
}

@Bean
public RestTemplate restTemplate(SimpleClientHttpRequestFactory httpClientFactory) {
    RestTemplate restTemplate = new RestTemplate(httpClientFactory);
    return restTemplate;
}

2.3 RestTemplate工具类

/**
 * 远程连接工具类
 */
@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 远程方法
     * @aram params  方法参数
     * @eturn
     */
    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");
    }
}

工具类中提供了远程过程中传递参数的两种格式:其中 headers.add(“Content-Type”, “application/x-www-form-urlencoded”) 为form表单格式,支持键值对数据传输;当参数类型为form表单时,数据需要封装成MultiValueMap<String,String>格式,前台使用controller接受时,可以直接使用 MultiValueMap 变量接收,代码如下:

接受参数为form对象

/**
 * 保存分组策略对象
 * @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);
}
headers.setContentType(MediaType.APPLICATION_JSON_UTF8)

接收参数为复杂json串

当参数为json格式时,远程服务器接受参数需加上注解@RequestBody,对于复杂参数可以使用对象接受,将对象转为Map,对数据进行加工,再将map转化为JSONObject。

/**
 * 保存试卷策略
 * @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);
}

3、使用Feign进行消费

3.1 在maven中添加依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>2.2.2</version>
</dependency>

3.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.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是要调的接口名

3.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());
}

4、HttpURLConnection方式

使用java.net自带的HttpURLConnection进行第三方接口的调用:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.logging.log4j.util.Strings;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.*;
import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

public class HttpUtil2 {

    /****************************************x-www-form-urlencoded*********************************************/
    public static <T> T getRequestByUrlencoded(String path , HashMap<String , Object> params, Type clazz){
        HttpURLConnection conn = null;
        BufferedReader br = null;
        InputStream is = null;
        String body = "";
        StringBuffer sb = new StringBuffer(path);
        //请求参数拼接到路径上
        if (!CollectionUtils.isEmpty(params)){
            sb.append("?");
            for (Map.Entry<String , Object> entry : params.entrySet()){
                sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }
            body = sb.substring(0 , sb.length()-1);
        }
        try {
            URL url = new URL(body);
            //打开与url之间的连接
            conn = (HttpURLConnection) url.openConnection();
            //不设置默认使用get
            conn.setRequestMethod("GET");
            conn.setRequestProperty("accept" , "*/*");
            conn.setRequestProperty("user-agent" , "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            conn.setRequestProperty("content-Type" , "application/x-www-form-urlencoded");
            conn.setRequestProperty("connection" , "keep-Alive");

            //本次连接是否自动使用重定向
            conn.setInstanceFollowRedirects(true);
            is = conn.getInputStream();
            br = new BufferedReader(new InputStreamReader(is));
            StringBuffer result = new StringBuffer();
            while ((body=br.readLine()) != null){
                result.append(body);
            }
            body = result.toString();
            if (Strings.isNotBlank(body)){
                Gson gson = new GsonBuilder().create();
                return gson.fromJson(body , clazz);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (conn != null){
                conn.disconnect();
            }
        }
        return null;
    }


    public static <T> T postRequestByUrlencoded(String path , HashMap<String , String> headers , Type clazz){
        DataOutputStream out = null;
        BufferedReader br = null;
        InputStream is = null;
        HttpURLConnection conn = null;
        StringBuffer sb = new StringBuffer();
        StringBuffer result = new StringBuffer();
        String body = "";
        try {
            URL url = new URL(path);
            //打开与url之间的连接
            conn = (HttpURLConnection) url.openConnection();
            //设置请求方式
            conn.setRequestMethod("POST");
            // Post 请求不能使用缓存
            conn.setUseCaches(false);
            //设置本次连接是否自动重定向
            conn.setInstanceFollowRedirects(true);
            //设置通用的请求属性
            conn.setRequestProperty("accept" , "*/*");
            conn.setRequestProperty("connection" , "keep-Alive");
            conn.setRequestProperty("user-agent" , "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            conn.setRequestProperty("content-Type" , "application/x-www-form-urlencoded");

            if (!CollectionUtils.isEmpty(headers)){
                for (Map.Entry<String , String> entry : headers.entrySet()){
                    sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
                }
                body =  sb.substring(0 , sb.length()-1);
            }

            //setDoOutput设置是否向httpUrlConnection输出,setDoInput设置是否向httpUrlConnection读入,发送post请求必须设置这两个属性
            conn.setDoOutput(true);
            conn.setDoInput(true);

            //获取URLConnection对象对应的输出流
            out = new DataOutputStream(conn.getOutputStream());
            //发送请求参数即数据
            out.writeBytes(body);
            out.flush();
            //获取URLConnection对象对应的输入流
            is = conn.getInputStream();
            br = new BufferedReader(new InputStreamReader(is));
            String str = "";
            while ((str=br.readLine())!=null){
                result.append(str);
            }
            str = result.toString();
            if (Strings.isNotBlank(str)){
                Gson gson = new GsonBuilder().create();
                return gson.fromJson(str , clazz);
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null){
                conn.disconnect();
            }
        }
        return null;
    }

/*************************************application/json*************************************************/
   //此方法可以使用,但具体是否正确有待商榷
   //首先:get请求方式传递json数据应该放在请求协议包的哪里,其次:setDoOutput方法要设置为true,即使是get方式,否则无法向URLConnection发送数据
    public static <T> T getRequestByJson(String path , String data ,Type clazz){
        OutputStreamWriter out = null;
        BufferedReader br = null;
        InputStream is = null;
        HttpURLConnection conn = null;
        StringBuffer sb = new StringBuffer();
        String result = "";

        try {
            URL url = new URL(path);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");

            conn.setRequestProperty("accept" , "*/*");
            conn.setRequestProperty("connection" , "keep-Alive");
            conn.setRequestProperty("user-agent" , "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            conn.setRequestProperty("content-Type" , "application/json;charset=utf-8");
            
            //从源码看,应该是检查是否连接,未连接的话进行连接
            conn.setDoOutput(true);
            conn.setDoInput(true);

            out = new OutputStreamWriter(conn.getOutputStream() , "UTF-8");
            out.write(data);
            out.flush();

            is = conn.getInputStream();
            br = new BufferedReader(new InputStreamReader(is));
            String body = "";
            while ((body=br.readLine())!=null){
                sb.append(body);
            }
            result = sb.toString();
            if (Strings.isNotBlank(result)){
                Gson gson = new GsonBuilder().create();
                return gson.fromJson(result , clazz);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null){
                conn.disconnect();
            }
        }
        return null;
    }



    public static <T> T postRequestByJson(String path , String data , Type clazz){
        OutputStreamWriter out = null;
        BufferedReader br = null;
        InputStream is = null;
        HttpURLConnection conn = null;
        StringBuffer sb = new StringBuffer();
        String result = "";
        try {
            URL url = new URL(path);
            //打开与url之间的连接
            conn = (HttpURLConnection) url.openConnection();
            //设置请求方式
            conn.setRequestMethod("POST");
            //设置通用的请求属性
            conn.setRequestProperty("accept" , "*/*");
            conn.setRequestProperty("connection" , "keep-Alive");
            conn.setRequestProperty("user-agent" , "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            conn.setRequestProperty("content-Type" , "application/json;charset=utf-8");

            //setDoOutput设置是否向httpUrlConnection输出,setDoInput设置是否向httpUrlConnection读入,发送post请求必须设置这两个属性
            conn.setDoOutput(true);
            conn.setDoInput(true);

            //获取URLConnection对象对应的输出流
            out = new OutputStreamWriter(conn.getOutputStream() , "UTF-8");
            //发送请求参数即数据
            out.write(data);
            out.flush();

            //获取URLConnection对象对应的输入流
            is = conn.getInputStream();
            br = new BufferedReader(new InputStreamReader(is));
            String str = "";
            while ((str=br.readLine())!=null){
                sb.append(str);
            }
            str = sb.toString();
            if (Strings.isNotBlank(str)){
               Gson gson = new GsonBuilder().create();
               return gson.fromJson(sb.toString() , clazz);
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null){
                conn.disconnect();
            }
        }
        return null;
    }
}
0

评论区