Java 利用JAX-RS实现REST服务的可重用性

Java 利用JAX-RS实现REST服务的可重用性,java,web-services,rest,jax-rs,reusability,Java,Web Services,Rest,Jax Rs,Reusability,我有一个简单的REST类服务,在中实现以维护Foo。它使用POST foos创建foo,使用GET foos列出foo,并使用GET foo/42详细说明给定foo(其中42是给定foo的id) 唯一的区别是@path注释中指定的路径值。由于此值应该是静态的(在编译时可见),因此不可能创建一个AbstracService类,如: public abstract class AbstracService<X> { //abstrac static is not possible

我有一个简单的REST类服务,在中实现以维护
Foo
。它使用
POST foos
创建foo,使用
GET foos
列出foo,并使用
GET foo/42
详细说明给定foo(其中42是给定foo的id)

唯一的区别是
@path
注释中指定的路径值。由于此值应该是静态的(在编译时可见),因此不可能创建一个
AbstracService
类,如:

public abstract class AbstracService<X> {

  //abstrac static is not possible
  public abstract static final String PATH;

  @POST
  @Path(PATH)
  public X create(X entity){ ... }

  @GET
  @Path(PATH)
  public List<X> get(){ ... }

  @GET
  @Path(PATH + "/{id}")
  public X get(@PathParam("id") int id){ ... }
}


public class FooService extends AbstractService<Foo>{
      //just override the PATH to be "foos"
}    

public class BarService extends AbstractService<Bar>{
      //just override the PATH to be "bars"
}    
公共抽象类服务{
//abstrac静态不可能
公共抽象静态最终字符串路径;
@职位
@路径(路径)
公共X创建(X实体){…}
@得到
@路径(路径)
公共列表get(){…}
@得到
@路径(路径+“/{id}”)
公共X get(@PathParam(“id”)int-id){…}
}
公共类FooService扩展了AbstractService{
//只需将路径重写为“foos”
}    
公共类BarService扩展了AbstractService{
//只需将路径覆盖为“条”
}    
我是否需要覆盖每个服务方法来调整
@Path
并调用
super
s实现


上面的类
FooService
BarService
太相似了,不能让我的可重用性保持沉默

我相信你可以做这样的事情

@POST
@Path("/{foosOrBars}")//will match to any string
public BaseFooBar create(@PathParam("foosOrBars") String type){

if(type.equals("foos")){
//do something with the foo
}else{
//do something different
}

}
因此,您有一个基类
BaseFooBar
,可以扩展为
Foo
Bar


但是,如果您在同一服务上有另一个方法,并且只有相同的层次结构级别,例如/foobar,那么您必须小心。它应该有一个固定的标识符,并且不使用大括号,否则您的路径将无法正确匹配。

这种模式在我的资源类中非常常见

@Path("foo")
public class FoosResource {
    @GET  // get all `Foo` resources
    ...
    @GET 
    @Path("{id}")  // get `Foo` with this id
    ...
    @POST // create new `Foo` in `foo` collection
    ...
    @PUT 
    @Path("{id}")  // Update `Foo` with this id
}
你明白了。关键是集合的名称在资源类上,而不是在资源方法级别上

@Path("foo/{id}")
无论如何,您都需要一个
@Path
,才能使该类成为资源类,为什么不为其使用最合适的名称呢


我还可以补充一点,那就是我经常做的事情。我在抽象类中添加了一个
Class
字段,其中包含一个构造函数arg,我可以将
Class
传递给它。然后在具体的类实现中,I
super(Foo.class)
。这样,JPA就可以访问该类,从而更容易进行类型查询。

太糟糕了,基类(
BaseFooBar
)必须事先知道它的所有扩展。这就是我所缺少的。
@Path("foo")
public class FoosResource {
    @GET  // get all `Foo` resources
    ...
    @GET 
    @Path("{id}")  // get `Foo` with this id
    ...
    @POST // create new `Foo` in `foo` collection
    ...
    @PUT 
    @Path("{id}")  // Update `Foo` with this id
}
@Path("foo/{id}")