使用Eclipse和Payara服务器的Jersey REST应用程序找不到HTTP状态404

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Eclipse和Payara服务器的Jersey REST应用程序找不到HTTP状态404相关的知识,希望对你有一定的参考价值。

我正在尝试使用Payara服务器为Eclipse中的预订系统开发Jersey服务器应用程序。当我运行项目时,我得到“HTTP状态404 - 未找到”。我检查了几个教程和StackOverflow帖子,但找不到错误。任何人都可以帮我吗?

BookingService界面:

public interface BookingService {

    public Response addBooking(Room room);

    public Response cancelBooking(Room room);

    public Room getRoom(int roomNumber);

    public Room[] getAllAvailableRooms();
}

BookingService实施:

@Path("/booking")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class BookingServiceImpl implements BookingService{

private static Map<Integer,Room> rooms = new HashMap<Integer,Room>();

@POST
@Path("/add")
public Response addBooking(Room room) {
    Response response = new Response();

    if(rooms.get(room.getNumber()).isBooked()) {
        response.setMessage("This room is not available");
        return response;
    }
    room.bookRoom();
    response.setMessage("Room successfully booked");

    return response;
}

@GET
@Path("/delete")
public Response cancelBooking(Room room) {
    Response response = new Response();
    if(!rooms.get(room.getNumber()).isBooked()) {
        response.setMessage("This room is not booked so booking cannot be cancelled");
        return response;
    }

    room.cancelBooking();
    response.setMessage("The booking for room " + room.getNumber() + "has been successfully cancelled");
    return null;
}

@GET
@Path("/getAll")
public Room[] getAllAvailableRooms() {
    Set<Integer> keys = rooms.keySet();
    Room[] roomArray = new Room[keys.size()];
    int i=0;
    for(Integer key : keys){
        if (!rooms.get(key).isBooked()) {
            roomArray[i] = rooms.get(key);
            i++;
        }
    }
    return roomArray;
}

pom.hml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>se.kth.id1212</groupId>
<artifactId>ID1212BookingSystem</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>ID1212BookingSystem Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-server</artifactId>
        <version>2.20</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>2.20</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.13</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-common</artifactId>
        <version>2.22.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>
<build>
    <finalName>ID1212BookingSystem</finalName>
    <plugins>
        <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.6</version>
            <configuration>
                <warSourceDirectory>WebContent</warSourceDirectory>
                <failOnMissingWebXml>false</failOnMissingWebXml>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.3</version>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
    </plugins>
</build>

编辑:当我研究问题时,我读到web.xml文件在使用jersey 2时不必指定除显示名称之外的任何内容。我不知道这是否属实,但下面是我之前使用的web.xml文件阅读,但它也不起作用。

<web-app>
    <display-name>Archetype Created Web Application</display-name>
    <!-- Jersey Servlet configurations -->
    <servlet>
        <servlet-name>Jersey REST Service</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>se.kth.id1212.ID1212BookingSystem</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey REST Service</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    <!-- Jersey Servlet configurations -->
</web-app>

编辑2,添加以下图片:

答案

即使您的最新web.xml存在问题,您也需要放慢速度并将每个更改与教程进行比较。按照提到的教程

你应该在你的web.xml中有init-param

<init-param>
    <param-name>jersey.config.server.provider.packages</param-name>
    <param-value>se.kth.id1212.ID1212BookingSystem</param-value>
</init-param>

但是,相反,你写了

<init-param>
    <param-name>javax.ws.rs.Application</param-name>
    <param-value>se.kth.id1212.ID1212BookingSystem</param-value>
</init-param>

此外,只是为了注意,/add期望POST,这意味着它将期望其身体中的请求数据。我建议使用一些REST客户端,可能是POSTMAN进行测试。

==更新==

我真的不明白,你为什么在你的web.xml使用下面的包名?

<param-value>se.kth.id1212.ID1212BookingSystem</param-value>

我是明确的,在某个地方,你没有犯错,BookingServiceImpl的包应该是server.service而不是se.kth.id1212.ID1212BookingSystem。所以,在param-value中,你应该提供相同的包名而不是随机的..所以,它应该是

 <param-value>server.service</param-value>

另外,我看到,你在课堂上使用过Produces / Consumes注释,而应该在每个方法上使用

 @Produces(MediaType.APPLICATION_JSON)
 @Consumes(MediaType.APPLICATION_JSON)
 public class BookingServiceImpl implements BookingService{

这是我谦虚的要求,不要把你的知识与可用的教程混在一起。首先尝试通过完全遵循任何可用的教程(可能只是复制/粘贴)来理解实现。选择最简单的教程可能只是打印Hello World

另一答案

您的应用程序似乎没有定义侦听根URL的REST端点。如果您的应用程序在http://localhost/myapp这样的网址上运行,则获取该网址的HTTP 404响应是完全正常的。您只能从绑定到某些REST方法的URL获得有效响应。

因为BookingServiceImpl绑定到“/ booking”并且它的所有方法都绑定到“/ add”或“/ getAll”之类的子路径,所以你可以通过组合来访问REST方法

  • 应用程序上下文根,例如“myapp”(我不知道)
  • JAX-RS应用程序根路径,它是web.xml中定义的“/ *”,表示它是空的
  • BookingServiceImpl路径,这是“/预订”
  • BookingServiceImpl方法的路径,例如getAllAvailableRooms的“/ getAll”

因此,要调用getAllAvailableRooms方法,您应该使用像http://localhost/myapp/booking/getAll这样的URL而不仅仅是http://localhost/myapp

在最近的Payara Server版本中,当您转到应用程序详细信息并单击底部“模块和组件”表中的“查看端点”时,您应该能够在Web管理控制台中看到所有可用的URL,请参阅结束。

补充说明:

我建议在一个单独的类中定义JAX-RS应用程序,该类扩展javax.ws.rs.Application并接受带有servlet映射的@ApplicationPath注释。然后,您的web.xml中不需要任何内容​​,甚至可以删除它。这是与您的web.xml等效的Java代码(是的,就是这么简单,所有其他代码都是可选的):

@ApplicationPath("/")  // maps the servlet to "/*"
public class MyRESTApplication extends Application {
}

我还建议观看一个关于在Netbeans中使用Payara创建REST服务的简短视频(它在http://www.youtube.com/watch?v = F26jcZrgGMkld中与Eclipse非常相似,IDE并不太相关):https://www.youtube.com/watch?v=F26jcZrgGMk (您可以跳过介绍并从3:30开始)

Payara管理控制台中的REST端点详细信息

Application details in Admin console REST endpoints in Admin console

以上是关于使用Eclipse和Payara服务器的Jersey REST应用程序找不到HTTP状态404的主要内容,如果未能解决你的问题,请参考以下文章

Payara中的Apache Camel:'java:/ TransactionManager'查找失败

如何计划从 WebSphere 迁移到更便宜的应用程序服务器,如 JBoss、Tomcat 或 Payara

升级到 payara 4.1.1.171 后应用程序未加载

收到 SSLHandshakeException:收到致命警报:尝试连接第三方 URL 时来自 Payara 服务器的 handshake_failure

使用 Payara 4.1.1 在不同的 JAR 中加载 CDI bean

如何在 Payara 5.193 中配置数据网格 ttl