サービスのパスの設定
@Pathアノテーション
クラス、メソッドに指定して、RESTサービスのパス(URL)を決める。@Path("employee")
public class EmpService{
@GET
@Path("service1")
public Response service1() {
この場合サービスのURLはhttp://ホスト/コンテキストルート/employee/service1
となる。
可変パスの扱い
@Pathと@PathParam
RESTでは”一意なURL”というのがが基本的な考え方としてある。URLのパスにIDを含める形になる(”サービス/{id} ”というような形)。jax-rsではパスの値が可変なURLを扱うことができる。
@Path("employee")
public class EmpService{
@GET
@Path("{id}")
public Response service1(@PathParam String id) {
これで、http://ホスト/コンテキストルート/employee/123
にアクセスした場合、 @PathParamアノテーションで修飾した引数 id に"123"が入ってくる。
複合キーならどうするか?
複合キーを"-"等で繋いだ場合、は以下のような形になる。http://ホスト/コンテキストルート/employee/123-111 の場合
@Path("employee")
public class EmpService{
@GET
@Path("{id1}-{id2}")
public Response service1(@PathParam String id1, @PathParam Strind id2) {
HTTPメソッドの指定
@GET, @PUT, @POST, @DELETE, @HEADアノテーションを使って、どのHTTPメソッドで受けるかを指定する。同一パスでもHTTPメソッドによって処理を切り分けることができる。
@Path("employee")
public class EmpService{
@GET
@Path("{id}")
public Response get(@PathParam String id) {
}
@PUT
@Path("{id}")
public Response update(@PathParam String id) {
}
@POST
@Path("{id}")
public Response insert(@PathParam String id) {
}
@DELETE
@Path("{id}")
public Response delete(@PathParam String id) {
}
}
この場合、同じURLhttp://ホスト/コンテキストルート/employee/123
を、HTTPメソッドを分けて使うことができる。正しいRESTの形はこのように実現できる。
実装されていないメソッドでアクセスがあった場合、405 Method Not Allowed がクライアントに返される。
POST,PUTされる様々なContent-TypeのデータをJavaオブジェクトへ変換する
@Consumesアノテーションで受け取るデータのContent-Typeを指定することができる。たとえば以下のJSONデータをPOSTされて、Employeeというクラス(Value Object)にマッピングする場合は以下のようになる。
{ "empId" : "123", "firstName" : "Oscar" , "lastName" : "Jarjays", "gender" : "female" }
@Path("employee")
public class EmpService{
@POST
@Consumes({ MediaType.APPLICATION_JSON })
public Response post(Employee employee) {
public class Employee {
private String empId;
private String firstName;
private String LastName;
private String gender;
public String getEmpId() {
return empId;
}
public void setEmpId(String empId) {
this.empId = empId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return LastName;
}
public void setLastName(String lastName) {
LastName = lastName;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
JSON以外のContent-Typeにも対応している。- application/json : MediaType.APPLICATION_JSON
- application/xml : MediaType.APPLICATION_XML
- application/x-www-form-urlencoded : MediaType.APPLICATION_FORM_URLENCODED
- application/octet-stream : MediaType.APPLICATION_OCTET_STREAM
- multipart/form-data : MediaType.MULTIPART_FORM_DATA
- text/plain : MediaType.TEXT_PLAIN
- etc..
Javaオブジェクトを様々なContent-Typeに変換してレスポンスを返す
@Producesアノテーションでレスポンスとして返すContent-Typeを指定する。
javax.ws.rs.core.Responseを使って、実際に変換を行ってレスポンスを返す。
EmployeeをJSONにして返す場合は以下のようになる。
@Path("myRestService")
public class MyRestService {
@GET
@Path("{id}")
@Produces({ MediaType.APPLICATION_JSON })
public Response get(@PathParam(name = "id") String id) {
Employee emp = getEmp(id);
return Response.ok(emp, MediaType.APPLICATION_JSON).build();
}
Response.ok()ではHTTPステータスコード200を返す。
OK以外のレスポンスを返す
javax.ws.rs.core.Response.status() を使う。
- status(int status)
- status(Response.Status status)
- status(Response.StatusType status)
- Response.status(404);
- Response.status(500);
- Response.status(Status.FORBIDDEN);
- Response.status(Status.INTERNAL_SERVER_ERROR);
クエリパラメータを扱う
http://ホスト/コンテキストルート/myRestService?param1=value1¶m2=value2という形で、パラメータを指定した場合は、引数を@QueryParamアノテーションで修飾することによって受け取ることができる。
@Path("myRestService")
public class MyRestService {
@GET
public Response get(@QueryParam(value="param1") param1, @QueryParam(value="param2" param2)) {
この方法だと、パラメータ値一つ一つをバラバラに受け取ることになる。
クラスにマッピングする方法もある。
まず、パラメータを受け取るクラスのフィールドに@QueryParamアノテーションをつける。
public class Employee {
@QueryParam("id")
String id;
@QueryParam("firstName")
String firstName;
@QueryParam("lastName");
String lastName;
サービスのメソッドの引数に@Contextアノテーションをつけたcom.sun.jersey.api.core.ResourceContextを指定する。
ResourceContext.getResource()にパラメータを格納するクラスを指定して、インスタンスを得ることができる。
これは@QueryParamだけでなく、@PathParam等にも使える。
@Path("myRestService")
public class MyRestService {
@GET
public Response get(@Context ResourceContext rc)) {
Employee emp = rc.getResource(Employee.class);
このやり方の問題は、引数がResourceContextになってしまって、欲しいパラメータはResourceContextから得ることになってUnit Testがやりにくくなってしまう。まとまった数のパラメータをPOJOで受け取りたいのであれば、POSTを使ってPOJOで受け取る方が良さそう。
0 件のコメント:
コメントを投稿