我在Resource类中创建了一种情况,其中我收到了所有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 Application类注册我的资源,并跨所有端点设置基本的“上下文”路径:

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

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

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

        resources.add(RegistrationResource.class);

        ...

        return resources;
    }
}


现在,如果将这些方法拆分为多个资源类,则可以使每个服务正常运行,但是我的问题是,上面的设计为什么不起作用?我尝试按上述方法的顺序在此处调用的完整端点是:

/context/incidents/55/registration
/context/incidents/registration/download
/context/incidents/registration/email


为什么找不到上面的映射?通过这种设计,我为每个端点获取了404。


  org.apache.wink.server.internal.RequestProcessor logException调用处理程序链期间发生以下错误:WebApplicationException(404-Not Found),消息为“ null”,同时处理发送到http://localhost:9081/someapp/context/incidents/55/registration的GET请求


作为进一步的说明,我将Wink 1.1用作我的JAX-RS实现,因为我目前绑定到WebSphere 8.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 {
    //...
    }
}


为了方便起见...上面的代码最终生成了这些uri:


GET /公共/事件
GET / public / v1 / incidents / {incidentId} / details
GET / public / v2 / incidents / {incidentId} / details
GET / public / incidents / {incidentId} /票
POST / public / incidents / {incidentId} /注册
POST /管理员/事件
PUT / admin / incidents / {incidentId}
删除/ admin / incidents / {incidentId}
PUT / admin / v1 / incidents / {incidentId} / details
PUT / admin / v2 / incidents / {incidentId} / details
POST / admin / incidents / {incidentId} /票
PUT / admin / incidents / {incidentId} /票
删除/ admin / incidents / {incidentId} / tickets / {detailsUrn}
GET /管理员/事件/注册/报告/下载
GET /管理员/事件/注册/报告/电子邮件
GET / admin / incidents / {incidentId} /注册
PUT / admin / incidents / {incidentId} /注册


那是很多代码;我本来想避免这种情况,但似乎有必要。另外,就其价值而言,直到我添加AdminRegistrationResource类之前,一切似乎一直在起作用。也许该类中的某个端点之一开始引起冲突?

再次...感谢您的时间!

-----------更新#2 -----------

我以为我会在这里发布我最近的特定错误之一,希望它可以帮助解决问题。当我将此端点称为:


  GET /公共/事件


我收到此错误消息:

00000203 ResourceRegis I org.apache.wink.server.internal.registry.ResourceRegistry filterDispatchMethods The system cannot find any method in the com.somewhere.unimportant.rest.resource.external.RegistrationResource class that supports GET. Verify that a method exists.

00000203 RequestProces I org.apache.wink.server.internal.RequestProcessor logException The following error occurred during the invocation of the handlers chain: WebApplicationException (405) with message 'null' while processing GET request sent to https://test.somewhere.com:88888/app777/public/events


现在,对此更有趣的是,我在本地收到此错误,但是我也将代码推送到了具有两个负载平衡服务器的测试环境中。在测试环境中,我在一台服务器上始终收到此错误,但另一台服务器始终运行。因此,一台成功的服务器和一台不成功的服务器的故障率分别为50%。

奇怪...为什么在该类中寻找我要命中的端点?

-----------更新#3 -----------

好的,我已经完全在我的PublicApplication类中使用了@ApplicationPath批注(如下面的注释所建议),并仅用“ /”替换了它,但在以下情况下仍然收到404错误(请注意,对于此测试我已经完全删除了“管理员”服务):

/* Public (and only) Service Set */

@ApplicationPath("/")
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("/public")
public class IncidentResource {

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

@Path("/public")
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("/public/incidents/{incidentId}/tickets")
public class TicketResource {

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

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

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


在这种情况下,我得到此错误:

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


尝试致电时:


  GET /公共/事件


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

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

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


我感谢到目前为止与我在一起的每个人!

最佳答案

删除@ApplicationPath(“ / context”),或者不要在请求uri中使用/ context,或者只使用@ApplicationPath(“ /”),即使升级也不会中断。

上面所有不同的方法都应该起作用,但是对于您的版本,我建议使用@ApplicationPath(“ /”)并通过删除/ context更新您的请求uri,一切都应该按照您最初的意图工作。

Apache Wink尚不支持ApplicationPath。

https://issues.apache.org/jira/browse/WINK-398

10-04 18:30