如何使用ServletContainerInitializer映射REST Web服务?

时间:2014-12-12 05:44:08

标签: java rest servlets jersey

我想使用ServletContainerInitializer映射REST API,我的代码是

@Override
public void onStartup(Set<Class<?>> classes, ServletContext container)
        throws ServletException {
    // TODO Auto-generated method stub
    Map<String, String> map=new HashMap<String, String>();
    map.put("com.sun.jersey.config.property.packages", "org.pack");

    ServletRegistration.Dynamic dispatcher = container.addServlet(
            "restful", new ServletContainer());
    dispatcher.setInitParameters(map);
    dispatcher.setLoadOnStartup(1);
    dispatcher.addMapping("/rest/*");

}

应用程序运行时没有任何错误,但未创建Web服务。请在任何网络应用程序中建议我错误的地方以及如何使用ServletContainerInitializer

提前致谢

1 个答案:

答案 0 :(得分:2)

根据我对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

enter image description here

这是初始化类

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并将其安装到本地仓库。然后创建了另一个Maven Web项目,将上面的jar添加到项目中。就是这样。把它放在Tomcat 8和7以及BAM

enter image description here


除此之外

jersey-serlvet.jar(需要使用您正在使用的ServletContainer课程)已经附带com.sun.jersey.server.impl.container.servlet.JerseyServletContainerInitializer。为什么我们需要创建自己的?


修改

  

它在maven上的工作,但我想在没有maven的情况下这样做。我是否必须在不使用maven的情况下将项目jar添加到lib文件夹中。

是的,你可以为初始化器.jar(包括Jersey jars)构建一个胖罐。然后,您需要放置Web项目WEB-INF/lib。所有Maven确实帮助了依赖项并构建.war文件。它还会将初始化jar放入webapp的WEB-INF/lib。所以只是效仿,而不是使用Maven。如果你不想构建一个胖罐,只需确保所有依赖项都包含在lib中