Upload
others
View
1
Download
0
Embed Size (px)
Citation preview
ดร.ธระยทธ ทองเครอ
ภาควชาวทยาการคอมพวเตอร คณะวทยาศาสตร
มหาวทยาลยขอนแกน
ปฏบตการท 9
REST Web Service Provider
1
JAX-RS API
JAX-RS คอ มาตรฐาน API ในภาษาจาวาทออกแบบสาหรบใชในการพฒนาเวบ
เซอรวสแบบ REST
JAX-RS ใชสวนทเรยกวา annotation ของภาษาจาวาในการกาหนด
Path ในการเรยกใชเวบเซอรวส
HTTP Method
รปแบบของขอมลทรบและสงจากเวบเซอรวส เชน XML, JSON, Text
ปจจบนม API ทเขยนขนตาม JAX-RS คอ Jersey (https://jersey.java.net/)
2
JAX-RS Annotations
@Path
ระบเสนทางหรอชอทใชเขาถง Service ซงจะตอทายชอ domain ใน URI
@Consumes
กาหนดรปแบบขอมล (MIME types) ทผใชจะตองสงมาให Service (input)
@Produces
กาหนดรปแบบขอมล ท Service จะสงผลลพธกลบไปใหผใช (output)
@GET, @POST, @DELETE, @PUT, @HEAD
ระบวธการเรยกใช Service (HTTP method)
มวธ GET วธเดยวทเรยกใชไดดวย Browser สวนวธอนๆ ตองเขยนคาสง หรอ
ใชโปรแกรมทดสอบ เชน SoapUI
3
JAX-RS Annotations
การดงคาทรบจากผเรยกเวบเซอรวส
@PathParam
ดงคาจาก path ของ URL
@QueryParam
ดงคาจาก URL query string (หลงเครองหมาย ?)
@HeaderParam
ดงคาจาก Header
@CookieParam
ดงคาจาก Cookies
4
Hello Service
@Path("/hello")public class Hello {
@GET@Produces("application/xml")public String getXml() {
return "<msg>Hello</msg>";}
}
Request URL: http://localhost:8080/RestService/hello
Response:
<msg>Hello</msg>
ชอ Path เรมตนของเวบเซอรวส
เรยกโดยวธ GET
output มรปแบบเปน XML
ขอความทสงกลบ
ชอ Project ชอ Path ของ
Class
5
การสรางเวบเซอรวสแบบ REST บน Eclipse
สราง Dynamic Web Project ใหม ชอ HelloService
Copy Library ของ Jersey ไวใน WebContent/WEB-INF/lib
สราง package ใหม ภายใต Java Resources/src ชอ com.hello
สรางคลาสใหม ชอ Hello และ implement method
Copy ไฟล web.xml (จากไฟลประกอบแลป) ไปเกบท WebContent/WEB-INF
เพม Project ใหกบ Server และ Start Server
ทดสอบ http://localhost:8080/RestService/rest/hello
6
ไฟล web.xml
<?xml version="1.0" encoding="UTF-8"?><web-app>
<servlet><servlet-name>jersey-servlet</servlet-name><servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class><init-param>
<param-name>jersey.config.server.provider.packages</param-name><param-value>com.hello</param-value>
</init-param></servlet>
<servlet-mapping><servlet-name>jersey-servlet</servlet-name><url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
ระบชอ package ทบรรจคลาส
ทเปนเวบเซอรวส
7
การรบคาจาก URL
@Path("/hello")public class Hello {
@GET@Produces("application/xml")@Path("/{name}") public String getXml(@PathParam("name") String name) {
return "<msg>Hello " + name + "</msg>";}
}
กาหนดรปแบบ
Request URL ให
ตอทายดวยชอ
ระบวาใหนาคา {name} จาก URL
เกบไวในตวแปร name
นาคาในตวแปร name มาสรางเปน output
รปแบบ Request URL: http://localhost:8080/RestService/hello/{name}
ตวอยาง: http://localhost:8080/RestService/hello/John
Response: <msg>Hello John</msg>
8
การกาหนด output หลายรปแบบ
@GET@Produces("application/json")@Path("/json/{name}") public String getJson(@PathParam("name") String name) {
return "{ \"msg\": \"Hello " + name + "\" }";}
@GET@Produces("text/plain")@Path("/text/{name}") public String getText(@PathParam("name") String name) {
return "Hello " + name;}
รปแบบ Request URL: http://localhost:8080/RestService/hello/json/{name}
ตวอยาง: http://localhost:8080/RestService/hello/json/Smith
Response: { "msg": "Hello Smith" }
รปแบบ Request URL: http://localhost:8080/RestService/hello/text/{name}
ตวอยาง: http://localhost:8080/RestService/hello/text/Smith
Response: Hello Smith
9
เวบเซอรวสบวกเลข
@Path("/calculate")public class Calculate {
@GET@Produces("application/json")@Path("/{a}/{b}") public String plus(@PathParam("a") int a, @PathParam("b") int b) {
int result = a + b; return "{ \"result\": \"" + result + "\" }";
}}
plusa: int
b: intJSON result
ไฟล Calculate.java
รปแบบ Request URL: http://localhost:8080/RestService/calculate/{a}/{b}
ตวอยาง: http://localhost:8080/RestService/calculate/5/20
Response: { "result": "25" }
10
การสราง Service รบขอมลแบบ POST
@Path("/calculate")public class Calculate {
@POST@Consumes("application/json")@Produces("application/json")public String plus(String jsonString) {
System.out.println(jsonStr ing);
Object document = Configuration.defaultConfiguration().jsonProvider().parse(jsonString);int a = JsonPath.read(document, "$.a");int b = JsonPath.read(document, "$.b");int result = a + b;
return "{ \"result\": \"" + result + "\" }";}
}
ไฟล Calculate.java
ฟงกชนนไมมการระบ path ดงนน URL
ทเขาถงจะใช path เดยวกบทระบบน class คอ
http://localhost:8080/RestService/calculate
ฟงกชนนจะทางานเมอมการเรยกแบบ POST เทานน
รบและสงขอมลในรปแบบ JSON
รปแบบ Request URL: http://localhost:8080/RestService/calculate/
11
ทดสอบสงขอมล JSON ไปยงเวบเซอรวส
การสงขอมลแบบ POST ไปยงเวบเซอรวสจะตองเขยนโปรแกรม หรอใช SoapUI
ผลลพธจากเวบเซอรวส
ระบ method ระบ URL
ขอมลในทจะสง
ใหเวบเซอรวส
ระบรปแบบ
ขอมลทจะสง
ระบ Path
12
WADL
WADL (Web Application Description Language) คอ เอกสารอธบายการตดตอกบ
เวบเซอรวสแบบ REST ซงอธบายรปแบบ URL ในการสงขอมลมายงเวบเซอรวส
ชนดขอมลทตองสง และรปแบบผลลพธทจะไดรบจากเวบเซอรวส
ผสรางเวบเซอรวสไมตองสราง WADL เอง เพราะเครองมอจะ Generateใหอตโนมต
13
โครงสรางของเอกสาร WADL
<application><doc/>*<grammars/>?<resources base="anyURI">?
<doc/>*<resource path="template" type="anyURI+"?>+
<doc/>*<param/>*( <method/> | <resource/> )+
</resource></resources>
(<method/> | <representation/> | <fault/> | <resource_type/>)*</application>
* => 0 or more? => 0 or 1+ => 1 or more
14
โครงสรางของ Method
<method name="NMTOKEN"? id="ID"? href="anyURI"?>
<doc/>*<request>?
<param>*<representation/>*
</request>
<response>?( <representation/> | <fault/> )*
</response>
</method>* => 0 or more? => 0 or 1+ => 1 or more
15
<application base="http://wadl.dev.java.net/2009/02"><resources base="http://localhost:8080/RestService/"><resource path="/calculate">
<resource path="/{a}/{b}"><param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="a"
style="template" type="xs:int" /><param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="b"
style="template" type="xs:int" /><method id="plus" name="GET">
<response><representation mediaType="application/json" />
</response></method>
</resource></resource>
</resources></application>
ตวอยาง WADL ของเวบเซอรวสบวกเลข
plusa: int
b: intJSON result
URL ของ WADL: http://localhost:8080/RestService/application.wadl
16
Assignment#9
จงสรางเวบเซอรวสใหบรการคานวณคา BMI (Body Mass Index) ซงมสตรดงน
ใหบรการ 2 แบบ ทงแบบ GET และ POST
แบบ GET
รปแบบ Request URL: http://localhost:8080/RestService/bmi/{weight}/{height}
ตวอยาง: http://localhost:8080/RestService/bmi/56/1.73
ตวอยาง Response: { "result": "18.710949" }
แบบ POST
รปแบบ Request URL: http://localhost:8080/RestService/bmi
ตวอยางขอมล: { "weight": "56", "height": "1.73" }
ตวอยาง Response: { "result": "18.710949" }
calculateBMIweight
:float
height:float
JSON
result
การแปลง String เปน Float ใชฟงกชน Float.parseFloat() 17
เวบเซอรวสใหบรการขอมลสนคา
Service ใหบรการ HTTP
Method
URL ในการเรยกเวบเซอรวส
รปแบบตามทกาหนดใน @Path
ขอมลเขา
@Consumes
ขอมลสงกลบ
@Produces
ใหรายการขอมล
สนคา
GET http://localhost:8080/RestService/product - ขอมลสนคา
รปแบบ JSON
ใหขอมลสนคาตาม
รหส
GET http://localhost:8080/RestService/product/{id} - ขอมลสนคา
รปแบบ JSON
เพมขอมลสนคา POST http://localhost:8080/RestService/product ขอมลสนคา
รปแบบ JSON
ขอความ "success"
รปแบบ Text
แกไขขอมลสนคา PUT http://localhost:8080/RestService/product/{id} ขอมลสนคา
รปแบบ JSON
ขอความ "success"
รปแบบ Text
ลบขอมลสนคา DELETE http://localhost:8080/RestService/product/{id} - ขอความ "success"
รปแบบ Text
18
กจกรรม
พจารณาโครงสรางคลาสเวบเซอรวสแบบ REST ทใหบรการขอมลสนคาจาก
เอกสารทแจกให โดยเฉพาะ Annotation ของ Method
HTTP Method
Path ทใช และขอมลทสงมากบ URL
รปแบบการรบ/สงขอมล
19
ฐานขอมลสนคา
ฐานขอมลสนคา มโครงสรางและขอมล ดงน
pid pname pdetail price
1 Centrum วตามนรวมจาก A ถง Zinc 350
2 Caltrate บารงกระดก เสรมวตามนด 760
3 Ester-C วตามนซ 500 mg ไมกดกระเพาะ 500
4 Glucosamine บารงขอตอ ปองกนขอเสอม 120
20
Service ใหรายการขอมลสนคา
ไฟล Product.java
@Path("/product")public class Product {
@GET@Produces("application/json")public String getProduct() {
JsonObjectBuilder root = Json.createObjectBuilder();JsonArrayBuilder productArray = Json.createArrayBuilder();
try {Connection con = connectDB();ResultSet rs = con.createStatement().executeQuery("SELECT * FROM product");
while (rs.next()) {JsonObjectBuilder product = Json.createObjectBuilder();product.add("pid", rs.getInt("pid"));product.add("pname", rs.getString("pname"));product.add("pdetail", rs.getString("pdetail"));product.add("price", rs.getInt("price"));productArray.add(product);
}rs.close();con.close();
} catch(Exception e) {e.getMessage();
}
root.add("products", productArray);return root.build().toString();
}}
รปแบบ Request URL: http://localhost:8080/RestService/product
HTTP Method: GET
ขอมลสงกลบ: รายการสนคารปแบบ JSON
21
ทดสอบการทางาน
22
Service ใหขอมลสนตามรหส
ไฟล Product.java
@GET@Produces("application/json")@Path("/{pid}")public String getProductById(@PathParam("pid") String pid) {
JsonObjectBuilder root = Json.createObjectBuilder();
try {Connection con = connectDB();ResultSet rs = con.createStatement().executeQuery("SELECT * FROM product WHERE pid = " + pid);
if (rs.next()) { root.add("pid", pid);root.add("pname", rs.getString("pname"));root.add("pdetail", rs.getString("pdetail"));root.add("price", rs.getInt("price"));
}rs.close();con.close();
} catch(Exception e) {e.getMessage();
}
return root.build().toString();}
รปแบบ Request URL: http://localhost:8080/RestService/product/{id}
ตวอยาง: http://localhost:8080/RestService/product/2
HTTP Method: GET
ขอมลสงกลบ: ขอมลสนคารปแบบ JSON
23
ทดสอบการทางาน
24
Service ใหบรการเพมขอมลสนคา
ไฟล Product.java
@POST@Consumes("application/json")@Produces("text/plain")public String createProduct(String jsonString) {
System.out.println(jsonString);
Object document = Configuration.defaultConfiguration().jsonProvider().parse(jsonString);String pname = JsonPath.read(document, "$.pname");String pdetail = JsonPath.read(document, "$.pdetail");int price = JsonPath.read(document, "$.price");
try {String sql = "INSERT INTO product (pname, pdetail, price) VALUES ('"
+ pname + "', '" + pdetail + "', " + price + ")";Connection con = connectDB();con.createStatement().executeUpdate(sql);con.close();
} catch(Exception e) {return e.getMessage();
}
return "success";}
รปแบบ Request URL: http://localhost:8080/RestService/product
HTTP Method: POST
ขอมลเขา : ขอมลสนคารปแบบ JSON
ขอมลสงกลบ: ขอความ "success" รปแบบ Text
25
ทดสอบการทางาน
26
Service แกไขขอมลสนคา
ไฟล Product.java
@PUT@Consumes("application/json")@Produces("text/plain")@Path("/{pid}")public String editProduct(@PathParam("pid") String pid, String jsonString) {
Object document = Configuration.defaultConfiguration().jsonProvider().parse(jsonString);String pname = JsonPath.read(document, "$.pname");String pdetail = JsonPath.read(document, "$.pdetail");int price = JsonPath.read(document, "$.price");
try {String sql = "UPDATE product SET pname='" + pname + "', pdetail='" + pdetail
+ "', price=" + price + " WHERE pid = " + pid;Connection con = connectDB();con.createStatement().executeUpdate(sql);con.close();
} catch(Exception e) {return e.getMessage();
}
return "success";}
รปแบบ Request URL: http://localhost:8080/RestService/product/{id}
ตวอยาง: http://localhost:8080/RestService/product/5
HTTP Method: PUT
ขอมลเขา : ขอมลสนคารปแบบ JSON
ขอมลสงกลบ: ขอความ "success" รปแบบ Text
27
ทดสอบการทางาน
28
Service ลบขอมลสนคา
ไฟล Product.java
@DELETE@Path("/{pid}")@Produces("text/plain")public String delete(@PathParam("pid") String pid) {
try {String sql = "DELETE FROM product WHERE pid = " + pid;Connection con = connectDB();con.createStatement().executeUpdate(sql);con.close();
} catch(Exception e) {return e.getMessage();
}
return "success";}
รปแบบ Request URL: http://localhost:8080/RestService/product/{id}
ตวอยาง: http://localhost:8080/RestService/product/5
HTTP Method: DELETE
ขอมลสงกลบ: ขอความ "success" รปแบบ Text
29
ทดสอบการทางาน
30
กจกรรม
ฐานขอมลพนกงาน มโครงสรางและขอมล ดงน
dept_id dept_name
1 ฝายสารสนเทศ
2 ฝายทรพยากรบคคล
3 ฝายบญช
emp_id firstname lastname position dept_id
1 บญม มากเหลอ โปรแกรมเมอร 1
2 สมย สมภาร นกบญช 3
3 บญชวย กาโว ผจดการ 2
4 สมใจ บญหลาย Tester 1
5 ยหวา เรารอน ธรการ 2
ตาราง department
ตาราง employee
31
กจกรรม
จงสรางเวบเซอรวสใหบรการขอมลพนกงาน ซงม Service ดงน
Service ใหบรการ HTTP
Method
URL ในการเรยกเวบเซอรวส
รปแบบตามทกาหนดใน @Path
ขอมลเขา
@Consumes
ขอมลสงกลบ
@Produces
ใหรายการขอมล
พนกงาน
GET http://localhost:8080/RestService/employee - ขอมลพนกงาน
รปแบบ JSON
ใหขอมลพนกงาน
ตามรหส
GET http://localhost:8080/RestService/employee/{id} - ขอมลพนกงาน
รปแบบ JSON
เพมขอมลพนกงาน POST http://localhost:8080/RestService/employee ขอมลพนกงาน
รปแบบ JSON
ขอความ "success"
รปแบบ Text
แกไขขอมล
พนกงาน
PUT http://localhost:8080/RestService/employee/{id} ขอมลพนกงาน
รปแบบ JSON
ขอความ "success"
รปแบบ Text
ลบขอมลพนกงาน DELETE http://localhost:8080/RestService/employee/{id} - ขอความ "success"
รปแบบ Text
32