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

Spring ResponseEntityExceptionHandler中获取HttpServletRequest的实现

在Spring Boot自定义异常处理器中获取HttpServletRequest的方法

嘿,我来帮你搞定这个问题!在你继承ResponseEntityExceptionHandler的自定义异常处理器里,获取HttpServletRequest有两种实用方式,对应不同的场景:

1. 重写父类方法时,从WebRequest转换获取

像你代码里的handleHttpMessageNotReadable、handleMethodArgumentNotValid这类重写的方法,参数里只有WebRequest,这时候可以通过RequestContextHolder来拿到HttpServletRequest:

@Override
protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
    // 从请求上下文获取HttpServletRequest
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest httpServletRequest = attributes.getRequest();
    
    // 现在就能用它做你需要的操作了,比如获取请求IP、URI
    String remoteIp = httpServletRequest.getRemoteAddr();
    String requestUri = httpServletRequest.getRequestURI();
    
    // 你的原有业务逻辑...
    if (ExceptionUtils.getRootCauseMessage(ex).contains("Duplicate entry")) {
        // 这里可以把httpServletRequest传给你的buildIntegrityError方法
        return response(HttpStatus.CONFLICT, new HttpHeaders(), buildIntegrityError(ex, httpServletRequest, HttpStatus.CONFLICT, LocaleContextHolder.getLocale()));
    } else {
        return response(HttpStatus.BAD_REQUEST, new HttpHeaders(), buildGenericError(ex, request, HttpStatus.BAD_REQUEST, LocaleContextHolder.getLocale()));
    }
}

注:在Spring MVC的请求上下文里,RequestContextHolder一定会持有ServletRequestAttributes,不用担心空指针问题。

2. 自定义@ExceptionHandler方法时,直接注入参数

就像你代码里的handleConflictException和handleFileUpload方法那样,直接把HttpServletRequest作为方法参数,Spring会自动帮你注入进来,用起来超方便:

@ExceptionHandler(MaxUploadSizeExceededException.class)
public ResponseEntity<?> handleFileUpload(MaxUploadSizeExceededException ex, HttpServletRequest request, Locale locale) throws Exception {
    // 直接使用request,比如你已经在日志里用到的获取远程IP
    log.error(String.format("从%s收到过大文件。错误信息:%s", AppUtils.getRemoteIp(request), ExceptionUtils.getRootCauseMessage(ex)));
    
    // 你的原有业务逻辑...
    return response(HttpStatus.BAD_REQUEST, new HttpHeaders(), buildIntegrityError(ex, request, HttpStatus.BAD_REQUEST, LocaleContextHolder.getLocale()));
}

额外小技巧:工具类中全局获取

如果你的工具方法(比如buildIntegrityError)也需要用到HttpServletRequest,可以写个静态工具方法:

private HttpServletRequest getCurrentRequest() {
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    return attributes != null ? attributes.getRequest() : null;
}

这样在任何需要的地方调用这个方法就能拿到当前请求对象了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:41:24