我有一个有趣的问题(至少从我目前的角度来看这是一个问题)。
我有一个暴露接口的 RESTful Web 服务。在我们的环境中,我们使用注解来装饰请求处理程序,例如 -
@RequiredTokenType("Binary")
public String getRecordInfo(HttpServletRequest request) {
String recordInfo = null;
final String methodName = "getRecordInfo()";
_log.debug("{}: received request", methodName);
// validate the request information
ValidationUtils.validateAcceptHeader(request, MimeConstants.getContentType());
. . .
. . .
return recordInfo;
}
我们需要有一个 CXF 拦截器/方面(spring AOP)在处理程序之前执行(如上),并检查 HttpServletRequest 的令牌类型。如果令牌类型(或装饰处理程序的任何其他属性)不是注释中指定的类型,则停止执行并返回 HTTP 状态 400(错误请求)。像上面这样的请求处理程序大约有 20 个。
我在这里面临的问题是,在编写了基于方面的 spring AOP 之后,(如下所示)我能够在 getRecordInfo() 执行之前捕获请求,但是当我尝试返回 400(或)抛出异常时,HTTP客户仍然看到 200 -
public void validateRequest(ProceedingJoinPoint joinPoint,
HttpServletRequest httpRequest,
RequiredTokenType tokenType) throws Throwable {
final String methodName = "validateRequest()";
_logger.info("{}: Entered, Thread Id: {}", methodName, "" + Thread.currentThread().getId());
// Extract the *REQUIRED* headers from the request ...
final String tokenData = httpRequest.getHeader(HEADER_TOKEN_DATA);
if (tokenData == null || tokenData.trim().length() < MIN_POSSIBLE_TOKEN_SIZE) {
// Error condition .... return (400 Bad Request)
_logger.info("{}: Invalid token. The HTTP request is rejected in lack of a valid token.");
throw new MissingTokenException(HttpStatus.BAD_REQUEST,
ErrorCode.BAD_REQUEST,
"Token is missing from the request.");
}
ValidityToken extractedTokenFromRequest = ValidityToken.initializeFromBase64(tokenData);
// Get the type of the token this request must include ...
String decoratedTokenType = tokenType.value();
_logger.debug("{}: Token Type Required: ", methodName, decoratedTokenType);
if (! extractedTokenFromRequest.getTypeName().equals(decoratedTokenType)) {
// Error condition .... return (400).
_logger.info("{}: {}",
methodName,
"The token in the request mismatches the type specified in RequiredTokenType handler. 400 Bad Request.");
throw new TokenTypeMismatchException(HttpStatus.BAD_REQUEST,
ErrorCode.BAD_REQUEST,
"Token type doesn't match.");
}
// More validations on extractedTokenFromRequest
. . .
. . .
// Continue with the actual business logic if correct token is included ...
joinPoint.proceed();
}
我检查了日志文件,我可以看到以下日志条目,确认请求处理程序和方面都被调用 -
getRecordInfo(): received request
. . .
. . .
validateRequest(): Entered, Thread Id: 792
. . .
. . .
validateRequest(): Invalid token. The HTTP request is rejected in lack of a valid token.
尽管有消息,客户端仍然看到 200 并且服务器日志显示其他基于 CXF 的拦截器正在执行的证据。
这是定义切入点的 Spring 上下文 XML -
<bean id="vGateKeeper" class="com....core.RequestValidator" />
<aop:config>
<aop:aspect id="methodInvocation" ref="methodInvocationProfiler">
<aop:around method="profileMethodInvocation"
pointcut="execution(* org.springframework.orm.jpa.JpaTransactionManager.commit(..))"/>
<aop:around method="profileMethodInvocation"
pointcut="execution(* org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(..))"/>
</aop:aspect>
<aop:aspect id="gateKeeper" ref="vGateKeeper">
<aop:pointcut expression="execution(* getRecordInfo(..)) and args(httpRequest) and @annotation(modPerms)" id="my"/>
<aop:around pointcut-ref="my" method="validateRequest"/>
</aop:aspect>
</aop:config>
在这种情况下,如何使用 Spring AOP 方面返回 HTTP 400,取消任何其他拦截器的执行?
我也在考虑编写一个 Apache CXF 拦截器来捕获调用并在它到达请求处理程序之前返回 400,但是我不确定,如何使用拦截器我可以知道应该执行哪个请求处理程序以及注释是什么装饰请求处理程序。CXF 拦截器是否提供任何方法来知道最终将执行哪个请求处理程序?
我在看这里,(https://cxf.apache.org/docs/interceptors.html)但还是没有找到。
任何帮助表示赞赏。
问候,
(*Vipul)() ;