【问题标题】:Error when using JAX-RS and Jetty?使用 JAX-RS 和 Jetty 时出错?
【发布时间】:2017-01-17 03:24:06
【问题描述】:

我正在尝试创建一个简单的 REST api,并按照 Jersey 网站上的教程进行操作:https://jersey.java.net/nonav/documentation/2.0/deployment.html

这是错误:

原因:javax.servlet.UnavailableException:持有者中没有类 在 org.eclipse.jetty.servlet.BaseHolder.doStart(BaseHolder.java:88) 在 org.eclipse.jetty.servlet.ServletHolder.doStart(ServletHolder.java:361) 在 org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) 在 org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:874)

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 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">
    <servlet>
        <display-name>My JAX-RS Servlet</display-name>
        <servlet-name>MyJaxRsApp</servlet-name>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.example.flexible.helloworld.MyApplication</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>MyJaxRsApp</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

REST 资源类

package com.example.flexible.helloworld;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Application;

public class MyJaxRsApplication {

    /**
     * Method handling HTTP GET requests. The returned object will be sent
     * to the client as "text/plain" media type.
     *
     * @return String that will be returned as a text/plain response.
     */
    @GET
    @Path("helloworld")
    @Produces(MediaType.TEXT_PLAIN)
    public String getIt() {
        return "Got it!";
    }
}

应用程序“根”

package com.example.flexible.helloworld;

import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

public class MyApplication extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> s = new HashSet<Class<?>>();
        s.add(MyJaxRsApplication.class);
        return s;
    }
}

pom.xml

<!-- [START project] -->
<project>
  <modelVersion>4.0.0</modelVersion>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <groupId>org.myproject</groupId>
  <artifactId>myproject-0.0</artifactId>

  <properties>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>

    <appengine.maven.plugin>0.1.1-beta</appengine.maven.plugin>
    <jetty-maven-plugin-version>9.3.7.v20160115</jetty-maven-plugin-version>

    <failOnMissingWebXml>false</failOnMissingWebXml>
  </properties>

  <!-- [START dependencies] -->
  <dependencies>

    <!-- REST framework -->
    <dependency>
      <groupId>org.glassfish.jersey.core</groupId>
      <artifactId>jersey-server</artifactId>
      <version>2.23.2</version>
    </dependency>

  </dependencies>
  <!-- [END dependencies] -->

  <build>
    <!-- for hot reload of the web application -->
    <outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
    <plugins>

      <plugin>
        <groupId>com.google.cloud.tools</groupId>
        <artifactId>appengine-maven-plugin</artifactId>
        <version>${appengine.maven.plugin}</version>
        <configuration>
          <!-- deploy configuration -->
          <deploy.promote>true</deploy.promote>
          <deploy.stopPreviousVersion>true</deploy.stopPreviousVersion>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <version>${jetty-maven-plugin-version}</version>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.0.0</version>
      </plugin>

    </plugins>
  </build>
</project>
<!-- [END project] -->

我实际上是在使用 jetty 的 Google AppEngine helloworld 示例的基础上构建的,所以我部署它的方式是“mvn clean jetty:run-exploded”。按照我的理解,jetty 是一个 web-server/servlet 容器。但是我这里有 servlet 吗?是隐式创建的吗?

另外,我查看了错误,发现需要定义 &lt;servlet-class&gt;。泽西的文档中也提到了这一点。但是当我添加 &lt;servlet-class&gt;org.glassfish.jersey.servlet.ServletContainer&lt;/servlet-class&gt; 行时,我在 localhost:8080/helloworld 得到 Resource not found。此外,servlet 3.0 不应该要求定义 &lt;servlet-class&gt;(也在 jersey 的文档中提到)。

【问题讨论】:

  • 您不能混合发现(字节码的注释扫描)和声明的(WEB-INF/web.xml)相同的端点(servlet/filters)并期望它工作。使用其中一种。

标签: servlets jakarta-ee jetty


【解决方案1】:

在没有 web.xml 的情况下设置 JAX-RS 应用程序配置

使用 ResourceConfig(不需要 web.xml)

@javax.ws.rs.ApplicationPath(ResourcePath.API_ROOT)
    public class ApplicationConfig extends ResourceConfig {

     public ApplicationConfig() {
    //register the necessary headers files needed from client
    register(CORSConfigurationFilter.class);
    //The jackson feature and provider is used for object serialization

    register(JacksonFeature.class);
    register(JacksonProvider.class);
    //inject and registered all resources class using the package

    packages("com.example.myapi.package");
  }

  @Override
  public Collection<String> getPropertyNames() {
    return super.getPropertyNames();
  }
}

【讨论】:

    猜你喜欢
    • 2013-12-18
    • 2013-08-27
    • 1970-01-01
    • 2012-04-20
    • 2011-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-23
    相关资源
    最近更新 更多