REST是的Representational State Transfer縮寫,中文意思是表象化狀態轉換。維基百科上給出REST的宗旨是:REST 從資源的角度來觀察整個網絡,分佈在各處的資源由URI確定,而客戶端的應用通過URI來獲取資源的表形。獲得這些表形致使這些應用程序轉變了其狀態。隨着不斷獲取資源的表形,客戶端應用不斷地在轉變着其狀態,所謂表形化的狀態轉變(Representational State Transfer)。
REST是基於HTTP動詞和標識資源的唯一的URI的,我們知道HTTP動詞有GET,POST,PUT和DELETE,這也就對應我們常說的CRUD(create, Read, Update and Delete)。
POST: create
GET: read
PUT: update
DELETE: delete
REST的要求:
- 客戶端和服務器結構
- 連接協議具有無狀態性
- 能夠利用Cache機制增進性能
- 層次化的系統
- Code On Demand - Javascript
Salary.java代碼:
package cn.edu.xidian;
public class Salary {
public int getSalary(String name) {
if ( name.equals("zhangsan") ) {
return 3000;
}
else if ( name.equals("lisi") ) {
return 4000;
}
else
return 5000;
}
}
public class Salary {
public int getSalary(String name) {
if ( name.equals("zhangsan") ) {
return 3000;
}
else if ( name.equals("lisi") ) {
return 4000;
}
else
return 5000;
}
}
使用axis2 service archiver發佈成爲web service,具體如何發佈,參考:使用Eclipse+Axis2構建Web Service應用(http://panpan.blog.51cto.com/489034/119204),服務名稱是SalaryService。
在瀏覽器輸入:http://localhost:8080/axis2/services/SalaryService/getSalary?name=zhangsan
即可看到服務返回信息:
<ns:getSalaryResponse>
<ns:return>3000</ns:return>
</ns:getSalaryResponse>
<ns:return>3000</ns:return>
</ns:getSalaryResponse>
寫客戶端代碼,調用剛發佈的SalaryService,代碼如下。
RESTClient.java代碼如下:
package cn.edu.xidian;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import javax.xml.namespace.QName;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
public class RESTClient {
private static String toEpr = "http://localhost:8080/axis2/services/SalaryService";
public static void main(String[] args) throws AxisFault {
Options options = new Options();
options.setTo(new EndpointReference(toEpr));
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
options.setProperty(Constants.Configuration.ENABLE_REST, Constants.VALUE_TRUE);
ServiceClient sender = new ServiceClient();
sender.setOptions(options);
OMElement result = sender.sendReceive(getPayload());
try {
XMLStreamWriter writer = XMLOutputFactory.newInstance()
.createXMLStreamWriter(System.out);
result.serialize(writer);
writer.flush();
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (FactoryConfigurationError e) {
e.printStackTrace();
}
}
private static OMElement getPayload() {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://xidian.edu.cn", "xsd");
OMElement method = fac.createOMElement("getSalary", omNs);
OMElement value = fac.createOMElement("name", omNs);
value.addChild(fac.createOMText(value, "lisi"));
method.addChild(value);
return method;
}
}
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import javax.xml.namespace.QName;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
public class RESTClient {
private static String toEpr = "http://localhost:8080/axis2/services/SalaryService";
public static void main(String[] args) throws AxisFault {
Options options = new Options();
options.setTo(new EndpointReference(toEpr));
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
options.setProperty(Constants.Configuration.ENABLE_REST, Constants.VALUE_TRUE);
ServiceClient sender = new ServiceClient();
sender.setOptions(options);
OMElement result = sender.sendReceive(getPayload());
try {
XMLStreamWriter writer = XMLOutputFactory.newInstance()
.createXMLStreamWriter(System.out);
result.serialize(writer);
writer.flush();
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (FactoryConfigurationError e) {
e.printStackTrace();
}
}
private static OMElement getPayload() {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://xidian.edu.cn", "xsd");
OMElement method = fac.createOMElement("getSalary", omNs);
OMElement value = fac.createOMElement("name", omNs);
value.addChild(fac.createOMText(value, "lisi"));
method.addChild(value);
return method;
}
}
運行這段代碼,結果如下:
<ns:getSalaryResponse xmlns:ns="http://xidian.edu.cn"><ns:return>4000</ns:return></ns:getSalaryResponse>
注意:客戶端REST方式調用服務跟普通服務的唯一區別就是這一句話:
options.setProperty(Constants.Configuration.ENABLE_REST, Constants.VALUE_TRUE);設置REST調用方式。
REST有以下優點:
- 可以利用緩存Cache來提高響應速度
- 通訊本身的無狀態性可以讓不同的服務器的處理一系列請求中的不同請求,提高服務器的擴展性
- 瀏覽器即可作爲客戶端,簡化軟件需求
- 相對與其他疊加在HTTP協議之上的機制,REST的軟件依賴性更小
- 不需要額外的資源發現機制
- 在軟件技術演進中的長期的兼容性更好