在RESTEasy的多种Path映射方式中,Sub Resource Locator是比较有特色的一种方法。通过使用Sub Resource Locator的方式来将URL Path映射至代码中的方法,可以让Class与Path之间有更加自然的关联度,从而提高代码的可读性与可维护性。本文通过实例来讲解这种映射方式。
在使用RESTEasy时,我们一般对某个方法同时标记对应的路径及对应的HTTP方法,例如:
@Path("/some_method")
@GET
public String someMethod() { ... }
这样,当用户以HTTP GET方式访问/some_method时,就会对应由someMethod来进行服务。
而Sub Resource的映射方式有所不同,它将资源拆分为多级,并以URL深度来做为分级的依据,处于"根"位置的方法,只需标记Path,而不需标记HTTP方法,例如:
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
@Path("/store")
public class ShoppingStore {
@Path("/customers/{id}")
public Customer getCustomer(@PathParam("id") int id) {
Customer cust = new Customer("Tom", "Example Street.");
return cust;
}
}
在上面的代码中,getCustomer方法只标记了对应的路径Path,而未标记对应的HTTP方法,我们将这种方法称为sub resource locator,即"子资源定位器",它只承担接受用户针对此路径的请求任务,当用户访问:
/store/customers/{id}
时,它会接收这个请求,但是真正的请求处理工作,则是分派给Customer这个类(注意上面的getCustomer()方法,它的返回类型是Customer)。我们来看看Customer的代码:
import javax.ws.rs.GET;
import javax.ws.rs.Path;
public class Customer {
private String name;
private String address;
public Customer(String name, String address) {
super();
this.name = name;
this.address = address;
}
@GET
public String get() {
return name;
}
@GET
@Path("/address")
public String getAddress() {
return address;
}
}
可以看到,在Customer类中有一个get()方法被标记了GET,它承担了实际的业务逻辑处理工作。
此外,还有一个getAddress()方法,被标记了 "/address" 的路径,当用户访问:
/store/customers/{id}/address
时,由它负责处理请求并返回结果。可以看到,URL地址的层次关系,与代码中的类别关系,被自然地映射在一起了。
小结
以上的代码样例展示了RESTEasy的Sub Resource的使用方法,我们可以看到,RESTEasy并不要求我们一定要把所有的WebService都放在一个Java Class当中,通过Sub Resource Locator,我们可以将WebService的Class设计与对应的URL地址更加直接地对应起来。
实验
我将本次讲解中使用的代码放在github上面了,有兴趣可以clone出来玩玩看:
git clone https://github.com/liweinan/try-resteasy.git
代码签出后可在根目录下运行:
mvn jetty:run
然后访问:
http://127.0.0.1:8080/try-resteasy/store/customers/1
以及:
http://127.0.0.1:8080/try-resteasy/store/customers/1/address
试试看。
参考资料
[1] http://docs.jboss.org/resteasy/docs/1.0.0.GA/userguide/html/JAX-RS_Resource_Locators_and_Sub_Resources.html