Как создать сервис JAX-RS, где подресурс @Path не имеет ведущей наклонной черты

Я создал сервис JAX-RS (MyService), который имеет много sub ресурсов, каждый из которых является подклассом MySubResource. sub выбираемый класс ресурса выбран на основе параметров, данных в пути MyService, например:

@Path("/") @Provides({"text/html", "text/xml"}) 
public class MyResource {
  @Path("people/{id}") public MySubResource getPeople(@PathParam("id") String id) {
    return new MyPeopleSubResource(id);
  }
  @Path("places/{id}") public MySubResource getPlaces(@PathParam("id") String id) {
    return new MyPlacesSubResource(id);
  }
}

где MyPlacesSubResource и MyPeopleSubResource являются оба подклассами MySubResource.

MySubResource определяется как:

public abstract class MySubResource {
  protected abstract Results getResults();

  @GET public Results get() { return getResults(); }

  @GET @Path("xml") 
  public Response getXml() {
    return Response.ok(getResults(), MediaType.TEXT_XML_TYPE).build();  
  }

  @GET @Path("html") 
  public Response getHtml() {
    return Response.ok(getResults(), MediaType.TEXT_HTML_TYPE).build();  
  }
}

Результаты обрабатываются соответствующим MessageBodyWriters в зависимости от mimetype ответа.

В то время как это работает, это приводит к путям как/people/Bob/html или/people/Bob/xml, где то, что я действительно хочу, является /people/Bob.html или /people/Bob.xml

Кто-либо знает, как выполнить то, что я хочу сделать?

5
задан PeeHaa 30 September 2013 в 11:54
поделиться

2 ответа

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

@GET @Path("/") @Produces(MediaType.APPLICATION_XML)
public Response getXml() { ... }

@GET @Path("/") @Produces(MediaType.APPLICATION_HTML)
public Response getHtml() { ... }

Провайдер JAX-RS будет сам решать, что вызывать, основываясь на запросе клиента. Еще лучше, если вы можете использовать JAXB и RestEASY, чтобы сделать все это за вас!

@GET
@Produces(MediaType.APPLICATION_XML)
@Path("/{id}")
public MyObject getXml(@PathParam("typeDocument") String id) {
 myObjectService.get(id);
}


@XmlRootElement(name="myObject")
public class MyObject {
// Some properties
}

Смотрите http://java.dzone.com/articles/resteasy-spring хороший пример с Spring.

1
ответ дан 13 December 2019 в 22:04
поделиться

Один из способов решения этой проблемы заключается в том, что вы можете использовать перехват регулярных выражений в вашем @javax.ws.rs.Path.

@Path("people/{id:[^/]+?}{format:(\\.[^/]*?)?}")
@GET
public MySubResource getPeople(@PathParam("id") String id, @PathParam("format") String format) {
    // remove the "." from the start of "format" if it is not null
    return new MySubResource(id, format);
}

Затем в вашем подресурсе:

public abstract class MySubResource {
    final protected String format;

    protected MySubResource(String id, String format) {
        this.format = format;
    }

    protected abstract Results getResults();

    @GET
    public Response get() {
       return Response.ok(getResults(), this.format).build();  
    }
}

Будьте осторожны с регулярными выражениями. Я привел пример, но вы можете захотеть ужесточить выражение, чтобы убедиться, что ничего не проскочило.

Другой способ решить эту проблему - изменить место захвата {id} и использовать регулярное выражение там. Вместо того чтобы @Path("id") MySubResource public getPeople(@PathParam("id") String id) перехватывать id, удалите перехват id из getPeople() и измените MySubResource следующим образом:

 @Path("people")
 public MySubResource getPeople() {
    return new MyPeopleSubResource();
 }

public abstract class MySubResource {
  protected abstract Results getResults();

  @GET
  @Path("{id}")
  public Results get() { return getResults(); }

  @GET
  @Path("{id}.xml") 
  public Response getXml() {
    return Response.ok(getResults(), MediaType.TEXT_XML_TYPE).build();  
  }

  @GET
  @Path("{id}.html") 
  public Response getHtml() {
    return Response.ok(getResults(), MediaType.TEXT_HTML_TYPE).build();  
  }
}

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

1
ответ дан 13 December 2019 в 22:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: