You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用HttpClient GET携带RequestParam并解析ResponseBody

Apache HttpClient 实现GET请求的正确写法

原有代码问题

  • 未拼接caseNumbers请求参数,直接使用基础路径创建请求
  • 创建客户端和请求对象后未实际执行请求逻辑,提前关闭了HttpClient实例
  • 无响应处理、结果反序列化逻辑
  • 资源释放无兜底逻辑,容易出现连接泄漏
  • 配置项存在拼写错误:${servce.urlBasePath}应为${service.urlBasePath}

完整Service层实现代码

以下代码完全兼容原有接口定义,无需修改Controller、Service接口的方法签名:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

@Service
public class ReadCaseByCaseNumberServiceImpl implements ReadCaseByCaseNumberService {

    @Value("${service.urlBasePath}")
    private String urlBasePath;

    @Value("${service.getCaseByCaseNumberPath}")
    private String getCaseByCaseNumberPath;

    private final ObjectMapper objectMapper;

    // 构造注入Spring自带的JSON解析工具,无需额外引入依赖
    public ReadCaseByCaseNumberServiceImpl(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public ReadCaseByCaseNumberResponse getReadCaseByCaseNumberResponse(String caseNumbers) throws IOException {
        // 1. 构建带参数的请求URI,自动处理URL编码,避免特殊字符异常
        URI requestUri;
        try {
            requestUri = new URIBuilder(urlBasePath + getCaseByCaseNumberPath)
                    .addParameter("caseNumbers", caseNumbers)
                    .build();
        } catch (URISyntaxException e) {
            throw new IOException("请求地址构建失败", e);
        }

        // 2. 创建GET请求、设置请求头
        HttpGet httpGet = new HttpGet(requestUri);
        httpGet.setHeader("Key", "替换为实际的Key值");
        httpGet.setHeader("Authorization", "Bearer 替换为实际的鉴权token");
        httpGet.setHeader("Accept", "application/json");

        // 3. 自动释放资源:try-with-resources语法会在请求结束后自动关闭客户端和响应,无需手动调用close()
        try (CloseableHttpClient httpClient = HttpClients.createDefault();
             CloseableHttpResponse response = httpClient.execute(httpGet)) {

            // 4. 校验响应状态,非2xx状态直接抛出异常携带错误信息
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode < 200 || statusCode >= 300) {
                String errorContent = EntityUtils.toString(response.getEntity(), "UTF-8");
                throw new IOException("HTTP请求失败,状态码:" + statusCode + ",错误信息:" + errorContent);
            }

            // 5. 读取响应内容,反序列化为目标对象返回
            String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
            return objectMapper.readValue(responseBody, ReadCaseByCaseNumberResponse.class);
        }
    }
}

关键实现说明

  • 禁止手动拼接URL参数,使用URIBuilder可以自动处理参数的URL编码,避免中文、特殊字符导致的请求异常
  • 不要手动调用close()方法释放连接,使用try-with-resources语法可以100%避免连接泄漏问题
  • 必须先校验HTTP响应状态码再解析响应体,避免请求失败时把错误信息当JSON解析抛出不明确的异常
  • 编码固定指定为UTF-8,避免不同环境默认编码不一致导致的响应乱码问题

生产环境优化建议

  • 不要每次请求都新建HttpClient实例,建议在配置类中统一构建带连接池、超时时间、重试策略的CloseableHttpClient Bean,全局注入使用,性能可提升数倍
  • Spring MVC注解(@GetMapping、@RequestParam)建议写在Controller实现类方法上,不要写在接口上,避免注解扫描、AOP代理时出现识别异常
  • 敏感请求头(鉴权token、API Key)不要硬编码在代码中,建议统一放到配置文件或配置中心读取

内容的提问来源于stack exchange,提问作者jashoa leninski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 03:06:22