无法获得简单的 RS web 服务来与 Eclipse Mars 一起工作

Cannot get simple RS webservice to work with Eclipse Mars

我按照一些教程设置了一个非常简单的 Jersey Webservice,这对我来说非常不清楚。

有时教程在谈论更改 web.xml,其他人则说只需要在您的服务中添加某些注释 class。

所以我得出以下结论:

使用 Jersey 2.x 您无需在 web.xml 中做任何特定的事情,只需拥有 jersey-container-servlet.jar 在您的 class 路径中创建您的服务 class,如下所示:

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

@ApplicationPath("rest")
public class RestService extends Application {

    @GET
    @Path("/sayhello")
    @Produces(MediaType.TEXT_PLAIN)
    public Response sayHello() {
        return Response.ok("Hello World").build();
    }

}

这应该允许我使用 http://localhost:8080/EETest/rest/sayhello

访问 API

我仔细检查了项目已经部署,没有错误,Tomcat7 服务器是 运行。所有的 jersey jar 和依赖项都在我的 lib 文件夹中,并已添加到项目库中。修改后的 index.html 在调用 http://localhost:8080/EETest

时显示正常

但是网络服务没有响应(而是显示 404 页面)。

我知道这一定是一些非常基本的东西我在这里做错了......我运行没有选择。

编辑:这是我的 web.xml 的价值

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>EETest</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
</web-app>

不确定你是从哪里学来的

@ApplicationPath("rest")
public class RestService extends Application {

    @GET
    @Path("/sayhello")
    @Produces(MediaType.TEXT_PLAIN)
    public Response sayHello() {
        return Response.ok("Hello World").build();
    }
}

但这是错误的。在 JAX-RS 中,我们有资源 classes。资源 class 应该用 @Path 注释,而不是 @ApplicationPath。后者用于应用程序配置 class。所以你应该有类似

的东西
@ApplicationPath("/rest")
public class AppConfig extends Application {}

@Path("/")
public class RestService {
    @GET
    @Path("/sayhello")
    @Produces(MediaType.TEXT_PLAIN)
    public Response sayHello() {
        return Response.ok("Hello World").build();
    }
}

@ApplicationPath的空class的作用是触发class路径扫描。因此,将扫描 class 路径以查找使用 @Path@Provider 注释的 classes,并且将注册那些 classes。

在示例中,我使用了 @Path("/"),这样您仍然可以使用相同的 URL /rest/sayHello。但一般来说,资源 class 将有一个映射到集合 URL 的路径,例如 /rest/animals,因此您可以在 class 上使用 @Path("animals"),并且您可以使用方法添加子资源 class 也用 @Path 注释。任何未使用 @Path 注释但具有 @GET 之类的方法的方法都将映射到根资源路径 /rest/animals.

其他几件事。请记住,我提到过 class 路径扫描是用带有 @ApplicationPath 注释的空 Application class 触发的。好吧,这有点令人沮丧。您可以显式注册 classes

@ApplicationPath("/rest")
public class AppConfig extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        final Set<Class<?>> classes = new HashSet<>();
        classes.add(RestService.class);
        return classes;
    }
}

但是当我们使用 Jersey 时,最好使用特定于 Jersey 的 classes(除非您需要保持它在 JAX-RS 实现之间的可移植性)。对于 Jersey,您可以使用它的 ResourceConfig class(它是 Application 的子 class)。您可以使用 register 方法注册单个 classes,您可以使用 packages 方法触发包扫描(这与 class路径扫描不同)

@ApplicationPath("/rest")
public class AppConfig extends ResourceConfig {
    public AppConfig() {
        packages("the.packages.to.scan");

        register(RestService.class);
    }
}