1,REST和RESTFUL是什么?
REST ( REpresentational State Transfer ),State Transfer 為 "狀態傳輸" 或 "狀態轉移 ",Representational 中文有人翻譯為"表征"、"具象",合起來就是 "表征狀態傳輸" 或 "具象狀態傳輸" 或 "表述性狀態轉移"
REST是一種架構風格,REST 指的是一組架構約束條件和原則。滿足這些約束條件和原則的應用程序或設計就是 RESTful。其核心是面向資源,REST專門針對網絡應用設計和開發方式,以降低開發的復雜性,提高系統的可伸縮性。
REST提出設計概念和准則為:
1.網絡上的所有事物都可以被抽象為資源(resource)
2.每一個資源都有唯一的資源標識(resource identifier),對資源的操作不會改變這些標識
3.所有的操作都是無狀態的
REST簡化開發,其架構遵循CRUD原則,該原則告訴我們對於資源(包括網絡資源)只需要四種行為:創建,獲取,更新和刪除就可以完成相關的操作和處理。您可以通過統一資源標識符(Universal Resource Identifier,URI)來識別和定位資源,並且針對這些資源而執行的操作是通過 HTTP 規范定義的。其核心操作只有GET,PUT,POST,DELETE。
由於REST強制所有的操作都必須是stateless的,這就沒有上下文的約束,如果做分布式,集群都不需要考慮上下文和會話保持的問題。極大的提高系統的可伸縮性。
2.SOAP Webservice和RESTful Webservice
WebService是一種能夠使應用程序在不同的平台使用不同的編程語言進行通訊的技術規范,而這種技術規范的實現可以用不同的方法,比如使用基於XML形式的協議(SOAP)進行通訊或者是RESTFUL形式的。
既然我們知道可以使用上面的兩種形式進行通訊,那么我們就需要對上面的兩種形式進行描述,規范化。而這些規范化的工作sun已經幫我們完成了,也就是JAX-WS,JAX-RS這兩種規范.
JAX-WS是一種規范,而在jdk1.6之后就有了自帶的實現,但是這種實現是比較簡單的,基本上就只能夠傳遞SOAP協議格式的消息。這就是為什么我們可以在沒有axis2或者CXF的情況下開發WebService。 這時候我們就會想了,如果我們需要其他的服務,比如我想讓JAX-WS與Spring集成。這種需求前輩都已經考慮過了,也實現了,不需要我們在去實現這樣的需求。而這種需求的解決方案在JAX-WS中是采用框架。而JAX-WS的框架就有AXIS2和CXF。框架使用起來可能會更加靈活,功能更加強大。比如CXF不僅僅實現JAX-WS,也實現了JAX-RS規范。

那么選擇SOAP Webservice和Restful Webservice的使用,首先需要理解就是SOAP偏向於面向活動,有嚴格的規范和標准,包括安全,事務等各個方面的內容,同時SOAP強調操作方法和操作對象的分離,有WSDL文件規范和XSD文件分別對其定義。而REST強調面向資源,只要我們要操作的對象可以抽象為資源即可以使用REST架構風格。
3. Cxf 開發soap webservice 簡單實例:
接口和實現類:
package demo2;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface HiGirl {
String sayHi(@WebParam(name = "text") String text);
}
package demo2;
import javax.jws.WebParam;
public class HiGirlImpl implements HiGirl {
@Override
public String sayHi(@WebParam(name = "text") String text) {
return "hi," + text;
}
}
spring配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:cxf="http://cxf.apache.org/core"
xmlns:wsa="http://cxf.apache.org/ws/addressing"
xsi:schemaLocation="
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.1.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<!-- 以下三個文件在 cxf-2.7.18.jar 中定義 ,主要功能室CXF和Spring集成時,注冊一些Process Bean -->
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<!-- publish -->
<jaxws:endpoint id="hiGirl" implementor="demo2.HiGirlImpl"
address="/hiGirl" />
<!-- client 如果是通過web的方式訪問,可以不用配置 該client,但是需要配置web.xml-->
<bean id="client" class="demo2.HiGirl" factory-bean="clientFactory"
factory-method="create"></bean>
<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="demo2.HiGirl"></property>
<property name="address" value="http://localhost:8080/webservice/hiGirl"></property>
</bean>
</beans>
web.xml 配置:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>CXFwebservice</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:demo2/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>CxfServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CxfServlet</servlet-name> <url-pattern>/webservice/*</url-pattern> </servlet-mapping> <filter> <filter-name>encoding</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encoding</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping> <filter-mapping> <filter-name>encoding</filter-name> <url-pattern>*.do</url-pattern> </filter-mapping> </web-app>
客戶端調用:
package demo2;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class WebServiceApp {
public static void main(String[] args) {
ApplicationContext factory = new ClassPathXmlApplicationContext("demo2/applicationContext.xml");
HiGirl client = (HiGirl) factory.getBean("client");
System.out.println(client.sayHi("bitch!"));
}
}
4,CXF開發 restful webservice 簡單實例:
package demo;
import java.util.LinkedList;
import java.util.List;
public class Config {
public static List<Person> persons;
static {
persons = new LinkedList<Person>();
Person person = new Person();
person.setId("6272058");
person.setName("劉德華");
persons.add(person);
}
}
package demo;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "Person")
public class Person {
private String name;
private String id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
package demo;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
@Path("/PersonService")
//@Produces注釋用來指定將要返回給client端的數據標識類型(MIME)。
//@Produces可以作為class注釋,也可以作為方法注釋,方法的@Produces注釋將會覆蓋class的注釋。
//覆蓋的意思是假如方法聲明了自己的Produce,那么以方法的為准,class的僅供參考
@Produces({ "application/json", "application/xml" })
public class PersonService {
@GET
@Path("/getPerson/{dd}")
@Produces(MediaType.APPLICATION_XML)
public Person getPerson(@PathParam("dd") String id) {
if (id != null && id.length() > 0) {
for (Person pp : Config.persons) {
if(id.equals(pp.getId())){
return pp;
}
}
Person result = new Person();
result.setId(id);
return result;
} else {
return new Person();
}
}
@POST
@Path("/regPerson")
//@Consumes與@Produces相反,用來指定可以接受client發送過來的MIME類型,
//同樣可以用於class或者method,也可以指定多個MIME類型,一般用於@PUT,@POST。
@Consumes({ "application/json", "application/xml" })
public Response regPerson(Person person) {
if (Config.persons.contains(person)) {
return Response.status(Status.BAD_REQUEST).build();
} else {
Config.persons.add(person);
return Response.ok(person).build();
}
}
@DELETE
@Path("/delPerson")
@Consumes({ "application/json", "application/xml" })
public Response delPerson(@QueryParam("id") String id) {
Person person = new Person();
person.setId(id);
if (Config.persons.contains(person)) {
return Response.status(Status.BAD_REQUEST).build();
} else {
Config.persons.remove(person);
return Response.ok(person).build();
}
}
@PUT
@Path("/updatePerson")
@Consumes({ "application/json", "application/xml" })
public Response updatePerson(Person person) {
if (Config.persons.contains(person)) {
return Response.status(Status.BAD_REQUEST).build();
} else {
for (Person pp : Config.persons) {
if (pp.equals(person)) {
pp.setName(person.getName());
}
}
return Response.ok(person).build();
}
}
}
spring配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="personService" class="demo.PersonService" />
<jaxrs:server id="rs_server" address="/rs">
<jaxrs:serviceBeans>
<ref bean="personService"/>
</jaxrs:serviceBeans>
</jaxrs:server>
</beans>
web.xml 配置:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>CxfRestWebservice</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:demo/beans.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>cxfservlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>cxfservlet</servlet-name> <url-pattern>/webservice/*</url-pattern> </servlet-mapping> </web-app>
通過瀏覽器訪問:注意URL和配置文件的及參數的對應關系


OK 本文到此結束,這只是個入門級的簡單實例,更多更復雜功能都是在此基礎上演化而來,跟過更復雜的配置也是以此為基礎,有興趣可以繼續挖掘研究。
