在运行于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代码注册它。我该怎么办?
DataResource
类中的服务可用性。 为什么不呢?我不想在所有资源类中编写和维护新代码。这是过滤器可以避免的一件事。 1 您可能会问,为什么该服务不可用?没关系动用你的想象力。该逻辑与该问题无关,因此我已将其替换为Random.nextBoolean()
。
答案 0 :(得分:1)
从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>
元素,或者您可以完全删除文件。