繁体   English   中英

泽西岛1.x和Tomcat:如何以编程方式注册ContainerRequestFilter,即没有web.xml?

[英]Jersey 1.x and Tomcat: how to register a ContainerRequestFilter programmatically, i.e. without web.xml?

我的应用程序

在我的Tomcat中运行的JAX-RS / Jersey应用程序中,我需要运行一个在每个资源方法之前实现ContainerRequestFilter的过滤器类。 过滤器确定该服务现在是否可用1 如果我在web.xml中注册过滤器,则可以轻松完成此操作:

DataResource.java

package thepackage;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("/data")
public class DataResource {

  @GET
  @Produces("application/json")
  public String getData() {
    return "{\"data\": [{\"id\": 1},{\"id\": 2}]}";
  }

}

ServiceAvailabilityFilter.java

package thepackage;

import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerRequestFilter;
import java.util.Random;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

public class ServiceAvailabilityFilter implements ContainerRequestFilter {

  private static final Random RANDOM = new Random();

  private boolean isServiceAvailable(ContainerRequest request) {
    // Actual logic goes here; for this sample, just flip a coin
    return RANDOM.nextBoolean();
  }

  @Override
  public ContainerRequest filter(ContainerRequest request) {
    if (isServiceAvailable(request)) {
      return request;
    } else {
      throw new WebApplicationException(
          Response.serverError().type(MediaType.APPLICATION_JSON_TYPE)
              .entity("{\"error\":\"Service not available\"}").build()
      );
    }
  }

}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
  <servlet>
    <servlet-name>jersey</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>com.sun.jersey.config.property.packages</param-name>
      <param-value>io.github.garysheppardjr.jersey1xfiltertest</param-value>
    </init-param>
    <init-param>
      <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
      <param-value>io.github.garysheppardjr.jersey1xfiltertest.ServiceAvailabilityFilter</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>jersey</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>

我的问题

但是,我不想用XML声明ServiceAvailabilityFilter 我想用Java代码注册它。 我该怎么做?

我宁愿不做的事情

  • 在web.xml中声明过滤器。 为什么不? 如果我以本地软件的形式提供此应用程序,那么我想确保某人无法通过编辑web.xml禁用我的过滤器。
  • DataResource类中检查服务可用性。 为什么不? 我不想在所有资源类中编写和维护新代码。 这是过滤器可以避免的一件事。
  • 从Jersey 1.x更改为Jersey2.x。 为什么不? 我有依赖关系和截止日期,这将使迁移到Jersey 2.x非常困难。

1您可能会问,为什么该服务不可用? 没关系 动用你的想象力。 该逻辑与该问题无关,因此我已将其替换为Random.nextBoolean()

从web.xml中删除您的<servlet>元素(或者如果您拥有其中的全部内容并且至少使用Servlet API 3.0,则甚至完全删除web.xml)。 要替换<servlet>元素,请创建一个扩展javax.ws.rs.core.Application的类。 对于此问题,扩展com.sun.jersey.api.core.PackagesResourceConfig可能是最简单的。 使用javax.ws.rs.ApplicationPath注释新类。 在此类的构造函数中进行<init-param>设置。

DataResource.java :不变。

ServiceAvailabilityFilter.java :不变。

MyApplication.java (或任何您想调用的名称):

package thepackage;

import com.sun.jersey.api.core.PackagesResourceConfig;
import javax.ws.rs.ApplicationPath;

@ApplicationPath("/")
public class MyApplication extends PackagesResourceConfig {

  public MyApplication() {
    // "com.sun.jersey.config.property.packages" init-param
    super(DataResource.class.getPackageName());
    // "com.sun.jersey.spi.container.ContainerRequestFilters" init-param
    getContainerRequestFilters().add(ServiceAvailabilityFilter.class);
  }

}

web.xml :至少删除<servlet>元素,或者您可以完全删除文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM