如何将多个HttpClient客户端方法抽象为更少的通用方法?
最优最简HTTP请求逻辑抽象方案
核心思路
把重复的HTTP请求逻辑(请求构建、发送、响应解析、异常处理)抽成泛型化的通用执行方法,再基于它封装CRUD通用模板方法,业务资源类(MessageTemplate、AddressBook等)只需传入资源路径、请求体、响应类型等差异化参数即可,彻底消除重复代码。
具体实现步骤与代码示例
1. 定义底层通用HTTP执行方法
这是所有HTTP请求的核心抽象,处理共性逻辑:
// 以RestTemplate为例,可替换为OkHttp、Apache HttpClient等客户端 private <T> T executeHttp(String resourcePath, HttpMethod method, Object requestBody, Class<T> responseType) { // 拼接完整请求URL String url = baseUrl + resourcePath; // 构建统一请求头(可添加认证、超时等全局配置) HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity<Object> requestEntity = new HttpEntity<>(requestBody, headers); // 发送请求并统一处理异常 try { ResponseEntity<T> response = restTemplate.exchange(url, method, requestEntity, responseType); return response.getBody(); } catch (RestClientException e) { throw new SmsCommsException("请求失败: " + e.getMessage(), e); } }
2. 封装CRUD通用模板方法
基于底层执行方法,封装常用CRUD操作,进一步简化业务调用:
// 查询单个资源 protected <T> T getOne(String resourcePath, Class<T> responseType) { return executeHttp(resourcePath, HttpMethod.GET, null, responseType); } // 查询资源列表(适配泛型列表解析) protected <T> List<T> getList(String resourcePath, Class<T> elementType) { ParameterizedTypeReference<List<T>> typeRef = new ParameterizedTypeReference<>() {}; ResponseEntity<List<T>> response = restTemplate.exchange( baseUrl + resourcePath, HttpMethod.GET, null, typeRef ); return response.getBody(); } // 创建资源 protected <Req, Res> Res create(String resourcePath, Req requestBody, Class<Res> responseType) { return executeHttp(resourcePath, HttpMethod.POST, requestBody, responseType); } // 更新资源 protected <Req, Res> Res update(String resourcePath, Req requestBody, Class<Res> responseType) { return executeHttp(resourcePath, HttpMethod.PUT, requestBody, responseType); } // 删除资源 protected void delete(String resourcePath) { executeHttp(resourcePath, HttpMethod.DELETE, null, Void.class); }
3. 重构业务资源方法
原来的MessageTemplate、AddressBook相关CRUD方法,现在只需调用通用方法,代码量骤减:
// MessageTemplate业务方法 public MessageTemplate getMessageTemplateById(Long id) { return getOne("/message-templates/" + id, MessageTemplate.class); } public List<MessageTemplate> listMessageTemplates() { return getList("/message-templates", MessageTemplate.class); } public MessageTemplate createMessageTemplate(MessageTemplateCreateReq req) { return create("/message-templates", req, MessageTemplate.class); } // AddressBook业务方法 public AddressBook getAddressBookById(Long id) { return getOne("/address-books/" + id, AddressBook.class); } public void deleteAddressBook(Long id) { delete("/address-books/" + id); }
额外优化建议
- 参数校验:在通用方法入口添加资源路径、响应类型等非空校验,避免无效请求
- 自定义请求头:允许业务方法传入自定义请求头,覆盖全局配置
- 分页支持:封装通用分页查询方法,自动拼接page、size等URL参数
- 异步请求:新增
executeHttpAsync方法,返回CompletableFuture适配异步场景
内容的提问来源于stack exchange,提问作者NomadsThings
相关产品推荐
相关产品推荐

