原理:使用拦截器拦截所有请求,并把请求中的
IP
信息存在ThreadLocal
中,下次直接从ThreadLocal
中取值。
引入hutool工具:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.18</version>
</dependency>
拦截器代码:
@Order
@Slf4j
@Component
public class CollectorInterceptor implements HandlerInterceptor, WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(this)
.addPathPatterns("/**"); // 拦截所有请求
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 从request中获取IP信息(使用hutool工具类)
RequestHolder.set(ServletUtil.getClientIP(request));
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 销毁对象时要移除上下文对象,避免内存泄漏
RequestHolder.remove();
}
}
封装一个内部的threadLocal
,这样在业务逻辑中,我们可以很轻松的拿到ip
的值。
public class RequestHolder {
private static final ThreadLocal<String> threadLocal = new ThreadLocal<>();
public static void set(String ip) {
threadLocal.set(ip);
}
public static RequestInfo get() {
return threadLocal.get();
}
public static void remove() {
threadLocal.remove();
}
}
controller
中使用:
@GetMapping("/getIp")
@ApiOperation("获取IP地址")
public ApiResult<String> getIp() {
return ApiResult.success(RequestHolder.get());
}