私には興味深い問題があります (少なくとも、私の現在の観点からは問題です)。
インターフェイスを公開している 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 の要求ハンドラーがあります。
ここで私が直面している問題は、アスペクトに基づいたスプリング 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)() ;