2016-08-18 2 views
1

У меня есть класс, реализующий конечную точку JAX-RS, согласно ниже:Java JAX-RS реагируют на любой конечной точке вызова

@Produces({MediaType.APPLICATION_JSON}) 
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_FORM_URLENCODED}) 
@Path("/site/") 
public class ApiSiteResource extends AbstractContentResource { 
... 
    @GET 
    @Path("/article/") 
    public Map<String, Object> getArticle (@Context HttpServletRequest request, @Context HttpServletResponse reponse, @BeanParam ApiParams params) { 
//do stuff 
} 

    @GET 
    @Path("/category/") 
    public Map<String, Object> getCategory (@Context HttpServletRequest request, @Context HttpServletResponse reponse, @BeanParam ApiParams params) { 
//do stuff 
} 

Что мне нужно, чтобы выполнить общую обработку (например, захват аналитики данных) когда вызывается какой-либо из концов этого класса REST, например, для/site/article/и/site/category /. Я в идеале ищу решение, которое будет вызываться в конце выполнения метода, и в идеале с минимальным возможным изменением кода существующих методов, поэтому добавление другого вызова метода в конце метода не является лучшим вариантом, поскольку приводит к слишком большому сцеплению кода. В идеале, я бы хотел, чтобы обработка была запущена из внешнего класса.

Есть ли способ, как это можно сделать?

+0

попробуйте удалить переднюю косую черту после каждого маршрута. Как в '/ site,/article,/category' –

+0

Спасибо Янг, это хорошее предложение - но боюсь, что это не поможет проблеме, которую я пытаюсь решить? –

+0

Хорошо, если я получу вас, вы пытаетесь вызвать метод из другого класса? –

ответ

1

Я использую метод класса Resource, который аннотируется с помощью аннотации @Context и имеет параметр, который вводится из контекстной области.

/** 
    * This method is called by JAX-RS for each request before 
    * the identified resource method is invoked, since it is 
    * annotated with the Context Annotation and carries a 
    * context-scope parameter which is injected. 
    */ 
    @Context 
    public void setServletContext(ServletContext servletContext) { 
    ... 
    } 

(Если вы удалите параметр ServletContext, автоматический вызов на каждом вызове ресурсов исчезает. - по крайней мере, в Джерси) Кроме того, вы можете поместить этот метод в базовом классе, скажем DefaultResourceImpl, которые ваши классы ресурсов может расширяться, поэтому у вас есть это для всех классов ресурсов.

+0

Это именно то, что я искал, спасибо миллион! Это может не совсем соответствовать моему приложению, и в конце концов мне придется отказаться от всей идеи, но хорошо знать, что она там, когда мне это нужно! Большое спасибо –

1

Вы можете использовать JAX-RS Filters and Interceptors

Например, существуют запроса фильтров и фильтров ответа. Вы можете сделать некоторые вещи там:

import java.io.IOException; 
import javax.ws.rs.container.ContainerRequestContext; 
import javax.ws.rs.container.ContainerResponseContext; 
import javax.ws.rs.container.ContainerResponseFilter; 
import javax.ws.rs.core.Response; 

public class PoweredByResponseFilter implements ContainerResponseFilter { 

    @Override 
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) 
     throws IOException { 

      responseContext.getHeaders().add("X-Powered-By", "Jersey :-)"); 
    } 
} 
+0

Вот что я наткнулся на позже, спасибо за хороший пример. Есть ли фильтр, который выполняется после вызова метода JAX-RS (или как сделать триггер фильтра после вызова метода)? –

+1

Непонятно, почему вы хотите сделать это после вызова метода?Один запрос - это вызов одного метода, поэтому вместо того, чтобы что-то делать после выхода из вызова метода, почему бы не использовать фильтр ответа (он будет запускаться каждый раз до того, как ответ попадет в выходной поток). Но если вы действительно хотите, чтобы что-то произошло по определенным вызовам метода, вы можете использовать AOP (например, Spring AOP). – ACV

+0

Ну, метод, который обрабатывает конечную точку REST, извлекает необходимые объекты из БД, поэтому мне нужно сначала собрать их, а затем запустить механизм для выполнения этой дополнительной работы. Итак, мне нужен механизм, который должен быть запущен в конце вызова метода. Спасибо! –

0

Благодарим всех вас за полезные ответы и комментарии.

Собственно, захват аналитики был всего лишь половиной истории. На самом деле мне также необходимо добавить заголовки ответов.

Итак, я в конечном итоге реализации фильтра, как показано ниже:

public class ApiResourceHeadersFilter extends OncePerRequestFilter { 

    public ApiResourceHeadersFilter() { 
    } 

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { 
     response.setHeader("Access-Control-Allow-Headers", "accept"); 
     response.setHeader("Access-Control-Allow-Methods", "GET OPTIONS"); 

     filterChain.doFilter(request, response); 
    } 
} 

Plus добавил отображение в web.xml:

<filter> 
    <filter-name>ApiResourceHeadersFilter</filter-name> 
    <filter-class>com.workangel.eap.filters.ApiResourceHeadersFilter</filter-class> 
    </filter> 

    <filter-mapping> 
    <filter-name>ApiResourceHeadersFilter</filter-name> 
    <url-pattern>/api/site/*</url-pattern> 
    </filter-mapping> 

работает как шарм; нет беспорядочных зависимостей или модификаций кода. Я уверен, что я могу расширить его, если мне нужно собрать аналитические данные.