サービスのパスの設定
@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) { } }この場合、同じURL
http://ホスト/コンテキストルート/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 件のコメント:
コメントを投稿