问题
Am new to JavaEE and have some issues getting custom ContainerRequestFilter to run in Jersey. I read the jersey documentation some more and created a new clean project straight from the 'jersey-quickstart-webapp', added the filter seen below but no luck (added an empty beans.xml as well).
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
@Provider
@PreMatching
public class MyFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).entity("User cannot access the resource.").build());
}
}
Was uncertain if Prematching and Provider was complementary or not so i used both then each separately, but didnt work (MyReasource just served as without filter). Tried throwing an exception in MyFilter but that didnt run either.
So i searched through StackOverflow and found 'http://blog.dejavu.sk/2013/11/19/registering-resources-and-providers-in-jersey-2/' which points to that you actually needs to implement registrations in Application or ResourceConfig class. I tried this (didnt work) but i atleast got a warning for the resource class now, 'No resource methods have been found for resource class a.b.MyFilter'
My Application class now looks like below (tried scan package but didnt make a difference. Without the manual filter registration i didnt get the warning either).
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;
import javax.ws.rs.ApplicationPath;
@ApplicationPath("resources")
public class RestApplication extends ResourceConfig {
public RestApplication() {
//packages("a.b");
register(MyFilter.class);
register(MyResource.class);
property(ServerProperties.TRACING, "ALL");
}
}
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
</web-app>
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>a.b</groupId>
<artifactId>server</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>server</name>
<build>
<finalName>server</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<inherited>true</inherited>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<!-- artifactId>jersey-container-servlet</artifactId -->
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
</dependencies>
<properties>
<jersey.version>2.22.1</jersey.version>
<failOnMissingWebXml>false</failOnMissingWebXml>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
All files lies in the 'a.b' (i.e my package) root. Any ideas on how to get the filter actually running and i would be very greatful ;). I presume it shouldnt be this hard to get this working so i guess im missing something here?
回答1:
Let me walk you through what's going on. When you first created the jersey-quickstart-webapp
archetype, it gave you this
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>a.b</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
What this init-param jersey.config.server.provider.packages
does is tell Jersey what package(s) to scan for resource classes annotated with @Path
, and provider classes annotated with @Provider
.
So from that point, all you needed to do was add the @Provider
to the filter, and it would have worked.
But then you decided to clear out the web.xml and use the ResourceConfig
with the @ApplicationPath
. For this to work Jersey takes advantage of the Servlet 3.0 pluggability mechanism, as mentioned in this answer. For that to work we need to make sure we have the jar that has the JerseyServletContainerInitializer
. That's where we need to look at the pom.xml file
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<!-- artifactId>jersey-container-servlet</artifactId -->
</dependency>
The comment is telling you that if you don't need Servlet 2.5 support, you should use jersey-container-servlet
instead of jersey-container-servlet-core
. I don't know, it might be poorly worded. Maybe instead it should say if you want Servlet 3.x support, change it. But in any case, the jersey-container-servlet
has the JerseyContainerServletInitializer
that we need. So if you want to go web.xml-less, then just switch out the dependency.
来源:https://stackoverflow.com/questions/33291897/containerrequestfilter-wont-run-in-javaee-jersey-project