第十八节 SpringBoot实现微服务调用

亮子 2021-05-11 14:03:31 20180 0 0 0

在分布式系统中,微服务调用是非常普遍的,就是在普通架构的系统中,给第三方服务发送请求,也是非常常见的。那么在SpringBoot项目中,如何来访问其他的微服务呢?

1、HttpClient

HttpClient是apache的一个经典项目,长期依赖在http请求开发中,占有绝对的统治地位。他的官网地址如下:

http://hc.apache.org/httpclient-legacy/

在官方网址的首页的最上面有一句话:

The Commons HttpClient project is now end of life, and is no longer being developed. It has been replaced by the Apache HttpComponents project in its HttpClient and HttpCore modules, which offer better performance and more flexibility.

大体的意思就是 HttpClient 项目现已结束,不再开发了。它已经被 HttpComponents 项目中的HttpClient and HttpCore模块所取代了,该项目中的HttpClient和HttpCore模块具有更好的性能和更大的灵活性。

那么接下来,我们就研究一下HttpComponents的使用方法:

1)、添加依赖

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

2)、GET请求

(1)无参的GET请求

	@Test
	public void testGet() throws IOException {
		// 创建Httpclient对象,相当于打开了浏览器
		CloseableHttpClient httpclient = HttpClients.createDefault();

		// 创建HttpGet请求,相当于在浏览器输入地址
		HttpGet httpGet = new HttpGet("http://localhost:8080/json");

		CloseableHttpResponse response = null;
		try {
			// 执行请求,相当于敲完地址后按下回车。获取响应
			response = httpclient.execute(httpGet);
			// 判断返回状态是否为200
			if (response.getStatusLine().getStatusCode() == 200) {
				// 解析响应,获取数据
				String content = EntityUtils.toString(response.getEntity(), "UTF-8");
				System.out.println(content);
			}
		} finally {
			if (response != null) {
				// 关闭资源
				response.close();
			}
			// 关闭浏览器
			httpclient.close();
		}
	}

(2)有参的GET请求

	@Test
	public void testGetByParams() throws URISyntaxException, IOException {
		// 创建Httpclient对象
		CloseableHttpClient httpclient = HttpClients.createDefault();
		// 创建URI对象,并且设置请求参数
		URI uri = new URIBuilder("http://localhost:8080/jsonParam")
				.setParameter("userName", "林冲")
				.setParameter("userAge", "23")
				.build();
		// 创建http GET请求
		HttpGet httpGet = new HttpGet(uri);

		CloseableHttpResponse response = null;
		try {
			// 执行请求
			response = httpclient.execute(httpGet);
			// 判断返回状态是否为200
			if (response.getStatusLine().getStatusCode() == 200) {
				// 解析响应数据
				String content = EntityUtils.toString(response.getEntity(), "UTF-8");
				System.out.println(content);
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} finally {
			if (response != null) {
				response.close();
			}
			httpclient.close();
		}
	}

3)、POST请求

(1)无参的POST请求

	@Test
	public void postTest() throws IOException {
		// 创建Httpclient对象
		CloseableHttpClient httpclient = HttpClients.createDefault();
		// 创建http POST请求
		HttpPost httpPost = new HttpPost("http://localhost:8080/json");
		// 把自己伪装成浏览器。否则开源中国会拦截访问
		httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36");

		CloseableHttpResponse response = null;
		try {
			// 执行请求
			response = httpclient.execute(httpPost);
			// 判断返回状态是否为200
			if (response.getStatusLine().getStatusCode() == 200) {
				// 解析响应数据
				String content = EntityUtils.toString(response.getEntity(), "UTF-8");
				System.out.println(content);
			}
		} finally {
			if (response != null) {
				response.close();
			}
			// 关闭浏览器
			httpclient.close();
		}
	}

(2)有参的POST请求(FORM格式)

	@Test
	public void postTestByParams() throws IOException {
		// 创建Httpclient对象
		CloseableHttpClient httpclient = HttpClients.createDefault();
		// 创建http POST请求
		HttpPost httpPost = new HttpPost("http://localhost:8080/jsonParam");

		// 根据接口请求需要,设置post请求参数
		List<NameValuePair> parameters = new ArrayList<NameValuePair>(0);
		parameters.add(new BasicNameValuePair("userName", "孙悟空"));
		parameters.add(new BasicNameValuePair("userAge", "500"));
		// 构造一个form表单式的实体
		UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters, Charset.forName("UTF-8"));
		// 将请求实体设置到httpPost对象中
		httpPost.setEntity(formEntity);

		CloseableHttpResponse response = null;
		try {
			// 执行请求
			response = httpclient.execute(httpPost);
			// 判断返回状态是否为200
			if (response.getStatusLine().getStatusCode() == 200) {
				// 解析响应体
				String content = EntityUtils.toString(response.getEntity(), "UTF-8");
				System.out.println(content);
			}
		} finally {
			if (response != null) {
				response.close();
			}
			// 关闭浏览器
			httpclient.close();
		}
	}

(3)有参的POST请求(JSON格式)

	@Test
	public void postByJson() throws JsonProcessingException {
		ObjectMapper mapper = new ObjectMapper();
		TbUser tbUser = new TbUser();
		tbUser.setUserName("阿拉蕾");
		tbUser.setUserAge(36);
		tbUser.setContent("阿拉蕾");

		String strJson = mapper.writeValueAsString(tbUser);

		CloseableHttpClient httpclient = HttpClientBuilder.create().build();
		HttpPost post = new HttpPost("http://localhost:8080/postByJson");
		try {
			StringEntity s = new StringEntity(strJson, Charset.forName("UTF-8"));

			//发送json数据需要设置contentType
			s.setContentType("application/json");
			post.setEntity(s);
			HttpResponse res = httpclient.execute(post);
			if(res.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
				// 返回json格式:
				String result = EntityUtils.toString(res.getEntity(), "UTF-8");
				System.out.println(result);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

2、RestTemplate

1)、简介

RestTemplate 是从 Spring3.0 开始支持的一个 HTTP 请求工具,它提供了常见的REST请求方案的模版,例如 GET 请求、POST 请求、PUT 请求、DELETE 请求以及一些通用的请求执行方法 exchange 以及 execute。RestTemplate 继承自 InterceptingHttpAccessor 并且实现了 RestOperations 接口,其中 RestOperations 接口定义了基本的 RESTful 操作,这些操作在 RestTemplate 中都得到了实现。接下来我们就来看看这些操作方法的使用。

2)、GET请求

(1)无参的GET请求

    @Test
    public void restGet() {
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://localhost:8080/json", String.class);
        String body = responseEntity.getBody();
        HttpStatus statusCode = responseEntity.getStatusCode();
        int statusCodeValue = responseEntity.getStatusCodeValue();
        HttpHeaders headers = responseEntity.getHeaders();
        StringBuffer result = new StringBuffer();
        result.append("responseEntity.getBody():").append(body).append("<hr>")
                .append("responseEntity.getStatusCode():").append(statusCode).append("<hr>")
                .append("responseEntity.getStatusCodeValue():").append(statusCodeValue).append("<hr>")
                .append("responseEntity.getHeaders():").append(headers).append("<hr>");

        System.out.println(result);
    }

(2)有参的GET请求

    @Test
    public void restGet1() throws UnsupportedEncodingException {
        RestTemplate restTemplate = new RestTemplate();

        // 方法一:
        ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://localhost:8080/jsonParam?userName={1}&userAge={2}", String.class, "张三", 25);
        String body = responseEntity.getBody();
        System.out.println(body);

        // 方法二:
        Map<String, String> map = new HashMap<>();
        map.put("userName", "李四");
        map.put("userAge", "22");
        responseEntity = restTemplate.getForEntity("http://localhost:8080/jsonParam?userName={userName}&userAge={userAge}", String.class, map);
        body = responseEntity.getBody();
        System.out.println(body);

        // 方法三:
        String url = "http://localhost:8080/jsonParam?userName="+ URLEncoder.encode("王二","UTF-8") + "&userAge=13";
        URI uri = URI.create(url);
        responseEntity = restTemplate.getForEntity(uri, String.class);
        body = responseEntity.getBody();
        System.out.println(body);

        // 方法四:
        String url1 = "http://localhost:8080/jsonParam?userName="+ URLEncoder.encode("周大","UTF-8") + "&userAge=13";
        URI uri1 = URI.create(url1);
        String s = restTemplate.getForObject(uri1, String.class);
        System.out.println(s);
    }

图片alt

3)、POST请求

(1)无参的POST请求

    @Test
    public void restPost1() {
        RestTemplate restTemplate = new RestTemplate();

        String url = "http://localhost:8080/json";
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, null, String.class);
        String body = responseEntity.getBody();
        System.out.println(body);
    }

(2)有参的POST请求(FORM格式)

    @Test
    public void restPostByForm() {
        RestTemplate restTemplate = new RestTemplate();

        String url = "http://localhost:8080/jsonParam";
        MultiValueMap map = new LinkedMultiValueMap();
        map.add("userName", "猪八戒");
        map.add("userAge", 250);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, map, String.class);
        String body = responseEntity.getBody();
        System.out.println(body);
    }

(3)有参的POST请求(JSON格式)

    @Test
    public void restPostByJson() {
        RestTemplate restTemplate = new RestTemplate();

        String url = "http://localhost:8080/postByJson";

        TbUser tbUser = new TbUser();
        tbUser.setUserName("阿拉蕾");
        tbUser.setUserAge(36);
        tbUser.setContent("阿拉蕾");

        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, tbUser, String.class);
        String body = responseEntity.getBody();
        System.out.println(body);
    }