在类和方法级别使用JAX-RS@Path注释在Java中识别URI

在类和方法级别使用JAX-RS@Path注释在Java中识别URI,java,rest,jax-rs,websphere,apache-wink,Java,Rest,Jax Rs,Websphere,Apache Wink,我在一个资源类中创建了一个场景,我收到了所有3个端点的404,希望有人能帮助解释原因。这是我的资源类: @Path("/incidents") public class RegistrationResource { @GET @Path("/{incidentId}/registration") public Response getRegisteredIncidents(@PathParam("incidentId") String incidentId) {

我在一个资源类中创建了一个场景,我收到了所有3个端点的404,希望有人能帮助解释原因。这是我的资源类:

@Path("/incidents")
public class RegistrationResource {

    @GET
    @Path("/{incidentId}/registration")
    public Response getRegisteredIncidents(@PathParam("incidentId") String incidentId) {
           ...
    }

    @GET
    @Path("/registration/download")
    public Response downloadRegistrationIncidentsReport() {
           ...
    }

    @GET
    @Path("/registration/email")
    public Response emailRegistrationIncidentsReport() {
           ...
    }
}
我还使用JAX-RS类注册我的资源,并跨所有端点设置基本“上下文”路径:

@ApplicationPath("/context") 
public class AdminApplication extends Application { 

    @Override
    public Set<Class<?>> getClasses() { 

        Set<Class<?>> resources = new HashSet<Class<?>>();

        resources.add(RegistrationResource.class);

        ...

        return resources;
    }
}
为什么找不到上面的映射?通过这种设计,我得到了每个端点的404

org.apache.wink.server.internal.RequestProcessor logException在调用处理程序链期间发生以下错误:在处理发送到的GET请求时,WebApplicationException(404-未找到)出现消息“null”

作为进一步的澄清,我使用Wink 1.1作为我的JAX-RS实现,因为我现在绑定到WebSphere8.5.5.5附带的打包版本

谢谢你的时间

----更新第1版-----

根据下面的评论,我修改了一些端点。然而,我仍然在某些端点上接收到404或405个错误的随机故障。需要注意的是,如果我重新部署,有时不同的端点会失败,或者所有端点都会工作。然后,如果我再次重新部署,我将得到类似的结果,但某些端点失败或全部工作的结果不同。归根结底,这是非常不一致的

正因为如此,似乎比我原来的帖子中有更多的端点冲突,所以为了完整性,我将所有端点粘贴到这里

/* Public Service Set */

@ApplicationPath("/public") 
public class PublicApplication extends Application { 

    @Override
    public Set<Class<?>> getClasses() { 

        Set<Class<?>> resources = new HashSet<Class<?>>();

        resources.add(IncidentResource.class);
        resources.add(IncidentDetailsResource.class);
        resources.add(TicketResource.class);
        resources.add(RegistrationResource.class);

        return resources;
    }
}

@Path("/incidents")
public class IncidentResource { 

    @GET
    @Produces(MediaType.APPLICATION_JSON) 
    public Response getIncidents() throws Exception {
    //...
    } 

@Path("/")
public class IncidentDetailsResource {

    @GET
    @Path("/v1/incidents/{incidentId}/details")
    @Produces(MediaType.APPLICATION_JSON) 
    public Response getIncidentDetails(@PathParam("incidentId") String incidentId) throws Exception {
    //...
    }

    @GET
    @Path("/v2/incidents/{incidentId}/details")
    @Produces(MediaType.APPLICATION_JSON) 
    public Response getIncidentDetailsAsJson(@PathParam("incidentId") String incidentId) throws Exception {
    //...
    }

}

@Path("/incidents/{incidentId}/tickets") 
public class TicketResource {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response getTickets(@PathParam("incidentId") String incidentId) throws Exception {
    //...
    }
}


@Path("/incidents")
public class RegistrationResource {

    @POST
    @Path("/{incidentId}/registration")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response register(@PathParam("incidentId") String incidentId, BaseRequestMessage<IncidentRegistrationRequest> baseRequestMessage) throws Exception {
    //...
    }
}

/* Admin Service Set */

@ApplicationPath("/admin") 
public class AdminApplication extends Application { 

    @Override
    public Set<Class<?>> getClasses() { 

        Set<Class<?>> resources = new HashSet<Class<?>>();

        resources.add(AdminIncidentResource.class);
        resources.add(AdminIncidentDetailsResource.class);
        resources.add(AdminRegistrationResource.class);
        resources.add(AdminRegistrationReportResource.class);
        resources.add(AdminTicketResource.class);

        return resources;
    }
}

@Path("/incidents")
public class AdminIncidentResource { 

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public Response addIncident(BaseRequestMessage<IncidentRequest> baseRequestMessage) throws Exception {
    //...
    }

    @PUT 
    @Path("/{incidentId}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response updateIncident(@PathParam("incidentId") String incidentId, BaseRequestMessage<IncidentRequest> baseRequestMessage) throws Exception {
    //...
    }

    @DELETE 
    @Path("/{incidentId}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response deleteIncident(@PathParam("incidentId") String incidentId) throws Exception {
    //...
    }
}

@Path("/")
public class AdminIncidentDetailsResource {

    @PUT
    @Path("/v1/incidents/{incidentId}/details")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response updateIncidentDetails(@PathParam("incidentId") String incidentId, BaseRequestMessage<IncidentDetailRequest> baseRequestMessage) throws Exception {
    //...    
    }

    @PUT
    @Path("/v2/incidents/{incidentId}/details")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response updateIncidentDetailsAsJson(@PathParam("incidentId") String incidentId, BaseRequestMessage<JsonNode> baseRequestMessage) throws Exception {
    //...
    }
}

@Path("/incidents/{incidentId}/tickets")
public class AdminTicketResource {

    @POST
    @Consumes(MediaType.APPLICATION_JSON) 
    public Response addTicket(@PathParam("incidentId") String incidentId, BaseRequestMessage<TicketRequest> baseRequestMessage) throws Exception {
    //...   
    }

    @PUT
    @Consumes(MediaType.APPLICATION_JSON) 
    public Response updateTicket(@PathParam("incidentId") String incidentId, BaseRequestMessage<TicketRequest> baseRequestMessage) throws Exception {
    //...    
    }

    @DELETE
    @Path("/{detailsUrn}")
    @Consumes(MediaType.APPLICATION_JSON) 
    public Response removeTicket(@PathParam("incidentId") String incidentId, @PathParam("detailsUrn") String detailsUrn) throws Exception {
    //...    
    }

}

@Path("/incidents/registration/report")
public class AdminRegistrationReportResource {

    @GET
    @Path("/download")
    @Produces("application/vnd.ms-excel")
    public Response downloadRegistrationReport() throws Exception { 
    //...    
    }

    @GET
    @Path("/email")
    @Produces(MediaType.APPLICATION_JSON)
    public Response emailRegistrationReport() throws Exception { 
    //...    
    }
}

@Path("/incidents/{incidentId}/registration")
public class AdminRegistrationResource {

    @GET
    @Produces(MediaType.APPLICATION_JSON) 
    public Response getRegisteredUsers(@PathParam("incidentId") String incidentId) throws Exception { 
    //...    
    }

    @PUT
    @Consumes(MediaType.APPLICATION_JSON)
    public Response updateRegisteredUser(@PathParam("incidentId") String incidentId, BaseRequestMessage<IncidentRegistrationRequest> baseRequestMessage) throws Exception {
    //...    
    }
}
现在更有趣的是,我在本地收到了这个错误,但我也将代码推到了一个测试环境中,其中有两个负载平衡的服务器。在测试环境中,我在其中一台服务器上一致地收到此错误,但另一台服务器的工作一致。因此,在一台成功的服务器和一台不成功的服务器上,故障率为50%

奇怪…为什么它在那个类中寻找我要到达的端点

----更新第3期-----

好的,我已经在我的PublicApplication类中完全取消了@ApplicationPath注释的使用(正如下面的评论所建议的),并将其替换为“/”,但在以下场景中仍然收到404错误(请注意,对于此测试,我已经完全删除了“admin”服务):

尝试呼叫时:

获取/公开/事件

上述其他4个端点工作正常也可能是相关的。更重要的是,如果我将IncidentResource类更改为如下所示(将@Path注释在方法级别完全移动到类级别),则所有5个端点都有效:

@Path("/public/incidents")
public class IncidentResource { 

    @GET
    @Produces(MediaType.APPLICATION_JSON) 
    public Response getIncidents() throws Exception {
    //...
    } 

我感谢所有和我在一起的人

这可能适合您:

@Path("/incidents/{incidentId}/registration")
public class RegistrationResource1 {

    @GET
    public Response getRegisteredIncidents(@PathParam("incidentId") String incidentId) {
           ...
    }
}

@Path("/incidents/registration/download")
public class RegistrationResource {

    @GET
    public Response downloadRegistrationIncidentsReport() {
           ...
    }
}

但是,我不建议像那样拆分控制器。相反,只需在每个函数中删除尽可能多的代码,以分离业务逻辑类。

这可能适合您:

@Path("/incidents/{incidentId}/registration")
public class RegistrationResource1 {

    @GET
    public Response getRegisteredIncidents(@PathParam("incidentId") String incidentId) {
           ...
    }
}

@Path("/incidents/registration/download")
public class RegistrationResource {

    @GET
    public Response downloadRegistrationIncidentsReport() {
           ...
    }
}
但是,我不建议像那样拆分控制器。相反,只需注意删除每个函数中尽可能多的代码以分离业务逻辑类。

删除@ApplicationPath(“/context”),或者不在请求uri中使用/context,或者只使用@ApplicationPath(“/”),升级时不会收支平衡

以上所有不同的方法都应该有效,但对于您的版本,我建议使用@ApplicationPath(“/”)并通过删除/context来更新您的请求uri,并且所有方法都应该按照您最初预期的方式工作

ApacheWink目前还不支持ApplicationPath

删除@ApplicationPath(“/context”),或者不在请求uri中使用/context,或者只使用@ApplicationPath(“/”),升级时不会收支平衡

以上所有不同的方法都应该有效,但对于您的版本,我建议使用@ApplicationPath(“/”)并通过删除/context来更新您的请求uri,并且所有方法都应该按照您最初预期的方式工作

ApacheWink目前还不支持ApplicationPath


好主意。最初我没有斜杠,我添加它们是希望它们能有所帮助。然而,在你的建议下,我只是再次删除了它们,但这并没有什么不同。@Roman Vottner:在JAX-RS类的扩展中;我对我的问题进行了编辑,将上述内容包括在内。我本以为这也行得通。我肯定有一个WebSphere服务,在不同的路径上有两个不同的
@GET
方法,尽管我的两个方法都没有任何参数。您是否尝试过一些不同的路径/参数组合,只是为了找出特定的原因?还有,什么版本的WebSphere?您是否查看了WebSphere日志中启动时和收到请求时的错误消息?我有多个方法组合和其他path/param组合,这些都很好。启动时没有WebSphere错误,WebSphere的确切版本是8.5.5.5。我已经用我收到的实际错误信息修改了原来的问题。我只是抓住一些东西来尝试,在这里找出根本原因。。。我试过删除/id/注册号,看看其他两个是否也有相同的行为?试着移除两个非参数中的一个,看看会发生什么?我的直觉告诉我,这可能和并没有参数方法有关,但我并没有具体的理由产生这种预感。好主意。最初我没有斜杠,我添加它们是希望它们能有所帮助。然而,在你的建议下,我只是再次删除了它们,但这并没有什么不同。@Roman Vottner:在JAX-RS类的扩展中;我对我的问题进行了编辑,将上述内容包括在内。我本以为这也行得通。我肯定有一个WebSphere服务w
org.apache.wink.server.internal.RequestProcessor logException The following error occurred during the invocation of the handlers chain: WebApplicationException (404 - Not Found) with message 'null' while processing GET request sent to http://test.somewhere.com:88888/app777/public/events
@Path("/public/incidents")
public class IncidentResource { 

    @GET
    @Produces(MediaType.APPLICATION_JSON) 
    public Response getIncidents() throws Exception {
    //...
    } 
@Path("/incidents/{incidentId}/registration")
public class RegistrationResource1 {

    @GET
    public Response getRegisteredIncidents(@PathParam("incidentId") String incidentId) {
           ...
    }
}

@Path("/incidents/registration/download")
public class RegistrationResource {

    @GET
    public Response downloadRegistrationIncidentsReport() {
           ...
    }
}