gpt4 book ai didi

spring - 使用 @ControllerAdvice 制作简单的 servlet 过滤器

转载 作者:IT老高 更新时间:2023-10-28 13:50:04 26 4
gpt4 key购买 nike

我有一个简单的过滤器,只是为了检查请求是否包含带有静态 key 的特殊 header - 没有用户身份验证 - 只是为了保护端点。这个想法是如果键不匹配则抛出 AccessForbiddenException,然后将其映射到带有 @ControllerAdvice 注释的类的响应。但是我不能让它工作。我的 @ExceptionHandler 没有被调用。

ClientKeyFilter

import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Controller

import javax.servlet.*
import javax.servlet.http.HttpServletRequest

@Controller //I know that @Component might be here
public class ClientKeyFilter implements Filter {

@Value('${CLIENT_KEY}')
String clientKey

public void init(FilterConfig filterConfig) {}

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
req = (HttpServletRequest) req
def reqClientKey = req.getHeader('Client-Key')
if (!clientKey.equals(reqClientKey)) {
throw new AccessForbiddenException('Invalid API key')
}
chain.doFilter(req, res)
}

public void destroy() {}
}

AccessForbiddenException

public class AccessForbiddenException extends RuntimeException {
AccessForbiddenException(String message) {
super(message)
}
}

异常 Controller

@ControllerAdvice
class ExceptionController {
static final Logger logger = LoggerFactory.getLogger(ExceptionController)

@ExceptionHandler(AccessForbiddenException)
public ResponseEntity handleException(HttpServletRequest request, AccessForbiddenException e) {
logger.error('Caught exception.', e)
return new ResponseEntity<>(e.getMessage(), I_AM_A_TEAPOT)
}
}

我哪里错了?简单的 servlet 过滤器可以和 spring-boot 的异常映射一起工作吗?

最佳答案

正如 java servlet 规范所指定的,Filter 总是在调用 Servlet 之前执行。现在 @ControllerAdvice 只对在 DispatcherServlet 内执行的 Controller 有用。因此,使用 Filter 并期望 @ControllerAdvice 或在本例中为 @ExceptionHandler 被调用是不会发生的。

您需要在过滤器中放入相同的逻辑(用于编写 JSON 响应),或者使用 HandlerInterceptor 代替过滤器哪个做这个检查。最简单的方法是扩展 HandlerInterceptorAdapter并且只需重写并实现 preHandle 方法并将过滤器中的逻辑放入该方法中。

public class ClientKeyInterceptor extends HandlerInterceptorAdapter {

@Value('${CLIENT_KEY}')
String clientKey

@Override
public boolean preHandle(ServletRequest req, ServletResponse res, Object handler) {
String reqClientKey = req.getHeader('Client-Key')
if (!clientKey.equals(reqClientKey)) {
throw new AccessForbiddenException('Invalid API key')
}
return true;
}

}

关于spring - 使用 @ControllerAdvice 制作简单的 servlet 过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30335157/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com