使用@ControllerAdvice使简单的servlet过滤器工作
我有一个简单的过滤器,仅用于检查请求是否包含带有静态密钥的特殊标头-无用户身份验证-
只是为了保护端点。这个想法是AccessForbiddenException
如果键不匹配则抛出一个,然后将其映射到带有注释的类的响应@ControllerAdvice
。但是我不能使它工作。我@ExceptionHandler
没有被叫。
import org.springframework.beans.factory.annotation.Valueimport 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() {}
}
public class AccessForbiddenException extends RuntimeException { AccessForbiddenException(String message) {
super(message)
}
}
@ControllerAdviceclass 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
调用a之前执行。现在,a
@ControllerAdvice
仅对在中执行的控制器有用DispatcherServlet
。因此,使用a Filter
并期望a
@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;
}
}
以上是 使用@ControllerAdvice使简单的servlet过滤器工作 的全部内容, 来源链接: utcz.com/qa/409852.html