据我了解,ServletContainerInitializer 是基于服务提供者模式的。不久前我浏览了一个关于它的教程,现在找不到了。但是您可以在ServiceLoader javadocs 中看到一些要求。它指出:
服务提供者是通过在资源目录META-INF/services 中放置提供者配置文件来识别的。该文件的名称是服务类型的完全限定二进制名称。该文件包含具体提供程序类的完全限定二进制名称列表,每行一个。
我为使您的示例生效所采取的步骤:
使用这些依赖项创建一个 Maven jar 项目
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.18.1</version>
</dependency>
创建一个META-INF/services 目录。您可以直接放入src 或使用Maven 我喜欢将其放入src/main/resources。他们最终会在同一个地方。
创建一个名为javax.servlet.ServletContainerInitializer 的文件,并将ServletContainerInitializer 实现的完全限定名称放入其中。将文件放入META-INF/services。这是我的
META-INF/services/
javax.servlet.ServletContainerInitializer
// content
jersey.servlet.initializer.MyJerseyContainerInitializer
这里是初始化类
package jersey.servlet.initializer;
import com.sun.jersey.spi.container.servlet.ServletContainer;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
public class MyJerseyContainerInitializer implements ServletContainerInitializer{
@Override
public void onStartup(Set<Class<?>> set, ServletContext sc)
throws ServletException {
System.out.println("===============================================");
System.out.println(" onStartup() ");
System.out.println("===============================================");
Map<String, String> map = new HashMap<>();
map.put("com.sun.jersey.config.property.packages",
"jersey.servlet.initializer.rest");
ServletRegistration.Dynamic dispatcher = sc.addServlet(
"restful", new ServletContainer());
dispatcher.setInitParameters(map);
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/rest/*");
}
}
还有一个简单的休息资源类
package jersey.servlet.initializer.rest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
@Path("/resource")
public class Resource {
@GET
public Response getResponse() {
return Response.ok("ServletContainerInitializer test OK!").build();
}
}
然后我构建了 jar 并将其安装到本地 repo。然后创建另一个 Maven web 项目,将上面的 jar 添加到项目中。而已。在 Tomcat 8 和 7 以及 BAM 上运行它
除此之外
jersey-serlvet.jar(使用您正在使用的ServletContainer 类需要它)已经随com.sun.jersey.server.impl.container.servlet.JerseyServletContainerInitializer 一起提供。为什么我们需要创建自己的?
编辑
它在 maven 上工作,但我想在没有 maven 的情况下做到这一点。如果没有 maven,我是否必须将项目 jar 添加到 lib 文件夹中。
是的,您可以为初始化程序 .jar(包括 Jersey jars)构建一个胖 jar。然后你需要放置 web 项目WEB-INF/lib。所有 Maven 都确实帮助解决了依赖关系并构建了 .war 文件。它还将初始化 jar 放入 webapp 的WEB-INF/lib。所以就跟风,不要使用 Maven。如果您不想构建胖 jar,只需确保所有依赖项都包含在 lib 中