[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 แค่นั้นเองครับ
library ที่จำเป็นต้องใช้ก็ตามนี้เลย
Annotation ที่เราจะเอามาใช้สำหรับทำ Web Service
และ annotation ที่เกี่ยวข้องไม่ได้มีเพียงเท่านี้ ยังมีตัวอื่นๆ อีกให้เลือกใช้อย่างเหมาะสม เช่น @PUT @DELETE @PathParam เป็นต้น
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 เข้าไปตามด้วย
http://localhost:8080/RestJersey1/webapi/Services/getIt
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
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 |
@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 และ ClientWADL ใน 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
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