【问题标题】:Create RESTful Web Service with JAX-RS and deploy it to tomcat使用 JAX-RS 创建 RESTful Web 服务并将其部署到 tomcat
【发布时间】:2013-12-24 21:50:31
【问题描述】:

我正在尝试使用 JAX-RS 创建和部署 RESTful Web 服务并将其部署到 tomcat。我不想使用任何 IDE。 在 Tomcat 中,我在 webapps\

中有以下目录结构
notifire\WEB-INF\
                 |
                 ---> web.xml
                 |
                 ---> \classes/Notifier.class
                 |
                 ---> \lib\javax.ws.rs-api-2.0

我的 web.xml 包含:

<servlet>
<servlet-name>Web Service Servlet</servlet-name>
<servlet-class>javax.ws.rs.core.Application</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>Web Service Servlet</servlet-name>
<url-pattern>/webservice/*</url-pattern>
</servlet-mapping>

类文件Notifier.class是从文件Notifier.java编译而来的。

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;

@Path("notifier")
public class Notifier {

    @Context
    private UriInfo context;

    @GET
    @Produces("text/html")
    public String getHTML() {

         return "<p></p>";
    }
}

当我尝试通过http://localhost:8080/notifire/webservice/notifier 访问 Web 服务时,我收到以下错误:

--类型异常报告

--message 类 javax.ws.rs.core.Application 不是 Servlet

--description 服务器遇到了一个内部错误,导致它无法完成这个请求。

感谢任何帮助。

【问题讨论】:

    标签: java web-services rest tomcat


    【解决方案1】:

    您的 Servlet 的类有误。不确定您为什么不想使用 IDE,但有一个 maven 原型可以使用 Jersey 开发人员定义的适当类为您布局项目结构。我的 web.xml 看起来像这样:

    <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>com.pluralsight</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey Web Application</servlet-name>
        <url-pattern>/webapi/*</url-pattern>
    </servlet-mapping>
    

    我在这门课程中涵盖了所有这些here

    【讨论】:

    • 顺便说一句,提供程序包只是您项目中的包。
    • 我更改了我的 web.xml,现在我有了“HTTP 状态 404 - 未找到”。我还下载了“Jersey JAX-RS 2.0 RI”捆绑包,并将其所有内容放在文件夹 \lib 中。我暂时不想使用 IDE,因为我想了解幕后发生的事情。
    • 好的,现在可以了...我忘记了 Notifier.java 文件中的包声明
    • 嗨,我也面临同样的问题。你能告诉我你在 web.xml 中究竟做了什么改变吗?
    • 您是否遇到完全相同的错误?您面临的“同样的问题”是什么?
    【解决方案2】:

    我也遇到了麻烦。因为无论如何你都必须使用web.xml,所以让restful web services工作的最简单的方法是完全忘记扩展javax.ws.rs.core.Application,而只需在那里指定上下文路径。您仍然可以使用标准的 jax-rs 注释来声明实际的 Web 服务。

    web.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app
      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_3_0.xsd"
      version="3.0"
    >
      <servlet>
        <servlet-name>rest-test</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <init-param>
          <param-name>com.sun.jersey.config.property.packages</param-name>
          <param-value>com.domain.mypackage</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name> rest-test</servlet-name>
        <url-pattern>/rest/*</url-pattern>
      </servlet-mapping>
    </web-app>
    

    两个值得注意的点:

    1. 您需要在 WAR 文件中捆绑一个 REST 实现,因为 servlet 容器通常不包含一个。由于 Jersey 是 JAX-RS 的参考实现,这就是我在上面的 servlet-class 元素中使用的那个。如果需要,您可以将其替换为 Apache CXF 实现。

    2. init-param 元素告诉 Jersey 您的哪些包要搜索带有 Web 服务注释的 Java 文件。编辑它以指向您的 Web 服务。请注意,如果您选择使用 apache CXF 而不是 Jersey,则任何 init-param 元素中所需的内容都会有所不同。知道 CXF 的人请发布他们会是什么。

    如果您使用的是 Maven,只需在 dependencies 文件的 dependencies 部分中添加对 jersey-servlet 的依赖项即可:

    <dependencies>
      <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-servlet</artifactId>
        <version>1.18.2</version>
      </dependency>
      ...
    </dependencies>
    

    在此之后,可以直接在 Java 类中使用标准 JAX-RS 注释来声明 Web 服务:

    package com.domain.mypackage;
    import javax.ws.rs.Consumes;
    import javax.ws.rs.Produces;
    import javax.ws.rs.GET;
    import javax.ws.rs.MatrixParam;
    import javax.ws.rs.Path;
    
    // It's good practice to include a version number in the path so you can have
    // multiple versions deployed at once. That way consumers don't need to upgrade
    // right away if things are working for them.
    @Path("calc/1.0")
    public class CalculatorV1_0 {
      @GET
      @Consumes("text/plain")
      @Produces("text/plain")
      @Path("addTwoNumbers")
      public String add(@MatrixParam("firstNumber") int n1, @MatrixParam("secondNumber") int n2) {
        return String.valueOf(n1 + n2);
      }
    }
    

    这应该就是您所需要的。如果您的 Tomcat 安装在端口 8080 上本地运行,并且您将 WAR 文件部署到上下文 myContext,则转到

    http://localhost:8080/myContext/rest/calc/1.0/addTwoNumbers;firstNumber=2;secondNumber=3
    

    ...应该会产生预期的结果 (5)。

    干杯!

    * 如果您知道在不使用web.xml 的情况下将 Jersey servlet 添加到 Tomcat 的上下文中的方法,请纠正我--也许通过使用上下文或生命周期侦听器?

    【讨论】:

    • 查看我的回答here,了解如何仅使用注释创建 REST 服务(无需 web.xml)。
    猜你喜欢
    • 1970-01-01
    • 2013-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 1970-01-01
    • 2021-04-06
    相关资源
    最近更新 更多