Java JAX-RS对任何端点调用做出反应

时间:2016-08-18 10:07:13

标签: java jax-rs

我有一个实现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类的任何endponts时执行常见处理(例如,捕获分析数据),例如,/ site / article /和/ site / category /。我理想地寻找在方法执行结束时调用的解决方案,理想情况下对现有方法代码的最小可能更改,因此在方法结束时添加另一个方法调用不是最佳选择导致代码耦合过多。理想情况下,我希望从外部类中触发处理。

有没有办法可以做到这一点?

3 个答案:

答案 0 :(得分:1)

我使用的是使用@Context Annotation 注释的Resource类的方法,而有一个从上下文范围注入的参数。

  /**
   * 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参数,每次资源调用的自动调用都会消失 - 至少在Jersey中。) 此外,您可以将此方法放在基类中,例如DefaultResourceImpl,您的资源类可以扩展,因此您可以为所有资源类使用此方法。

答案 1 :(得分: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 :-)");
    }
}

答案 2 :(得分: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);
    }
}

在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>

像魅力一样工作;没有杂乱的代码依赖或修改。如果我还需要收集分析数据,我相信我可以进一步扩展它。