Refactoring the EarthGrid SOAP API to REST style and implementing it to Metacat
Rest Web Service - JDeveloperade.web.elte.hu/BPMN/WS/Rest Web Service - JDeveloper.pdf · CORBA...
Transcript of Rest Web Service - JDeveloperade.web.elte.hu/BPMN/WS/Rest Web Service - JDeveloper.pdf · CORBA...
CORBA
Java RMI
REST
SOAP Document Style
SOAP RPC Style
RFC-707 A High Level Framework for Network Based Resource Sharing (Remote Procedure Call – Távoli eljáráshívás)
Microsoft DCOM
Web Service történet
„Enterprise Ready”
• Többféle protokollt támogat
• Procedurális (RPC) alapú
• Biztonságos
• SOA-hoz ideális
• Egyszerű megoldásokhoz nehézkes
„Programmer Friendly”
• Csak HTTP-n keresztül
• 4 parancs -> CRUD – Create – létrehozás - POST
– Read – olvasás - GET
– Update – módosítás - PUT
– Delete –törlés - DELETE
• Egyszerű
• Barátságos
• SOA-hoz nem éppen ideális
SOAP vs REST
The Request – HTTP Protocol
GET /about_web_services.html HTTP/1.1 Host: www.elte.hu User-Agent: Mozilla/5.0 Gecko/20100914 Firefox/3.6.10 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 115 Connection: keep-alive Cookie: __utma=4761137.486424683.1273755779.1285256345.1285459361.13;; If-Modified-Since: Sun, 31 Jan 2010 13:35:33 GMT If-None-Match: "1a690fe-40df-f1645340" Cache-Control: max-age=0
HTTP Accept URIs HTTP GET/PUT/POST/DELETE URIs GET/PUT/POST/DELETE
The Response - HTTP Protocol
HTTP/1.1 200 OK Date: Sun, 26 Sep 2010 00:02:25 GMT Server: Apache/2.0.55 (Ubuntu) Connection: Keep-Alive Keep-Alive: timeout=15, max=96 Etag: "1a690fe-40df-f1645340“ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en“> <head> <title>Sabout Web Services </title </head> .... Etc .... </html>
HTTP Error Codes Payload/Body HTTP Error Code
Java JAX-RS & Jersey
• JAX-RS (API)
• Java SE 5.0-el jelent meg
• Kliens és szerver oldalon inplementálható
• Jersey - Oracle/Sun referencia implementáció
• Jersey 1.0 – 1.0.3 = JAX-RS 1.0 Spec
• Jersey 1.1+ = JAX-RS 1.2 Spec
Példa kód – v1 package restproject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
@Path("customer")
public class MySimplePojo {
@GET
@Produces("text/xml")
public String getCustomer() {
//Normál esetben adatbázisból olvas ki, s xml-
ben ad vissza
System.out.println("--- " +
this.getClass().getCanonicalName()
+ ".getCustomer() invoked");
return "<customer>\n"
+ "<id>123</id>\n"
+ "<firstName>Nagy</firstName>\n"
+ "<middleName>István</middleName>\n"
+ "<lastName>Zsolt</lastName>\n"
+ "</customer>\n";
}
/**
* Új vevő létrehozása
* @param Vevő XML reprezentációja - vevő
létrehozás */
@PUT
@Consumes("text/xml")
public void createCustomer(String customerXML) {
//Normál esetben XML-t kap és beírja az adatbázisba
System.out.println("--- " +
this.getClass().getCanonicalName()
+ ".createCustomer() invoked");
System.out.println("customerXML = " + customerXML);
}
@POST
@Consumes("text/xml")
public void updateCustomer(String customerXML) {
//XML-t kap, módosítja az adatbázisban
System.out.println("--- " +
this.getClass().getCanonicalName()
+ ".updateCustomer() invoked");
System.out.println("customerXML = " + customerXML);
}
@DELETE
@Consumes("text/xml")
public void deleteCustomer(String customerXML) {
//XML-t kap, törli a rekordot az adatbázisban
System.out.println("--- " +
this.getClass().getCanonicalName()
+ ".deleteCustomer() invoked");
System.out.println("customerXML = " + customerXML);
}
}
01 <html>
02 <head>
03 <style type="text/css">
04 table {background-color:#F2F2F5;}
05 td {color:#000000; font-family:Arial; padding:8px; background-color:#F2F2F5;}
06 th {font-family:Arial; font-size:12pt; padding:8px; background-color:#CFE0F1;}
07 </style>
08 </head>
09 <body>
10 <table border="0" cellpadding="0" cellspacing="0">
11 <tr>
12 <th>DEPARTMENT_ID</th>
13 <th>DEPARTMENT_NAME</th>
14 </tr>
15 <tbody>
16 <tr> <td>10</td> <td>Administration</td> </tr>
17 <tr> <td>20</td> <td>Marketing</td> </tr>
18 <tr> <td>30</td> <td>Purchasing</td> </tr>
19 <tr> <td>40</td> <td>Human Resources</td> </tr>
20 <tr> <td>50</td> <td>Shipping</td> </tr>
21 <tr> <td>60</td> <td>IT</td> </tr>
22 <tr> <td>70</td> <td>Public Relations</td> </tr>
23 <tr> <td>80</td> <td>Sales</td> </tr>
24 <tr> <td>90</td> <td>Executive</td> </tr>
25 <tr> <td>100</td> <td>Finance</td> </tr>
26 </tbody>
27 </table>
28 </body>
29 </html>
30
31
32
01 <html>
02 <head>
03 <style type="text/css">
04 table {background-color:#F2F2F5;}
05 td {color:#000000; font-family:Arial; padding:8px; background-color:#F2F2F5;}
06 th {font-family:Arial; font-size:12pt; padding:8px; background-color:#CFE0F1;}
07 </style>
08 </head>
09 <body>
10 <table border="0" cellpadding="0" cellspacing="0">
11 <tr>
12 <th>DEPARTMENT_ID</th>
13 <th>DEPARTMENT_NAME</th>
14 </tr>
15 <tbody>
16 <tr> <td>10</td> <td>Administration</td> </tr>
17 <tr> <td>20</td> <td>Marketing</td> </tr>
18 <tr> <td>30</td> <td>Purchasing</td> </tr>
19 <tr> <td>40</td> <td>Human Resources</td> </tr>
20 <tr> <td>50</td> <td>Shipping</td> </tr>
21 <tr> <td>60</td> <td>IT</td> </tr>
22 <tr> <td>70</td> <td>Public Relations</td> </tr>
23 <tr> <td>80</td> <td>Sales</td> </tr>
24 <tr> <td>90</td> <td>Executive</td> </tr>
25 <tr> <td>100</td> <td>Finance</td> </tr>
26 </tbody>
27 </table>
28 </body>
29 </html>
30
31
32
01 <html>
02 <head>
03 <style type="text/css">
04 table {background-color:#F2F2F5;}
05 td {color:#000000; font-family:Arial; padding:8px; background-color:#F2F2F5;}
06 th {font-family:Arial; font-size:12pt; padding:8px; background-color:#CFE0F1;}
07 </style>
08 </head>
09 <body>
10 <table border="0" cellpadding="0" cellspacing="0">
11 <tr>
12 <th>DEPARTMENT_ID</th>
13 <th>DEPARTMENT_NAME</th>
14 </tr>
15 <tbody>
16 <tr> <td>10</td> <td>Administration</td> </tr>
17 <tr> <td>20</td> <td>Marketing</td> </tr>
18 <tr> <td>30</td> <td>Purchasing</td> </tr>
19 <tr> <td>40</td> <td>Human Resources</td> </tr>
20 <tr> <td>50</td> <td>Shipping</td> </tr>
21 <tr> <td>60</td> <td>IT</td> </tr>
22 <tr> <td>70</td> <td>Public Relations</td> </tr>
23 <tr> <td>80</td> <td>Sales</td> </tr>
24 <tr> <td>90</td> <td>Executive</td> </tr>
25 <tr> <td>100</td> <td>Finance</td> </tr>
26 </tbody>
27 </table>
28 </body>
29 </html>
30
31
32
10
Administration
20
Marketing
30
Purchasing
40
Human Resources
50
Shipping
60
IT
70
Public Relations
80
Sales
90
Executive
100
Finance
DEPARTMENT_ID,DEPARTMENT_NAME
10,Administration
20,Marketing
30,Purchasing
40,Human Resources
50,Shipping
60,IT
70,Public Relations
80,Sales
90,Executive
100,Finance
<DEPARTMENTS>
<DEPT><DEPTID>10</DEPTID><NAME>Administration</NAME></DEPT>
<DEPT><DEPTID>20</DEPTID><NAME>Marketing</NAME></DEPT>
<DEPT><DEPTID>30</DEPTID><NAME>Purchasing</NAME></DEPT>
<DEPT><DEPTID>40</DEPTID><NAME>Human Resources</NAME></DEPT>
<DEPT><DEPTID>50</DEPTID><NAME>Shipping</NAME></DEPT>
<DEPT><DEPTID>60</DEPTID><NAME>IT</NAME></DEPT>
<DEPT><DEPTID>70</DEPTID><NAME>Public Relations</NAME></DEPT>
<DEPT><DEPTID>80</DEPTID><NAME>Sales</NAME></DEPT>
<DEPT><DEPTID>90</DEPTID><NAME>Executive</NAME></DEPT>
<DEPT><DEPTID>100</DEPTID><NAME>Finance</NAME></DEPT>
</DEPARTMENTS>
public class DepartmentsResource {
public static String queryDepartmentsSQL() throws SQLException {
Connection jdbcConn =
DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","hr","hr");
String query = "SELECT department_id, department_name FROM departments";
Statement statement = jdbcConn.createStatement();
ResultSet resultSet = statement.executeQuery(query);
String result = "";
while (resultSet.next()) {
result = result + resultSet.getInt(1) + "\n";
result = result + resultSet.getString(2) + "\n";
}
statement.close();
jdbcConn.close();
return result;
}
public static void main(String[] args) throws SQLException {
String result = DepartmentsResource.queryDepartmentsSQL();
System.out.println(result);
}
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Path("/Departments")
public class DepartmentsResource {
public static String queryDepartmentsSQL() throws SQLException {
Connection jdbcConn =
DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","hr","hr");
String query = "SELECT department_id, department_name FROM departments";
Statement statement = jdbcConn.createStatement();
ResultSet resultSet = statement.executeQuery(query);
String result = "";
while (resultSet.next()) {
result = result + resultSet.getInt(1) + "\n";
result = result + resultSet.getString(2) + "\n";
}
statement.close();
jdbcConn.close();
return result;
}
@GET
@Produces("plain/text")
public String getDepartments() throws SQLException {
return DepartmentsResource.queryDepartmentsSQL();
}
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Department {
private int deptId;
private String name;
public Department(int newDeptId, String newName) {
deptId = newDeptId;
name = newName;
}
public void setDeptId(int newDeptId) {
deptId = newDeptId;
}
public int getDeptId() {
return deptId;
}
public void setName(String newName) {
name = newName;
}
public String getName() {
return name;
}
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Path("/Departments")
public class DepartmentsResource {
public static ArrayList<Department> queryDepartmentsSQL() throws SQLException {
Connection jdbcConn =
DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","hr","hr");
String query = "SELECT department_id, department_name FROM departments";
Statement statement = jdbcConn.createStatement();
ResultSet resultSet = statement.executeQuery(query);
ArrayList<Department> departments = new ArrayList<Department>();
while (resultSet.next()) {
Department dept = new Department(resultSet.getInt(1), resultSet.getString(2));
departments.add(dept);
}
statement.close();
jdbcConn.close();
return departments;
}
@GET
@Produces("plain/text")
public String getDepartments() throws SQLException {
String result = "";
for (Department department : DepartmentsResource.queryDepartmentsSQL()) {
result = result + department.getDeptId() + "," + department.getName() + "\n";
}
return result;
}
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Path("/Departments")
public class DepartmentsResource {
public static Department queryDepartmentSQL(int deptId) throws SQLException {
Connection jdbcConn =
DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","hr","hr");
String query = "SELECT department_id, department_name FROM departments "
+ "WHERE department_id = ?";
PreparedStatement statement = jdbcConn.prepareStatement(query);
statement.setInt(1, deptId);
ResultSet resultSet = statement.executeQuery();
Department department = null;
if (resultSet.next())
department = new Department(resultSet.getInt(1), resultSet.getString(2));
statement.close();
jdbcConn.close();
return department;
}
@GET
@Path("/{dept_id}") // /Departments/{dept_id}
@Produces("plain/text")
public String getDepartment(@PathParam("dept_id") int deptId) throws SQLException {
Department department = DepartmentsResource.queryDepartmentSQL(deptId);
return department.getDeptId() + "," + department.getName() + "\n";
}
}
24
25
26
27
28
29
30
31
32
33
34
@GET
@Path("/{dept_id}")
@Produces("plain/text")
public String getDepartment(@PathParam("dept_id") int deptId) throws SQLException {
Department department = DepartmentsResource.queryDepartmentSQL(deptId);
if (department == null)
throw new NotFoundException("Department ID " + deptId + " not found");
return department.getDeptId() + "," + department.getName() + "\n";
}
<DEPARTMENTS>
<DEPT><DEPTID>10</DEPTID><NAME>Administration</NAME></DEPT>
<DEPT><DEPTID>20</DEPTID><NAME>Marketing</NAME></DEPT>
<DEPT><DEPTID>30</DEPTID><NAME>Purchasing</NAME></DEPT>
<DEPT><DEPTID>40</DEPTID><NAME>Human Resources</NAME></DEPT>
<DEPT><DEPTID>50</DEPTID><NAME>Shipping</NAME></DEPT>
<DEPT><DEPTID>60</DEPTID><NAME>IT</NAME></DEPT>
<DEPT><DEPTID>70</DEPTID><NAME>Public Relations</NAME></DEPT>
<DEPT><DEPTID>80</DEPTID><NAME>Sales</NAME></DEPT>
<DEPT><DEPTID>90</DEPTID><NAME>Executive</NAME></DEPT>
<DEPT><DEPTID>100</DEPTID><NAME>Finance</NAME></DEPT>
</DEPARTMENTS>
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = { "deptId", "name" })
@XmlRootElement(name = "DEPT")
public class Department {
@XmlElement(name = "DEPTID", required = true)
private int deptId;
@XmlElement(name = "NAME", required = true)
private String name;
public Department() { } // default no-arg constructor required for JAXB
public Department(int newDeptId, String newName) {
deptId = newDeptId;
name = newName;
}
public void setDeptId(int newDeptId) { deptId = newDeptId; }
public int getDeptId() { return deptId; }
public void setName(String newName) { name = newName; }
public String getName() { return name; }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@GET
// @Path("/Departments")
@Produces("plain/text")
public String getDepartments() throws SQLException {
String result = "";
for (Department department : DepartmentResources.queryDepartmentsSQL()) {
result = result + department.getDeptId() + "," + department.getName() + "\n";
}
return result;
}
@GET
@Path("/{dept_id}") // /Departments/{dept_id}
@Produces("plain/text")
public String getDepartment(@PathParam("dept_id") int deptId) throws SQLException {
Department department = DepartmentResources.queryDepartmentSQL(deptId);
if (department == null)
throw new NotFoundException("Department ID " + deptId + " not found");
return department.getDeptId() + "," + department.getName() + "\n";
}
@GET
@Path("/{dept_id}") // /Departments/{dept_id}
@Produces("application/xml")
public Department getDepartmentXML(@PathParam("dept_id") int deptId) throws SQLException
Department department = DepartmentResources.queryDepartmentSQL(deptId);
if (department == null)
throw new NotFoundException("Department ID " + deptId + " not found");
return department;
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@GET
// @Path("/Departments")
@Produces("plain/text")
public String getDepartments() throws SQLException {
String result = "";
for (Department department : DepartmentsResource.queryDepartmentsSQL()) {
result = result + department.getDeptId() + "," + department.getName() + "\n";
}
return result;
}
@GET
@Path("/{dept_id}") // /Departments/{dept_id}
@Produces("plain/text")
public String getDepartment(@PathParam("dept_id") int deptId) throws SQLException {
Department department = DepartmentsResource.queryDepartmentSQL(deptId);
if (department == null)
throw new NotFoundException("Department ID " + deptId + " not found");
return department.getDeptId() + "," + department.getName() + "\n";
}
@GET
@Path("/{dept_id}") // /Departments/{dept_id}
@Produces("application/xml")
public Department getDepartmentXML(@PathParam("dept_id") int deptId) throws SQLException
Department department = DepartmentsResource.queryDepartmentSQL(deptId);
if (department == null)
throw new NotFoundException("Department ID " + deptId + " not found");
return department;
}
<DEPARTMENTS>
<DEPT><DEPTID>10</DEPTID><NAME>Administration</NAME></DEPT>
<DEPT><DEPTID>20</DEPTID><NAME>Marketing</NAME></DEPT>
<DEPT><DEPTID>30</DEPTID><NAME>Purchasing</NAME></DEPT>
<DEPT><DEPTID>40</DEPTID><NAME>Human Resources</NAME></DEPT>
<DEPT><DEPTID>50</DEPTID><NAME>Shipping</NAME></DEPT>
<DEPT><DEPTID>60</DEPTID><NAME>IT</NAME></DEPT>
<DEPT><DEPTID>70</DEPTID><NAME>Public Relations</NAME></DEPT>
<DEPT><DEPTID>80</DEPTID><NAME>Sales</NAME></DEPT>
<DEPT><DEPTID>90</DEPTID><NAME>Executive</NAME></DEPT>
<DEPT><DEPTID>100</DEPTID><NAME>Finance</NAME></DEPT>
</DEPARTMENTS>
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = { "departments" })
@XmlRootElement(name = "DEPARTMENTS")
public class Departments {
@XmlElement(name = "DEPT", required = true)
protected List<Department> departments;
public List<Department> getDepartments() {
if (departments == null) {
departments = new ArrayList<Department>();
}
return this.departments;
}
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public static Departments queryDepartmentsSQL() throws SQLException {
Connection jdbcConn =
DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:home","hr","hr");
String query = "SELECT department_id, department_name FROM departments";
Statement statement = jdbcConn.createStatement();
ResultSet resultSet = statement.executeQuery(query);
Departments departments = new Departments();
List<Department> departmentList = departments.getDepartments();
while (resultSet.next()) {
Department dept = new Department(resultSet.getInt(1), resultSet.getString(2));
departmentList.add(dept);
}
statement.close();
jdbcConn.close();
return departments;
}
@GET
@Produces("application/xml")
public Departments getDepartmentsXML() throws SQLException {
return DepartmentsResource.queryDepartmentsSQL();
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public static void insertDepartmentSQL(int deptId, String name)
throws SQLException {
Connection jdbcConn =
DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","hr","hr");
String insert = "INSERT INTO departments (department_id, department_name) "
+ "VALUES (?, ?)";
PreparedStatement statement = jdbcConn.prepareStatement(insert);
statement.setInt(1, deptId);
statement.setString(2, name);
boolean result = statement.execute();
jdbcConn.commit();
statement.close();
jdbcConn.close();
}
@POST
@Path("/{dept_id}")
public void insertDepartment(@PathParam("dept_id") int deptId
,@FormParam("name") String name)
throws SQLException {
DepartmentsResource.insertDepartmentSQL(deptId, name);
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public static void updateDepartmentSQL(int deptId, String name)
throws SQLException {
Connection jdbcConn =
DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","hr","hr");
String update = "UPDATE departments SET department_name = ? "
+ "WHERE department_id = ?";
PreparedStatement statement = jdbcConn.prepareStatement(update);
statement.setString(1, name);
statement.setInt(2, deptId);
boolean result = statement.execute();
jdbcConn.commit();
statement.close();
jdbcConn.close();
}
@PUT
@Path("/{dept_id}")
public void updateDepartment(@PathParam("dept_id") int deptId
,@FormParam("name") String name)
throws SQLException {
DepartmentsResource.updateDepartmentSQL(deptId, name);
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static void deleteDepartmentSQL(int deptId)
throws SQLException {
Connection jdbcConn =
DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","hr","hr");
String delete = "DELETE departments WHERE department_id = ?";
PreparedStatement statement = jdbcConn.prepareStatement(delete);
statement.setInt(1, deptId);
boolean result = statement.execute();
jdbcConn.commit();
statement.close();
jdbcConn.close();
}
@DELETE
@Path("/{dept_id}")
public void deleteDepartment(@PathParam("dept_id") int deptId)
throws SQLException {
DepartmentsResource.deleteDepartmentSQL(deptId);
}
Irodalom
• Chris Muir: JDeveloper 11g's REST web services, SAGE Computing Services http://one-size-doesnt-fit-all.blogspot.com,
www.sagecomputing.com.au