【问题标题】:How to map REST web service using ServletContainerInitializer?如何使用 ServletContainerInitializer 映射 REST Web 服务?
【发布时间】:2015-02-10 19:19:54
【问题描述】:

我想使用 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

提前致谢

【问题讨论】:

    标签: java rest servlets jersey


    【解决方案1】:

    据我了解,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 中

    【讨论】:

    • 感谢您的回复。它在 Maven 上工作,但我想在没有 Maven 的情况下进行。如果没有 maven,我是否必须将项目 jar 添加到 lib 文件夹中。
    • 是的,您可以为初始化程序 .jar(包括 Jersey jars)构建一个胖 jar。然后你需要放置 web 项目WEB-INF/lib。所有 Maven 都确实帮助解决了依赖关系并构建了 .war 文件。它还将初始化 jar 放入 webapp 的WEB-INF/lib。所以就跟风,使用 Maven。如果您不想构建胖 jar,只需确保所有依赖项都包含在 lib 中
    • META-INF/services 应该放在src
    • 非常感谢。这个对我有用。我试图在最后几天这样做,但没有得到任何解决方案。你帮了我很多
    猜你喜欢
    • 2010-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-26
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多