2016-09-10 3 views
0

다음은 나의 사용 사례입니다.저지 : 저지 필터()의 반환 유형을 재정의 할 수 있습니까?

등록한 저지 엔드 포인트에 대한 모든 수신 요청을 가로 챌 저지 필터 public void filter(ContainerRequestContext requestContext){ //do stuff }을 구현했습니다. 내가 들어오는 요청 헤더의 할 몇 가지 검증을 바탕으로, 나는 다음을 통해 요청을 거부 할 수 있었다 :

Response response = Response.status(status).entity(errorMsg).build(); 
requestContext.abortWith(response); 

이 내가 그것을하고있다 그리고 그것은 나를 위해 일했다 방법이다. 그러나 이제는 요청 된 실제 엔드 포인트 자체 내에서 requestContext의 특정 정보에 액세스해야합니다. 내가 할 경우

@Path("/path") 
@GET 
public ReturnType endpoint(@Context ContainerRequestContext requestContext, 
          @CookieParam("cookieId") String cookieValue, 
          @HeaderParam("headerId") String headerValue, etc..){ 
    //do stuff 
} 

문제가되는 위는 엔드 포인트에서 요청 정보에 액세스하는 것은, 내가 더 이상 필터의 요청을 취소 할 수 없습니다 필터 유효성 검사가 실패^경우 :이과 같이 할 수있어 나는 다음과 같은 오류가 있기 때문에 : 당신이 ContainerRequestContext 내에서 액세스 할 수 있습니다 저지 엔드 포인트에 매개 변수의 종류를 정의하는 경우

java.lang.IllegalStateException: The request cannot be aborted as it is 
already in the response processing phase. 

보인다, 당신이 필터 내 필터 체인을 중단하는 것을 허용하지 않습니다.

필터 확인에 실패하면 필터 내에서 요청을 중단하려고 시도하는 대신 맞춤 헤더를 추가 할 수 있습니다 (아직 시도하지 않았지만 정상적으로 작동한다고 가정). 요청에. 그런 다음 엔드 포인트 자체에서 해당 헤더가 설정되어 있는지 점검 할 수 있습니다. 설정되어 있으면 필터 유효성 검사에 실패했음을 알게되고 Response 개체를 만들어 반환 할 수 있습니다. 설정되어 있지 않으면 필터 유효성 검사가 성공한 것으로 알고 요청을 처리 할 수 ​​있습니다.

그러나 필터가있는 모든 단일 저널 끝점에서이 검사를 수동으로 수행하지 않으려면 필터에서 요청을 중지하고 바로 응답을 중단하거나 바로 중단하는 것이 좋습니다. 나는 이것이 처음부터 필터의 모든 부분이라고 생각했습니다. 그러나 Jersey 필터 메서드의 반환 형식은 void이며이를 무시할 수는 없습니다.

누구나 내 딜레마에 대한 해결책이 있습니까?

+0

[this] (http : // stackoverflow.com/a/27666797/2587435) 전체 요청 컨텍스트를 가져 오는 대신 –

+0

감사합니다. 그러나 내가 잘못한 것을 알아 냈습니다. 답변을 쓸 것입니다. – bscott

답변

0

문제의 근원을 파악했습니다. 위의 코드 예제에서 볼 수 있듯이 심지어 요청 유효성 검사에 도착하기 전에

class ResponseFilter implements ContainerResponseFilter{ 
    public void filter(ContainerRequestContext requestContext, 
         ContainerResponseContext responseContext){ 
     MultivaluedMap<String, Object> headers = responseContext.getHeaders(); 
     headers.add("Access-Control-Allow-Origin", "http://localhost:9000"); 
     headers.add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT"); 
     headers.add("Access-Control-Allow-Headers", "Content-Type"); 
     headers.add("Access-Control-Allow-Credentials", "true"); 
     if(requestValidationFailed){ 
      Response response = Response.status(status).entity(error).build(); 
      requestContext.abortWith(response); 
     } 
    } 
} 

, 나는 이미 응답 헤더를 정의하고 있습니다 : 내 필터는 다음처럼 보였다 응답 필터했다. 이렇게함으로써 Jersey는 내가 지금 '응답 처리 단계'에 있다고 가정합니다. 이미 응답 헤더를 설정하고있을 때 요청을 중단시키지 않을 것입니다.

이 문제를 해결할 수있는 다른 방법이 있지만 내 필터를 두 개의 필터 (두 개의 개별 클래스)로 나누어서 해결했습니다.

class RequestFilter implements ContainerRequestFilter{ 
    public void filter(ContainerRequestContext requestContext){ 
     if(requestValidationFailed){ 
      Response response = Response.status(status).entity(error).build(); 
      requestContext.abortWith(response); 
     } 
} 

class ResponseFilter implements ContainerResponseFilter{ 
    public void filter(ContainerRequestContext requestContext, 
         ContainerResponseContext responseContext){ 
     MultivaluedMap<String, Object> headers = responseContext.getHeaders(); 
     headers.add("Access-Control-Allow-Origin", "http://localhost:9000"); 
     headers.add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT"); 
     headers.add("Access-Control-Allow-Headers", "Content-Type"); 
     headers.add("Access-Control-Allow-Credentials", "true"); 
    } 
} 

나는 지금 java.io.IllegalStateException을받지 않고 내 자원 클래스의 기능에 @Context, @CookieParam, @HeaderParam 등의 매개 변수를 전달할 수 있습니다. requestValidationFailed 검사가 true를 반환하고 리소스 함수가 ​​호출되지 않으면 필터 체인도 성공적으로 중단됩니다.