[Java] เขียน RESTful Web Service ด้วย Jersey

Web Service คือ เว็บที่ทำหน้าที่ให้ข้อมูลไปยังอีกเว็บหนึ่ง

Restful Web Service เป็น web services ประเภทหนึ่งที่ lightweight และไม่ยุ่งยาก ใช้ port http ในการแลกเปลี่ยนข้อมูล (GET/POST) คล้ายๆกับเรา submit form ใน html ปกติเลย

Data ที่ใช้รับ-ส่งระหว่าง server - client ก็ขึ้นอยู่กับตกลงว่าจะกำหนด parameters แบบไหน return เป็นอะไร ซึ่งโดยทั่วไปมักจะใช้ JSON ในการรับส่งครับ (ตัวอย่างจะทำแค่ plain text จะได้ไม่งงกับ library ที่ไม่เกี่ยวข้องกับ rest)

ผู้อ่านบางคนอาจจะยังไม่คุ้นเคยกับ Web Service ลืมคำนี้ไปก่อนก็ได้ ก็เขียน Method ตามปกติ เสร็จแล้วก็เติม config บางอย่างเพื่อบอกให้มันเป็น Web Service แค่นั้นเองครับ


เอาล่ะ มาส่วนของ coding กัน

เนื่องจากเป็น "Web" ก็ต้องเตรียม application server ให้เรียบร้อยซะก่อน ในที่นี้ผมใช้เป็น WildFly 9 ครับ

library ที่จำเป็นต้องใช้ก็ตามนี้เลย
  • jersey-servlet 1.19
    ณ ตอนนี้ มี 2 versions โดยสังเกตความแตกต่างได้จาก package 1.x เป็นของ com.sun.jersey ส่วน 2.x เป็นของ org.glassfish.jersey ในที่นี้เป็นวิธีการของ version 1.19 ซึ่ง library และ config จะดูง่ายกว่า

เพิ่ม config ใน web.xml
 <servlet>
  <servlet-name>jersey-serlvet</servlet-name>
  <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
  <init-param>
   <param-name>com.sun.jersey.config.property.packages</param-name>
   <param-value>th.in.lordgift.RestJersey1</param-value><!-- replace value with your package name-->
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
  <servlet-name>jersey-serlvet</servlet-name>
  <url-pattern>/webapi/*</url-pattern><!-- pattern for use jersey-->
 </servlet-mapping>


import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;

@Path("Services")
public class Services {

    @GET
    @Path("getIt")
    @Produces(MediaType.TEXT_PLAIN)
    public String getIt() {
        return "Got it!";
    }
    
    @GET
    @Path("getQueryParam")
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    @Produces(MediaType.TEXT_PLAIN)
    public String getQueryParam(@QueryParam("param") String param) {
        return "Got QueryParam="+param+"!";
    }
    
    @POST
    @Path("getFormParam")
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    @Produces(MediaType.TEXT_PLAIN)
    public String getFormParam(@FormParam("param") String param) {
        return "Got FormParam="+param+"!";
    }
    
}

https://github.com/lordgift/Restful-Jersey
Annotation ที่เราจะเอามาใช้สำหรับทำ Web Service
  • @GET@POST ใช้กำหนดวิธีการเรียก method 
  • @Path ใช้กำหนด url สำหรับเข้าใช้งาน
  • @Produces ใช้กำหนด mediatype ของ response
  • @Consumes ใช้กำหนด mediatype ของ request
โดยถ้าเรียกแบบ @GET อาจไม่ต้องกำหนด @Consumes ก็ได้เพราะว่าส่งมาได้แบบเดียวอยู่แล้ว คือเป็น parameter ที่ต่อด้านหลัง URL
  • @GET จะต้องกำหนด parameter ให้เป็น @QueryParam
  • @POST จะต้องกำหนดเป็น @FormParam
ไม่สามารถใช้สลับกันได้

และ annotation ที่เกี่ยวข้องไม่ได้มีเพียงเท่านี้ ยังมีตัวอื่นๆ อีกให้เลือกใช้อย่างเหมาะสม เช่น @PUT @DELETE @PathParam เป็นต้น


มาถึงส่วนของการทดสอบ

ขอดึงกลับไปเล่าถึง SOAP Web Service ซะหน่อย SOAP จะใช้ XML ที่รวมเอาข้อมูล, datatype ต่างๆ แพ็ครวมกันแล้วรับ-ส่งกัน เป็นรูปแบบการส่งข้อมูลซึ่งมีชื่อเฉพาะว่า WSDL ซึ่งจะเป็นของสำคัญสำหรับทั้ง Server และ Client 

WADL ใน Rest นั้นจะคล้ายกับ WSDL อยู่เพราะเป็น XML เหมือนกัน แต่ต่างกันตรงที่ Rest นั้นไม่ได้เอา WADL มาใช้สื่อสารกันระหว่างโปรแกรมเลย แต่เราจะใช้ประโยชน์มันโดยการเอามาทดสอบ web service ที่เราเขียนขึ้น

Rest Web Service ที่เราเขียนขึ้นก่อนหน้านี้ เอามาเช็คดู WADL กันก่อนว่าเรียกได้จริงไหม ?

http://localhost:8080/RestJersey1/webapi/application.wadl?detail=true

ถ้าต้องการทดสอบเรียก method ผ่าน URL (เสมือนเป็น client) ก็ทำได้ผ่าน
ใส่ URL เข้าไปตามด้วย

  • RestJersey1 เป็นชื่อ project
  • webapi เป็น pattern ที่เรากำหนดไว้ใน web.xml
  • Service เป็น Path ที่เราตั้งไว้ที่ class
  • getIt เป็น Path ที่เราตั้งไว้ที่ method (เปลี่ยนให้ตรงกับ method ที่จะเรียก)

http://localhost:8080/RestJersey1/webapi/Services/getIt

ถึงตรงนี้ เราก็บอกใครต่อใครได้แล้วว่า เขียน rest webservice เป็นแล้วนะ :D

ref:
http://www.mkyong.com/webservices/jax-rs/restful-java-client-with-jersey-client/
http://www.rawitat.com/2007/10/08/79/
http://java-thai-talk.blogspot.com/2012/02/restful-webservices-with-java-jersey.html

Facebook Comment

Popular post of 7 days

[Java] ความแตกต่างระหว่าง Overloading กับ Overriding

ลืมรหัสปลดล็อค Android เข้าเครื่องไม่ได้ มีทางออกครับ

[Android] เปิดเครื่องไม่ได้ โลโก้ค้าง (Boot Loop)