湖南专业做网站公司什么是seo关键词优化
目录
- 前言
- 1. Java8 Demo
- 2. Java8 实战
- 3. Java11 Demo
前言
🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF
1. Java8 Demo
下述主体主要针对Java8的版本,后续会有一个特定的Java11版本
推荐使用 Apache HttpClient 4.x,这是在 Java 8 中使用最广泛、最稳定的 HTTP 客户端工具
Apache HttpClient 是 Apache 出品的 HTTP 客户端库,功能强大,适用于:
-
发起 HTTP 请求(GET、POST、PUT、DELETE 等)
-
携带请求头、请求参数
-
设置超时、重定向等策略
-
读取响应状态码、响应体、响应头等
导入相关的依赖包:
<!-- Apache HttpClient -->
<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.13</version> <!-- 推荐稳定版本 -->
</dependency>
相关的核心类如下:
类名 | 说明 |
---|---|
CloseableHttpClient | 客户端对象,用于发送请求 |
HttpGet / HttpPost | 表示 HTTP 请求(GET/POST) |
HttpResponse | 响应对象 |
HttpEntity | 请求体或响应体封装 |
EntityUtils | 帮助读取响应体为字符串等形式 |
以下Demo主要用于测试使用,便于理解其用法说明:
Get请求:
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;public class ApacheHttpGetDemo {public static void main(String[] args) throws Exception {// 1. 创建 HttpClient 实例CloseableHttpClient client = HttpClients.createDefault();// 2. 创建 HttpGet 请求对象,并设置 URLHttpGet get = new HttpGet("https://jsonplaceholder.typicode.com/posts/1");// 3. 执行请求,获取响应HttpResponse response = client.execute(get);// 4. 获取状态码int statusCode = response.getStatusLine().getStatusCode();System.out.println("状态码: " + statusCode);// 5. 获取响应体内容String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");System.out.println("响应内容: \n" + responseBody);// 6. 关闭客户端连接client.close();}
}
Post请求:
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;public class ApacheHttpPostDemo {public static void main(String[] args) throws Exception {// 1. 创建 HttpClient 实例CloseableHttpClient client = HttpClients.createDefault();// 2. 创建 HttpPost 请求对象HttpPost post = new HttpPost("https://jsonplaceholder.typicode.com/posts");// 3. 构造 JSON 请求体(Java 8 用字符串拼接)String json = "{"+ "\"title\": \"foo\","+ "\"body\": \"bar\","+ "\"userId\": 1"+ "}";// 4. 设置请求头和请求体post.setHeader("Content-Type", "application/json");post.setEntity(new StringEntity(json, "UTF-8"));// 5. 发送 POST 请求HttpResponse response = client.execute(post);// 6. 读取响应状态码和响应体int statusCode = response.getStatusLine().getStatusCode();String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");// 7. 打印结果System.out.println("状态码: " + statusCode);System.out.println("响应内容:\n" + responseBody);// 8. 关闭客户端client.close();}
}
上述常用方法总结
✅ 创建客户端:CloseableHttpClient client = HttpClients.createDefault();
✅ GET 请求:HttpGet get = new HttpGet("http://example.com/api");
✅ POST 请求 + JSON
HttpPost post = new HttpPost("http://example.com/api");
post.setHeader("Content-Type", "application/json");
post.setEntity(new StringEntity(jsonData, "UTF-8"));
✅ 发送请求 + 获取响应
HttpResponse response = client.execute(get或post);
int statusCode = response.getStatusLine().getStatusCode();
String body = EntityUtils.toString(response.getEntity(), "UTF-8");
✅ 设置请求头
post.setHeader("Authorization", "Bearer your-token");
post.setHeader("Accept", "application/json");
2. Java8 实战
对接的API接口是一张照片,之后将识别结果返回,比对是否两者一致!
实战中的Demo如下,实战中的Demo主要以思路讲解的方式:
// 某个接口中有所调用API传输文件,得到AI识别结果:
String result = uploadImageAndRecognize(downloadedFile);// 具体调用的方法参数:
private String uploadImageAndRecognize(File imageFile) throws IOException {String url = "http://xxxx/recognize";// 创建HttpClientCloseableHttpClient httpClient = HttpClients.createDefault();// 创建 POST 请求HttpPost uploadFile = new HttpPost(url);MultipartEntityBuilder builder = MultipartEntityBuilder.create();builder.addBinaryBody("image",new FileInputStream(imageFile),ContentType.APPLICATION_OCTET_STREAM,imageFile.getName());HttpEntity multipart = builder.build();uploadFile.setEntity(multipart);// 执行请求CloseableHttpResponse response = httpClient.execute(uploadFile);HttpEntity responseEntity = response.getEntity();if (responseEntity != null) {String jsonString = EntityUtils.toString(responseEntity);// 解析 JSON,提取结果ObjectMapper objectMapper = new ObjectMapper();JsonNode rootNode = objectMapper.readTree(jsonString);JsonNode resultsNode = rootNode.path("results");if (resultsNode.isArray() && resultsNode.size() > 0) {return resultsNode.get(0).asText(); // 返回第一个结果}}return null; // 如果解析失败或无结果
}
方法结构核心知识点:
-
CloseableHttpClient httpClient = HttpClients.createDefault();
创建一个 HttpClient 客户端实例
用于执行 HTTP 请求,属于同步阻塞操作 -
HttpPost uploadFile = new HttpPost(url);
创建一个 POST 请求对象,URL 是目标服务端 API 接口 -
MultipartEntityBuilder
用于构建带文件上传的 multipart/form-data 请求体
addBinaryBody() 表示添加文件字段,支持设置内容类型和文件名 -
httpClient.execute(uploadFile)
执行请求,阻塞线程直到响应返回
返回的是 CloseableHttpResponse 对象 -
EntityUtils.toString(responseEntity)
将响应实体转为字符串格式(JSON文本)。 -
ObjectMapper 解析 JSON
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(jsonString);
JsonNode resultsNode = rootNode.path("results");
使用 Jackson 库解析 JSON
path() 用于安全地访问节点,避免 null 指针
- 返回识别结果
if (resultsNode.isArray() && resultsNode.size() > 0) {return resultsNode.get(0).asText();
}
后续还可进一步优化:
为什么用 CompletableFuture?
异步处理耗时任务(如 HTTP 请求)时,主线程无需等待
非阻塞性能更好,适合高并发场景
支持链式调用、异常处理、并发组合等高级特性
整体改进如下:
✅ 1. 异步化请求(使用 CompletableFuture)
通过异步处理,你可以避免等待 HTTP 请求的过程,减少主线程阻塞,提升性能。使用 CompletableFuture 可以让你并行处理多个请求。
import java.util.concurrent.CompletableFuture;private CompletableFuture<String> uploadImageAndRecognizeAsync(File imageFile) {return CompletableFuture.supplyAsync(() -> {try {return uploadImageAndRecognize(imageFile);} catch (IOException e) {throw new RuntimeException(e);}});
}
在调用处,可以异步执行,并在适当的时候等待结果
String key = "xxxxx";
Boolean newStatus = redisTemplate.opsForValue().get(key) == null;
if (newStatus) {File downloadedFile = null;try {downloadedFile = downloadFileFromUrl(createReqVO.getImgCntrF());// 异步调用AI校验接口CompletableFuture<String> futureResult = uploadImageAndRecognizeAsync(downloadedFile);// 等待结果并处理String result = futureResult.get(); // 可以加上超时处理System.out.println("识别结果: " + result);// 进一步处理结果...} catch (Exception e) {throw new RuntimeException(e);}
}
✅ 2. 封装 HTTP 请求
为了避免重复代码,你可以把 HTTP 请求的部分封装成一个独立的工具类。这样可以提高代码的可维护性和可重用性。
HttpClientUtils 工具类:
public class HttpClientUtils {/*** 发送POST请求上传图片并获取识别结果* @param url 请求的URL* @param imageFile 需要上传的图片文件* @return 识别结果* @throws IOException*/public static String postFile(String url, File imageFile) throws IOException {try (CloseableHttpClient httpClient = HttpClients.createDefault()) {HttpPost uploadFile = new HttpPost(url);MultipartEntityBuilder builder = MultipartEntityBuilder.create();builder.addBinaryBody("image",new FileInputStream(imageFile),ContentType.APPLICATION_OCTET_STREAM,imageFile.getName());HttpEntity multipart = builder.build();uploadFile.setEntity(multipart);try (CloseableHttpResponse response = httpClient.execute(uploadFile)) {HttpEntity responseEntity = response.getEntity();if (responseEntity != null) {String jsonString = EntityUtils.toString(responseEntity);ObjectMapper objectMapper = new ObjectMapper();JsonNode rootNode = objectMapper.readTree(jsonString);JsonNode resultsNode = rootNode.path("results");if (resultsNode.isArray() && resultsNode.size() > 0) {return resultsNode.get(0).asText(); // 返回第一个识别结果}}}}return null; // 如果没有获取到识别结果}
}
然后,调用时直接使用工具类:
String key = "xxxx";
Boolean newStatus = redisTemplate.opsForValue().get(key) == null;
if (newStatus) {File downloadedFile = null;try {downloadedFile = downloadFileFromUrl(createReqVO.getImgCntrF());// 调用工具类进行图片上传与识别String result = HttpClientUtils.postFile("http://10.197.2.16:5000/api/recognize", downloadedFile);System.out.println("识别结果: " + result);} catch (IOException e) {throw new RuntimeException(e);}
}
✅ 3. 异常处理与重试机制
考虑到网络请求的可能失败,可以加入重试机制。比如在请求失败时可以重试几次,使用 RetryTemplate 或 Spring Retry 可以实现。
下面是一个简单的重试实现:
import org.springframework.retry.support.RetryTemplate;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.backoff.ExponentialBackOffPolicy;public class RetryHttpClientUtils {private static RetryTemplate createRetryTemplate() {RetryTemplate retryTemplate = new RetryTemplate();// 设置重试策略:最多重试3次SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();retryPolicy.setMaxAttempts(3);retryTemplate.setRetryPolicy(retryPolicy);// 设置重试的退避策略:指数退避ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();backOffPolicy.setInitialInterval(1000); // 初始间隔时间:1秒backOffPolicy.setMultiplier(2); // 每次间隔时间倍增retryTemplate.setBackOffPolicy(backOffPolicy);return retryTemplate;}public static String postFileWithRetry(String url, File imageFile) throws IOException {RetryTemplate retryTemplate = createRetryTemplate();return retryTemplate.execute(context -> HttpClientUtils.postFile(url, imageFile));}
}
3. Java11 Demo
后续发现一个野生的Java11版本
Java 11 之后,HttpClient 成为了标准库的一部分(位于 java.net.http 包中)
核心类:
类名 | 说明 |
---|---|
HttpClient | HTTP 客户端,用于发送请求、接收响应 |
HttpRequest | 表示一个 HTTP 请求(如 GET/POST) |
HttpResponse | 表示响应结果,包括状态码、响应体等 |
HttpRequest.BodyPublishers | 用于构造请求体 |
HttpResponse.BodyHandlers | 用于处理响应体 |
基本的逻辑步骤如下:
-
创建 HttpClient 客户端对象
-
构造 HttpRequest 请求对象
-
发送请求并获取 HttpResponse 响应对象
Get请求:
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;public class HttpClientGetDemo {public static void main(String[] args) throws Exception {// 1. 创建 HttpClient 实例HttpClient client = HttpClient.newHttpClient();// 2. 构造 GET 请求(指定 URI)HttpRequest request = HttpRequest.newBuilder().uri(new URI("https://jsonplaceholder.typicode.com/posts/1")).GET() // 默认就是 GET.build();// 3. 发送请求并获取响应HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());// 4. 打印状态码和响应体System.out.println("状态码: " + response.statusCode());System.out.println("响应内容: \n" + response.body());}
}
Post请求:
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpRequest.BodyPublishers;public class HttpClientPostDemo {public static void main(String[] args) throws Exception {// 1. 创建 HttpClient 实例HttpClient client = HttpClient.newHttpClient();// 2. 构造 POST 请求,发送 JSON 数据String json = """{"title": "foo","body": "bar","userId": 1}""";HttpRequest request = HttpRequest.newBuilder().uri(new URI("https://jsonplaceholder.typicode.com/posts")).header("Content-Type", "application/json") // 设置请求头.POST(BodyPublishers.ofString(json)) // 设置请求体.build();// 3. 发送请求并接收响应HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());// 4. 打印状态码和响应内容System.out.println("状态码: " + response.statusCode());System.out.println("响应内容: \n" + response.body());}
}
常用方法分析
HttpClient 创建
HttpClient client = HttpClient.newHttpClient(); // 默认配置
HttpClient client = HttpClient.newBuilder().version(HttpClient.Version.HTTP_2).followRedirects(HttpClient.Redirect.NORMAL).build();
HttpRequest 构建方法
// GET 请求
HttpRequest.newBuilder().uri(new URI("...")).GET().build();// POST 请求
HttpRequest.newBuilder().uri(new URI("...")).POST(BodyPublishers.ofString("请求体")).build();// 设置请求头
.header("Content-Type", "application/json")
HttpResponse 处理方式
HttpResponse.BodyHandlers.ofString(); // 将响应体转为字符串
HttpResponse.BodyHandlers.ofByteArray(); // 转为字节数组
HttpResponse.BodyHandlers.ofFile(Path.of("output.txt")); // 写入文件