Hutool请求拦截:HTTP请求响应拦截

Hutool请求拦截:HTTP请求响应拦截

【免费下载链接】hutool 🍬A set of tools that keep Java sweet. 【免费下载链接】hutool 项目地址: https://gitcode.com/gh_mirrors/hu/hutool

还在为HTTP请求的全局处理而烦恼?每次都要手动添加相同的header、记录日志、处理异常?Hutool的HTTP拦截器机制让你一键解决这些痛点!本文将深入解析Hutool的HTTP请求响应拦截功能,带你掌握高效、灵活的HTTP请求处理方案。

什么是HTTP拦截器?

HTTP拦截器(Interceptor)是一种设计模式,允许你在HTTP请求发送前和响应接收后插入自定义处理逻辑。Hutool提供了强大的拦截器机制,支持:

  • 请求拦截:在请求发送前修改请求参数、添加header、记录日志等
  • 响应拦截:在响应接收后处理响应数据、记录日志、统一异常处理等
  • 全局拦截:对所有HTTP请求生效的拦截器
  • 局部拦截:对特定请求生效的拦截器

Hutool拦截器核心架构

Hutool的HTTP拦截器系统基于以下几个核心组件:

1. HttpInterceptor接口

@FunctionalInterface
public interface HttpInterceptor<T extends HttpBase<T>> {
    void process(T httpObj);
}

这是一个函数式接口,支持Lambda表达式,非常简洁易用。

2. 拦截器链(Chain)模式

class Chain<T extends HttpBase<T>> implements cn.hutool.core.lang.Chain<HttpInterceptor<T>, Chain<T>> {
    private final List<HttpInterceptor<T>> interceptors = new LinkedList<>();
    // 链式添加、迭代器支持
}

采用责任链模式,支持多个拦截器按顺序执行。

3. 全局拦截器管理器

public enum GlobalInterceptor {
    INSTANCE;
    
    private final HttpInterceptor.Chain<HttpRequest> requestInterceptors = new HttpInterceptor.Chain<>();
    private final HttpInterceptor.Chain<HttpResponse> responseInterceptors = new HttpInterceptor.Chain<>();
    // 全局管理方法
}

单例模式确保全局拦截器的统一管理。

实战:四种拦截器使用场景

场景一:全局请求头自动添加

// 全局添加认证token
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
    request.header("Authorization", "Bearer your-token-here");
});

// 后续所有请求都会自动携带token
HttpResponse response = HttpRequest.get("https://api.example.com/data").execute();

场景二:请求日志记录

// 记录请求信息
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
    System.out.println("请求URL: " + request.getUrl());
    System.out.println("请求方法: " + request.getMethod());
    System.out.println("请求头: " + request.headers());
});

// 记录响应信息  
GlobalInterceptor.INSTANCE.addResponseInterceptor(response -> {
    System.out.println("响应状态: " + response.getStatus());
    System.out.println("响应内容长度: " + response.body().length);
});

场景三:统一异常处理

GlobalInterceptor.INSTANCE.addResponseInterceptor(response -> {
    if (response.getStatus() >= 400) {
        // 统一处理错误响应
        String errorMsg = "请求失败: " + response.getStatus() + " - " + response.body();
        throw new RuntimeException(errorMsg);
    }
});

try {
    HttpResponse response = HttpRequest.get("https://api.example.com/error-endpoint").execute();
} catch (RuntimeException e) {
    System.out.println("统一异常处理: " + e.getMessage());
}

场景四:请求参数预处理

// 对特定请求添加参数
HttpRequest request = HttpRequest.get("https://api.example.com/search")
    .addRequestInterceptor(req -> {
        req.form("timestamp", System.currentTimeMillis());
        req.form("sign", generateSign(req));
    })
    .form("keyword", "hutool");

HttpResponse response = request.execute();

拦截器执行流程

mermaid

高级特性详解

1. 拦截器优先级控制

由于拦截器按添加顺序执行,可以通过控制添加顺序来实现优先级:

// 先执行:基础认证
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
    request.basicAuth("user", "pass");
});

// 后执行:业务特定处理
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
    request.header("X-Request-ID", UUID.randomUUID().toString());
});

2. 条件性拦截

GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
    // 只对特定域名添加header
    if (request.getUrl().contains("api.example.com")) {
        request.header("X-API-Version", "v2");
    }
});

GlobalInterceptor.INSTANCE.addResponseInterceptor(response -> {
    // 只处理JSON响应
    if (response.header("Content-Type").contains("application/json")) {
        JSONObject json = JSONUtil.parseObj(response.body());
        // 处理JSON数据
    }
});

3. 重定向时的拦截器控制

HttpRequest.get("https://example.com/redirect")
    .setInterceptorOnRedirect(true)  // 重定向时也使用拦截器
    .setMaxRedirectCount(3)
    .execute();

4. 性能监控拦截器

GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
    request.attr("startTime", System.currentTimeMillis());
});

GlobalInterceptor.INSTANCE.addResponseInterceptor(response -> {
    Long startTime = (Long) response.getRequest().attr("startTime");
    long duration = System.currentTimeMillis() - startTime;
    System.out.println("请求耗时: " + duration + "ms");
    
    // 记录到监控系统
    monitor.recordRequestDuration(duration, response.getStatus());
});

实战案例:完整的API客户端

public class ApiClient {
    private static final String BASE_URL = "https://api.example.com";
    
    static {
        // 全局初始化
        setupGlobalInterceptors();
    }
    
    private static void setupGlobalInterceptors() {
        // 认证
        GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
            request.basicAuth("api-user", "api-secret");
        });
        
        // 请求ID
        GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
            request.header("X-Request-ID", UUID.randomUUID().toString());
        });
        
        // 性能监控
        GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
            request.attr("startTime", System.currentTimeMillis());
        });
        
        GlobalInterceptor.INSTANCE.addResponseInterceptor(response -> {
            Long startTime = (Long) response.getRequest().attr("startTime");
            long duration = System.currentTimeMillis() - startTime;
            logRequest(response.getRequest(), response, duration);
        });
        
        // 错误处理
        GlobalInterceptor.INSTANCE.addResponseInterceptor(response -> {
            if (response.getStatus() >= 400) {
                handleErrorResponse(response);
            }
        });
    }
    
    public static JSONObject getUserInfo(String userId) {
        return HttpRequest.get(BASE_URL + "/users/" + userId)
            .addResponseInterceptor(response -> {
                // 特定接口的响应处理
                if (response.getStatus() == 404) {
                    return JSONUtil.createObj().put("error", "用户不存在");
                }
            })
            .execute()
            .bodyToJson();
    }
    
    public static JSONObject createUser(Map<String, Object> userData) {
        return HttpRequest.post(BASE_URL + "/users")
            .body(JSONUtil.toJsonStr(userData))
            .addRequestInterceptor(request -> {
                // 特定接口的请求处理
                request.header("X-User-Operation", "create");
            })
            .execute()
            .bodyToJson();
    }
    
    private static void logRequest(HttpRequest request, HttpResponse response, long duration) {
        // 记录到日志系统
    }
    
    private static void handleErrorResponse(HttpResponse response) {
        // 统一错误处理逻辑
    }
}

拦截器最佳实践

1. 保持拦截器轻量

// 好:轻量级操作
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
    request.header("X-Trace-ID", MDC.get("traceId"));
});

// 避免:重量级操作
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
    // 避免在拦截器中执行数据库操作等重量级任务
    // User user = userService.getCurrentUser(); // 不推荐
});

2. 异常处理策略

GlobalInterceptor.INSTANCE.addResponseInterceptor(response -> {
    try {
        // 拦截器逻辑
    } catch (Exception e) {
        // 妥善处理异常,避免影响其他拦截器
        log.error("拦截器处理异常", e);
    }
});

3. 线程安全考虑

// 使用线程安全的操作
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
    // 使用线程安全的类
    request.header("X-Thread-ID", Thread.currentThread().getName());
});

常见问题与解决方案

Q1: 拦截器执行顺序问题

问题:多个拦截器之间存在依赖关系,需要控制执行顺序。

解决方案

// 明确控制添加顺序
GlobalInterceptor.INSTANCE.clear(); // 清空现有拦截器

// 按依赖顺序添加
GlobalInterceptor.INSTANCE.addRequestInterceptor(authInterceptor);
GlobalInterceptor.INSTANCE.addRequestInterceptor(loggingInterceptor);
GlobalInterceptor.INSTANCE.addRequestInterceptor(businessInterceptor);

Q2: 特定请求不需要某些全局拦截器

问题:全局拦截器对某些特殊请求不适用。

解决方案

// 方法1:使用局部拦截器覆盖
HttpRequest.get("https://special.api.com/data")
    .addRequestInterceptor(request -> {
        // 特殊处理,不执行某些全局逻辑
    })
    .execute();

// 方法2:条件判断
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
    if (!request.getUrl().contains("special.api.com")) {
        // 正常执行全局逻辑
    }
});

Q3: 拦截器性能影响

问题:拦截器过多影响请求性能。

解决方案

// 使用条件执行
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
    if (needLogging(request)) { // 条件判断
        // 执行相对耗时的操作
        logRequestDetails(request);
    }
});

总结

Hutool的HTTP拦截器机制提供了强大而灵活的请求响应处理能力。通过本文的学习,你应该掌握:

  1. 核心概念:理解HttpInterceptor接口和拦截器链模式
  2. 四种使用场景:全局配置、日志记录、异常处理、参数预处理
  3. 高级特性:优先级控制、条件拦截、性能监控
  4. 最佳实践:保持轻量、妥善处理异常、线程安全
  5. 问题解决:常见问题的解决方案

拦截器模式极大地提升了HTTP请求处理的模块化和可维护性,让你能够以声明式的方式管理横切关注点(Cross-Cutting Concerns)。无论是简单的API调用还是复杂的企业级应用,Hutool的拦截器都能为你提供强大的支持。

现在就开始使用Hutool拦截器,让你的HTTP请求处理更加优雅和高效!

【免费下载链接】hutool 🍬A set of tools that keep Java sweet. 【免费下载链接】hutool 项目地址: https://gitcode.com/gh_mirrors/hu/hutool

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值