2016-03-01 5 views
1

Мне нужен Interceptor в Jersey 2.x, который дает ссылки на запрос, ответ и метод, который соответствует пути к веб-службе.Есть ли перехватчик на Джерси, подобный тому, который использовался в HandlerInterceptor весны?

Нечто похожее на HandlerInterceptor of Spring.

Требование:

  1. Потребность аннотаций используемых по классу - Выполните следующие проверки, только если соответствующий метод, который должен быть вызван джерси НЕ Аннотированная с аннотациями.
  2. Запрос - Получить/установить атрибуты и получить объект сеанса для проверки пользователя.
  3. Ответ - перенаправить вызов в случае, если какая-либо проверка не удалась даже до вызова соответствующих меток.

Spring эквивалентный код:

public class WebServiceInterceptor implements HandlerInterceptor { 
    @Override 
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 

     try { 
      SkipWebServiceIntercept skipWebService = handler.getClass().getAnnotation(SkipWebServiceIntercept.class); 

      if (skipWebService != null) { 
       return Boolean.TRUE; 
      } 

      ... 

      if(securityFails) 
      { 
       if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) { 
        response.setCharacterEncoding("utf-8"); 
        response.setContentType("application/json"); 
        PrintWriter out = response.getWriter(); 
        String json; 
        ... 
        out.println(json); 
        return Boolean.FALSE; 
       } 
       else { 
        response.sendRedirect(redirectUrl); 
       } 
      } 
      else 
      { 
       return Boolean.TRUE; 
      } 
     }catch (Exception e) { 
      log.error("Exception in preHandle, redirecting to Login page", e); 
      return LoginUtil.redirectToLogin(request, response); 
     } 
    } 
} 

я нашел упоминание о

  1. ReaderInterceptor - Это обеспечивает только Аннотации класса. Нет доступа к запросу/ответу.
  2. ContainerRequestFilter - Предоставляет объект запроса, но отсутствует Аннотации/Ответ.
  3. ContainerResponseFilter - Дает запрос & Ответ. Но после вызова веб-сервиса/метода.

Есть ли какой-либо другой способ, который может быть достигнут без использования фильтров. потому что мне нужно, чтобы эта обработка выполнялась ТОЛЬКО, если присутствует соответствующий веб-сервис. Фильтр с/* с другой стороны всегда будет выполнять эти проверки, даже если ресурс не найден.

Edit: Благодаря @peeskillet answer Это, как я реализовал его.

@Provider 
public class ResourceInterceptor implements DynamicFeature { 

    @Override 
    public void configure(ResourceInfo resourceInfo, FeatureContext context) { 

     System.out.println("Resource Interceptor called"); 

     if (resourceInfo.getResourceClass() != null 
       && resourceInfo.getResourceClass().getAnnotation(SkipWebServiceIntercept.class) != null) 
      return; 

     context.register(LoginFilter.class); 
    } 

} 


@Slf4j 
public class LoginFilter implements ContainerRequestFilter { 

    @Context 
    private HttpServletRequest  request; 

    @Context 
    private ServletContext   servletContext; 

    @Override 
    public void filter(ContainerRequestContext requestContext) throws IOException { 
     try { 


WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(servletContext); 

CookieAuthenticator cookieAuthenticator = springContext.getBean(CookieAuthenticator.class); 

HttpSession session = request.getSession(true); 

... 

// Отправка JSON/объект назад в ответ

... 
String json = gson.toJson(resposeJson); 

Response response = new ResponseBuilderImpl().encoding(StandardCharsets.UTF_8.name()) 
         .type(MediaType.APPLICATION_JSON).entity(json).build(); 
requestContext.abortWith(response); 
... 

// или отправка URL назад

... 
URI uri = new URI(baseUrl + redirectUrl + "?refback=" + url); 
requestContext.abortWith(Response.temporaryRedirect(uri).build()); 
... 

Оба подхода работали отлично, похожие на HandlerInterce ptor of Spring.

ответ

1

Есть ли какой-либо другой способ, который может быть достигнут без использования фильтров. потому что мне нужно, чтобы эта обработка выполнялась ТОЛЬКО, если присутствует соответствующий веб-сервис.Фильтр с/* с другой стороны всегда будет выполнять эти проверки, даже если ресурс не найден.

Существуют различные способы регистрации фильтра.

  1. Просто зарегистрировать это нормально, где результат фильтра всегда вызывался. (чего вы не хотите).

  2. Зарегистрировано аннотацией, хотя name binding. Таким образом, через фильтр будет проходить только ресурс, аннотированный. (Это вид что вы хотите, только проблема в том, вы должны аннотировать каждый класс)

    @Target({TYPE, METHOD}) 
    @Retention(RetentionPolicy.RUNTIME); 
    class @interface Filtered {} 
    
    @Path("..") 
    @Filtered 
    public class YourResource {} 
    
    @Filtered 
    @Provider 
    public class YourFilter implements ContainerRequestFilter {} 
    
  3. Use a DynamicFeature связать ресурс программно, а не декларативно. DynamicFeture будет вызываться для каждого вашего ресурса методов, поэтому вы можете просто зарегистрировать фильтр для каждый звонок. Это имеет такое же влияние, как и аннотирование каждого класса ресурсов (как упоминалось выше) с привязкой имени (это, вероятно, то, что вы хотите).

    @Provider 
    public class MyFeature implements DynamicFeature { 
        @Override 
        public void configure(ResourceInfo ri, FeatureContext ctx) { 
         ctx.register(YourFilter.class); 
        } 
    } 
    

Смотрите также:

+0

Проблема с использованием 'ContainerRequestFilter', что я не буду иметь объект ответа со мной. Я могу получить доступ к ResourceInfo для проверки аннотаций, но если проверка не удалась, мне придется перенаправить из самого фильтра, не вызывая ресурс. Использование ** Сервлет-фильтр ** Для этого я могу использовать response.sendRedirect(). Как использовать ContainerRequestFilter для этого? Я изучил все API ContainerRequestContext, и я не смог найти ответ. Так есть способ перенаправления на другой URL-адрес из ContainerRequestFilter? –

+0

Вы можете использовать 'requestContext.abortWith (Response)' ... ('Response.seeOther (...)' для перенаправления) –

+0

Или вы можете выбросить исключение и обработать перенаправление в [ExceptionMapper] (https: // jersey.java.net/documentation/latest/representations.html#d0e6665) –

 Смежные вопросы

  • Нет связанных вопросов^_^