2016-09-27 5 views
0

Я создал ситуацию в классе ресурсов, где я получаю 404s для всех трех конечных точек, и надеялся, что кто-то сможет объяснить, почему. Вот мой класс ресурса:URI Распознавание в Java Использование JAX-RS @Path Аннотации на уровне класса и метода

@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 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://localhost:9081/someapp/context/incidents/55/registration

Как еще одну точку осветления Я использую подмигивание 1.1, как мои JAX-RS реализация, так как я привязан к упакованной версии, которая поставляется с WebSphere 8.5.5.5 в это время.

Спасибо за ваше время!

----------- UPDATE # 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 { 
    //...  
    } 
} 

В целях целесообразности ...вышеприведенный код заканчивается генерации этих URIs:

  • GET/государственные/инцидентов
  • GET/общественные/v1/Происшествия/{incidentId}/детали
  • GET/государственные/v2/инциденты/{incidentId}/Подробнее
  • GET/общественные/происшествия/{incidentId}/билеты
  • POST/государственные/происшествия/{incidentId}/регистрация

  • POST/администратора/происшествия

  • PUT/администратора/происшествия/{incidentId}
  • DELETE/админ/происшествия/{incidentId}
  • PUT/админ/v1/инциденты/{incidentId}/детали
  • PUT/администратора/v2/происшествия/{incidentId}/детали
  • POST/администратора/происшествия/{incidentId}/билеты
  • PUT/админ/происшествия/{incidentId}/билеты
  • DELETE/админ/происшествия/{incidentId}/билеты/{ detailsUnn}
  • GET/admin/инциденты/регистрация Рацион/отчет/загрузить
  • GET/админ/происшествия/регистрация/отчет/электронная почта
  • GET/админ/происшествия/{incidentId}/регистрация
  • PUT/админ/происшествия/{incidentId}/регистрация

Это код; Я хотел избежать этого изначально, но, похоже, это необходимо. Кроме того, для чего это стоит, все, казалось, работало, пока я не добавил класс AdminRegistrationResource. Возможно, что-то с одной из конечных точек в этом классе стало причиной конфликта?

Снова ... спасибо за ваше время!

----------- UPDATE # 2 -----------

Я думал, что я отправлю одну из моих недавних специфических ошибок здесь в надежде, что это может помочь в решении проблемы. Когда я называю эту конечную точку:

GET /public/incidents

Я получаю сообщение об ошибке:

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% разбивается на один успешный сервер и один неудачный сервер.

Странно ... почему это выглядит в этом классе для конечной точки, в которую я попал?

----------- UPDATE # 3 -----------

Хорошо, я вынула использование @ApplicationPath аннотацию в мой класс PublicApplication (как это предлагается из комментариев ниже) и заменил его на «/», но все же получил ошибку 404 в следующем сценарии (обратите внимание, что для этого теста я полностью удалил службы «admin»):

/* 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 /public/incidents

Он также может иметь значение, что остальные 4 конечные точки над работой просто отлично. И, что более важно , если изменить класс IncidentResource, чтобы выглядеть следующим образом (перемещение аннотации @Path на уровне методы полностью на уровень класса), то всего 5 оконечных работу:

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

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

I оцените всех, кто остался со мной так далеко!

+0

Хорошая идея. Изначально у меня было ** не было черенок и добавил их в надежде, что они помогут. Я, однако, просто удалял их снова по вашему предложению, но это не имело никакого значения. – risingTide

+0

@ Roman Vottner: в расширении класса JAX-RS [Приложение] (http://docs.oracle.com/javaee/6/api/javax/ws/rs/core/Application.html); Я отредактировал свой вопрос, чтобы включить это выше. – risingTide

+0

Я бы ожидал, что это тоже сработает. У меня определенно есть служба WebSphere с двумя разными методами '@ GET' на разных путях, хотя ни один из моих методов не имеет параметров вообще. Вы пробовали с некоторыми разными комбинациями path/param, просто чтобы попытаться изолировать определенную причину? Кроме того, какая версия WebSphere? И просмотрели журналы WebSphere для сообщений об ошибках при запуске и по запросу? – dbreaux

ответ

0

Это может работать для вас:

@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() { 
      ... 
    } 
} 

Однако, я бы не рекомендовал расщеплению до контроллера, как это. Вместо этого просто удалите часть кода внутри каждой функции, чтобы отделить классы бизнес-логики.

+0

Спасибо, Майк. Да, это будет работать на самом деле; как я сказал выше, я могу заставить его работать, разбивая его на разные классы. Но мой вопрос пытается понять, почему первоначальная реализация не будет работать. – risingTide

2

Удалить @ApplicationPath ("/ context") или, альтернативно, не использовать/context в запросе uri или просто использовать @ApplicationPath ("/"), он не будет ломаться даже при обновлении.

Все перечисленные выше способы должны работать, но для вашей версии я бы рекомендовал @ApplicationPath ("/") и обновил uris запроса путем удаления/контекста, и все должно работать так, как вы изначально планировали.

У Apache Wink пока нет поддержки для ApplicationPath.

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

+1

Я не ожидал, что это будет основной причиной, но, по-видимому, это так. Если я заменил '@ApplicationPath ("/context ")' на '@ApplicationPath ("/")', тогда все службы будут работать. Проблема может заключаться в том, что у меня есть два отдельных класса, расширяющих 'javax.ws.rs.Application' - по существу«/contextOne »и«/contextTwo ». Возможно, были и конфликты с ними, и изменение одного, чтобы просто «/» устранило конфликт. Что беспокоит то, что у нас есть другие приложения, работающие с несколькими расширениями 'Application', и они работают нормально. Это должно быть связано с определенными комбинациями URL-адресов между ними? – risingTide

+0

Хм ... теперь я думаю, что это не связано с двойным расширением приложения вообще, потому что если я переключу, у какой аннотации есть «/», у меня все еще есть та же проблема. Я должен удалить фактический «contextOne», который включает в себя ресурс выше, чтобы заставить его работать. Таким образом, проблема должна быть напрямую связана с Wink и комбинацией в этом ресурсе, описанной в вопросе выше. – risingTide

+0

Я думаю, что работа вокруг аннотации пути приложения - это ваш единственный вариант. – Veeram

 Смежные вопросы

  • Нет связанных вопросов^_^