问题
I'm trying to configure Jersey with Servlet 3.1 and an Application Subclass. Been reading documentation for a while and trying to get this going, but i'm not sure what's wrong here.
web.xml (though I shouldn't need one I get a 404 without one...)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>Foobar Models</display-name>
<welcome-file-list>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
<session-config>
<session-timeout>30</session-timeout>
<cookie-config>
<name>SESSIONID</name>
</cookie-config>
</session-config>
<servlet>
<servlet-name>Foo Bar Application</servlet-name>
<servlet-class>com.foobar.jaxrs.application.FooBarApplication</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Foo Bar Application</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
</web-app>
Application Subclass
package com.foobar.jaxrs.application;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/api")
public class FooBarApplication extends Application {
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(com.foobar.api.HealthCheckResource.class);
return s;
}
}
HealthCheckResource.java
package com.foobar.api;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@Path("health")
public class HealthCheckResource {
@GET
@Produces("text/html")
public String getHeath() {
return "Foo Bar Application is healthy!";
}
}
Running in jetty (same in Tomcat 8)
HTTP ERROR 404
Problem accessing /foobar/api/health. Reason:
Servlet class com.foobar.jaxrs.application.FooBarApplication is not a javax.servlet.Servlet
Caused by:
javax.servlet.UnavailableException: Servlet class com.foobar.jaxrs.application.FooBarApplication is not a javax.servlet.Servlet
at org.mortbay.jetty.servlet.ServletHolder.checkServletType(ServletHolder.java:362)
at org.mortbay.jetty.servlet.ServletHolder.doStart(ServletHolder.java:243)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:685)
....
回答1:
Well, the message says it all. You're trying to deploy your Application subclass, which doesn't extend from Servlet, as a servlet. That can't possibly work.
This is not how the Jersey documentation tells to do things. Here is what it says:
Hooking up Jersey as a Servlet
<web-app>
<servlet>
<servlet-name>MyApplication</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
...
</init-param>
</servlet>
...
<servlet-mapping>
<servlet-name>MyApplication</servlet-name>
<url-pattern>/myApp/*</url-pattern>
</servlet-mapping>
...
</web-app>
Note that the servlet class is org.glassfish.jersey.servlet.ServletContainer. Not your custom Application subclass.
Custom Application subclass
If you extend the Application class to provide the list of relevant root resource classes (getClasses()) and singletons (getSingletons()), i.e. your JAX-RS application model, you then need to register it in your web application web.xml deployment descriptor using a Servlet or Servlet filter initialization parameter with a name of javax.ws.rs.Application [sic] as follows:
Example 4.11. Configuring Jersey container Servlet or Filter to use custom Application subclass
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>org.foo.MyApplication</param-value>
</init-param>
Note that the custom Application subclass is configured as an init-param of the servlet. Not as the servlet class.
回答2:
I figured out the issue - I was running in gradle's jetty plugin which uses servlet 2.5 but i'm deploying a servlet 3.1 app. I was able to get it to work without the web.xml after deploying to Tomcat 8 with the correct configuration.
It still doesnt work with Jetty (need to get an updated version of jetty), but in Tomcat 8 this works:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>Foo Bar Models</display-name>
<welcome-file-list>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
</web-app>
BaseApplication.java package com.foobar.jaxrs.application;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("")
public class BaseApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(com.patrickkee.resources.HealthCheckResource.class);
return s;
}
}
来源:https://stackoverflow.com/questions/33323138/servlet-class-com-foobar-jaxrs-application-myapplication-is-not-a-javax-servlet