RESTful Webservice

1,REST和RESTFUL是什麼html

   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。
java

   因爲REST強制全部的操做都必須是stateless的,這就沒有上下文的約束,若是作分佈式,集羣都不須要考慮上下文和會話保持的問題。極大的提升系統的可伸縮性。web

2.SOAP Webservice和RESTful Webservicespring

  WebService是一種可以使應用程序在不一樣的平臺使用不一樣的編程語言進行通信的技術規範,而這種技術規範的實現能夠用不一樣的方法,好比使用基於XML形式的協議(SOAP)進行通信或者是RESTFUL形式的。apache

   既然咱們知道可使用上面的兩種形式進行通信,那麼咱們就須要對上面的兩種形式進行描述,規範化。而這些規範化的工做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規範。json

 

  那麼選擇SOAP Webservice和Restful Webservice的使用,首先須要理解就是SOAP偏向於面向活動,有嚴格的規範和標準,包括安全,事務等各個方面的內容,同時SOAP強調操做方法和操做對象的分離,有WSDL文件規範和XSD文件分別對其定義。而REST強調面向資源,只要咱們要操做的對象能夠抽象爲資源便可以使用REST架構風格。瀏覽器

 

3. Cxf 開發soap webservice 簡單實例:安全

接口和實現類:restful

 

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 本文到此結束,這只是個入門級的簡單實例,更多更復雜功能都是在此基礎上演化而來,跟過更復雜的配置也是以此爲基礎,有興趣能夠繼續挖掘研究。

相關文章
相關標籤/搜索