WebService顧名思義就是web服務,web服務主要有兩種,一種是基於soap類型的服務,一種是基於rest類型的服務,其中soap類型的服務有兩種版本,一種是soap1.1版本,一種是soap1.2版本,soap服務類型的數據是xml數據格式的,而rest服務的數據類型是json格式的。html
wsdl(網絡服務描述語言)是Web Service的描述語言,也就是說wsdl文件是soap的使用說明書。在學習soap以前,認識WSDL是很是有必要的,只有能看懂WSDL文件,咱們才能夠去調用soap類型的Web服務,下面是一個很是簡單的wsdl文件。java
接下來咱們利用Java發佈一個soap類型的服務,在Java JDK1.6版本之後,咱們能夠經過Endpoint
來發佈一個soap服務,代碼以下:web
1 package com.skd.service; 2 3 import javax.jws.WebMethod; 4 import javax.jws.WebParam; 5 import javax.jws.WebResult; 6 import javax.jws.WebService; 7 import javax.xml.ws.Endpoint; 8 9 //必需要加註釋 10 @WebService 11 public class Hello { 12 public String sayHello(String name){ 13 return "hello " + name; 14 } 15 public static void main(String[] args) { 16 //服務的地址 17 String address = "http://localhost:8080/hello"; 18 Hello implementor = new Hello(); 19 //發佈服務,第一個參數是服務的地址,第二個參數是發佈出去服務的方法 20 Endpoint.publish(address, implementor); 21 } 22 }
代碼以下:spring
1 package com.skd.service; 2 3 import javax.jws.WebMethod; 4 import javax.jws.WebParam; 5 import javax.jws.WebResult; 6 import javax.jws.WebService; 7 import javax.xml.ws.Endpoint; 8 9 10 @WebService(targetNamespace="http://com.wpx",serviceName="WPXService") 11 public class Hello { 12 //提供一個合法的web方法 13 @WebMethod(operationName="myMethod") 14 @WebResult(name="myRet") 15 public String sayHello( 16 @WebParam(name="name") 17 String name){ 18 return "hello " + name; 19 } 20 //排除當前方法 21 @WebMethod(exclude=true) 22 public String sayHi(String name){ 23 return "hi " + name; 24 } 25 public static void main(String[] args) { 26 String address = "http://localhost:8080/hello";//服務的發佈地址 27 Hello implementor = new Hello();//提供服務的實例 28 Endpoint.publish(address, implementor);//發佈服務 29 } 30 }
wsimport原理是根據wsdl文件生成本地代理。apache
1 wsimport -s ./ http://localhost:8080/hello?wsdl 2 //若是指定輸出的包名代碼爲: 3 wsimport -s ./ -p com.skd.client.wsimport http://localhost:8080/hello?wsdl 4 //打jar包的命令:(將當前的com文件夾打成ws.jar) 5 jar cvf ws.jar ./com
1 import wpx.com.Hello; 2 import wpx.com.WPXService; 3 4 public class APP { 5 public static void main(String[] args) { 6 WPXService service=new WPXService(); 7 Hello h=service.getHelloPort(); 8 String result=h.myMethod("wpx"); 9 System.out.println(result); 10 } 11 12 }
總結:wsimport調用web服務的java代碼是有規律的,總共分爲三步:json
1 import java.io.InputStream; 2 import java.io.OutputStream; 3 import java.net.HttpURLConnection; 4 import java.net.URL; 5 6 /** 7 * 使用UrlConnection方式調用WebService服務 8 * 9 */ 10 public class APP { 11 public static void main(String[] args) throws Exception { 12 // WebService服務的地址 13 URL url = new URL("http://localhost:8080/hello"); 14 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 15 //是否具備輸入參數 16 conn.setDoInput(true); 17 //是否輸出輸入參數 18 conn.setDoOutput(true); 19 //發POST請求 20 conn.setRequestMethod("POST"); 21 //設置請求頭(注意必定是xml格式) 22 conn.setRequestProperty("content-type", "text/xml;charset=utf-8"); 23 24 // 構造請求體,符合SOAP規範(最重要的) 25 String requestBody = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:q0=\"http://com.wpx\" " 26 + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" 27 + "<soapenv:Body>" 28 + "<q0:myMethod>" 29 + "<name>wpx</name>" 30 + "</q0:myMethod>" 31 + "</soapenv:Body>" 32 + "</soapenv:Envelope>"; 33 34 //得到一個輸出流 35 OutputStream out = conn.getOutputStream(); 36 out.write(requestBody.getBytes()); 37 38 //得到服務端響應狀態碼 39 int code = conn.getResponseCode(); 40 StringBuffer sb = new StringBuffer(); 41 if(code == 200){ 42 //得到一個輸入流,讀取服務端響應的數據 43 InputStream is = conn.getInputStream(); 44 byte[] b = new byte[1024]; 45 int len = 0; 46 47 while((len = is.read(b)) != -1){ 48 String s = new String(b,0,len,"utf-8"); 49 sb.append(s); 50 } 51 is.close(); 52 } 53 54 out.close(); 55 System.out.println("服務端響應數據爲:"+sb.toString()); 56 57 } 58 }
在前兩種方法中,第一種方案生成的代碼很是多,第二種方案服務器返回的數據須要咱們來解析,都不是很是的完美,咱們可使用第三種方法,生成的代碼不是很是的多,對於服務器返回的數據也不須要咱們本身來解析,過程以下。api
1 import java.net.MalformedURLException; 2 import java.net.URL; 3 4 import javax.xml.namespace.QName; 5 import javax.xml.ws.Service; 6 public class APP { 7 public static void main(String[] args) throws Exception { 8 String wsdlUrl = "http://localhost:8080/hello?wsdl"; 9 //QName,第一個參數是服務的命名空間,第二個參數是服務的名稱 10 Service service = Service.create(new URL(wsdlUrl), new QName("http://com.wpx", "WPXService")); 11 //QName,第一個參數是服務的命名空間,第二個參數是獲得接口的Port 12 Hello port = service.getPort(new QName("http://com.wpx","HelloPort"), Hello.class); 13 String ret = port.myMethod("wpx"); 14 System.out.println(ret); 15 } 16 }
1 QName qname = new QName("http://...", 2 "Service"); 3 Service service = new Service(Url,qname); 4 ServiceSoap sop =service.getServiceSoap(); 5 String res = sop.docUpload(bs, clntnum+"_"+strformat.format(date)+"_"+i + ".jpg"); 6 res = res.replace("\\", "/");
注:QName跨域
api:https://www.oschina.net/uploads/doc/flex-doc-3.2/QName.html服務器
1.來歷:qname是qualified name 的簡寫
2.構成:由名字空間(namespace)前綴(prefix)以及冒號(:),還有一個元素名稱構成
3.舉例:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
version="1.0">
<xsl:template match="foo">
<hr/>
</xsl:template>
</xsl:stylesheet>
xsl是名字空間前綴,template是元素名稱,xsl:template 就是一個qname
4.總結:qname無非是有着特定格式的xml元素,其做用主要是增長了名字空間,好比有一樣的元素名稱,而名字空間不一樣的狀況。網絡
1 package com.skd.service; 2 3 import javax.jws.WebService; 4 5 @WebService 6 public class Hello { 7 public String sayHello(String name){ 8 System.out.println("sayHi called..."); 9 return " hello " + name; 10 } 11 12 }
1 package com.skd.soap; 2 3 import org.apache.cxf.jaxws.JaxWsServerFactoryBean; 4 import com.skd.service.Hello; 5 6 public class JaxWsBean { 7 8 /** 9 * 使用JaxWsServerFactoryBean發佈CXF的WebService服務 10 */ 11 public static void main(String[] args) { 12 //使用JaxWsServerFactoryBean發佈服務,須要在類上加入@WebService註解, 13 //若是不加,當前類中的方法都不能被髮布爲web方法 14 JaxWsServerFactoryBean bean = new JaxWsServerFactoryBean(); 15 //發佈服務的地址 16 bean.setAddress("http://localhost:8080/hello"); 17 //由於沒有接口,因此 18 bean.setServiceClass(Hello.class); 19 //發佈服務的實現類 20 bean.setServiceBean(new Hello()); 21 //發佈服務 22 bean.create(); 23 } 24 25 }
接口:
1 package com.skd.service; 2 @WebService 3 public interface IHi { 4 public String sayHi(String name); 5 }
實現類:
1 package com.skd.service; 2 3 public class HiImpl implements IHi { 4 5 @Override 6 public String sayHi(String name) { 7 return name+"Hi"; 8 } 9 10 }
發佈服務:
1 package com.skd.soap.impl; 2 3 import org.apache.cxf.jaxws.JaxWsServerFactoryBean; 4 import com.skd.service.Hello; 5 import com.skd.service.HiImpl; 6 import com.skd.service.IHi; 7 8 public class JaxWsBean { 9 10 /** 11 * 使用JaxWsServerFactoryBean發佈CXF的WebService服務 12 */ 13 public static void main(String[] args) { 14 //使用JaxWsServerFactoryBean發佈服務,須要在類上加入@WebService註解, 15 //若是不加,當前類中的方法都不能被髮布爲web方法 16 JaxWsServerFactoryBean bean = new JaxWsServerFactoryBean(); 17 //發佈服務的地址 18 bean.setAddress("http://localhost:8080/hello"); 19 //接口類型 20 bean.setServiceClass(IHi.class); 21 //接口的實現類 22 bean.setServiceBean(new HiImpl()); 23 //發佈服務 24 bean.create(); 25 } 26 27 }
建立Person類(必須實現Serializable接口)
1 package com.skd.rest.service; 2 3 import java.io.Serializable; 4 5 public class Person implements Serializable{ 6 7 private static final long serialVersionUID = 1L; 8 private String name; 9 private int age; 10 public String getName() { 11 return name; 12 } 13 public void setName(String name) { 14 this.name = name; 15 } 16 public int getAge() { 17 return age; 18 } 19 public void setAge(int age) { 20 this.age = age; 21 } 22 23 24 }
接口:
1 package com.skd.rest.service; 2 3 import java.util.List; 4 5 import javax.ws.rs.GET; 6 import javax.ws.rs.Path; 7 import javax.ws.rs.PathParam; 8 import javax.ws.rs.Produces; 9 import javax.ws.rs.core.MediaType; 10 11 @Produces( { MediaType.APPLICATION_JSON }) 12 public interface IPerson { 13 @GET//當前方法能夠經過GET方式訪問 14 @Path("hello/{name}")//當前方法的訪問路徑 15 public Person getPerson(@PathParam("name") String name);//將id得到賦予方法 16 17 }
實現類:
1 package com.skd.rest.service; 2 3 public class PersonImpl implements IPerson { 4 5 @Override 6 public Person getPerson(String name) { 7 Person p=new Person(); 8 p.setName(name); 9 p.setAge(11); 10 return p; 11 } 12 13 14 }
發佈服務(注意必須添加序列化類此處用的是JacksonJsonProvider
):
1 package com.skd.rest.server; 2 import java.util.ArrayList; 3 import java.util.List; 4 import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; 5 import org.codehaus.jackson.jaxrs.JacksonJsonProvider; 6 import com.skd.rest.service.PersonImpl; 7 public class JaxWsBean { 8 9 /** 10 * 使用JaxWsServerFactoryBean發佈CXF的WebService服務 11 */ 12 public static void main(String[] args) { 13 //注意發佈rest服務的類爲JAXRSServerFactoryBean 14 JAXRSServerFactoryBean bean = new JAXRSServerFactoryBean(); 15 //發佈服務的地址 16 bean.setAddress("http://localhost:8080"); 17 bean.setResourceClasses(PersonImpl.class); 18 List<Object> list=new ArrayList<Object>(); 19 //必須添加,用於序列化person類爲json對象 20 list.add(new JacksonJsonProvider()); 21 bean.setProviders(list); 22 //發佈服務 23 bean.create(); 24 System.out.println("web服務"); 25 } 26 27 }
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 <groupId>web</groupId> 5 <artifactId>cxf</artifactId> 6 <packaging>war</packaging> 7 <version>1.0-SNAPSHOT</version> 8 <name>cxf Maven Webapp</name> 9 <url>http://maven.apache.org</url> 10 <properties> 11 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 12 <cxf.version>3.1.9</cxf.version> 13 <jackson.version>1.9.13</jackson.version> 14 <spring.version>4.0.5.RELEASE</spring.version> 15 </properties> 16 <dependencies> 17 <!-- Spring --> 18 <dependency> 19 <groupId>org.springframework</groupId> 20 <artifactId>spring-context</artifactId> 21 <version>${spring.version}</version> 22 </dependency> 23 <dependency> 24 <groupId>org.springframework</groupId> 25 <artifactId>spring-web</artifactId> 26 <version>${spring.version}</version> 27 </dependency> 28 <!--cxf所須要的jar包--> 29 <!--cxf-rt-frontend-jaxws 對soap服務的支持--> 30 <dependency> 31 <groupId>org.apache.cxf</groupId> 32 <artifactId>cxf-rt-frontend-jaxws</artifactId> 33 <version>${cxf.version}</version> 34 </dependency> 35 <!--cxf-rt-frontend-jaxrs 對rest服務的支持--> 36 <dependency> 37 <groupId>org.apache.cxf</groupId> 38 <artifactId>cxf-rt-frontend-jaxrs</artifactId> 39 <version>${cxf.version}</version> 40 </dependency> 41 <dependency> 42 <groupId>org.apache.cxf</groupId> 43 <artifactId>cxf-rt-transports-http</artifactId> 44 <version>${cxf.version}</version> 45 </dependency> 46 <dependency> 47 <groupId>org.apache.cxf</groupId> 48 <artifactId>cxf-rt-transports-http-jetty</artifactId> 49 <version>${cxf.version}</version> 50 </dependency> 51 <!-- 用於rest服務序列化對象--> 52 <dependency> 53 <groupId>org.codehaus.jackson</groupId> 54 <artifactId>jackson-jaxrs</artifactId> 55 <version>${jackson.version}</version> 56 </dependency> 57 <!--用於跨域的jar包--> 58 <dependency> 59 <groupId>com.thetransactioncompany</groupId> 60 <artifactId>java-property-utils</artifactId> 61 <version>1.9</version> 62 </dependency> 63 <dependency> 64 <groupId>com.thetransactioncompany</groupId> 65 <artifactId>cors-filter</artifactId> 66 <version>1.7</version> 67 </dependency> 68 <dependency> 69 <groupId>junit</groupId> 70 <artifactId>junit</artifactId> 71 <version>4.9</version> 72 <scope>test</scope> 73 </dependency> 74 </dependencies> 75 <build> 76 <finalName>cxf</finalName> 77 </build> 78 </project>
1 <!DOCTYPE web-app PUBLIC 2 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 3 "http://java.sun.com/dtd/web-app_2_3.dtd" > 4 5 <web-app> 6 <display-name>Archetype Created Web Application</display-name> 7 <filter> 8 <filter-name>CORS</filter-name> 9 <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class> 10 <init-param> 11 <param-name>cors.allowOrigin</param-name> 12 <param-value>*</param-value> 13 </init-param> 14 <init-param> 15 <param-name>cors.supportedMethods</param-name> 16 <param-value>GET, POST, HEAD, PUT, DELETE</param-value> 17 </init-param> 18 <init-param> 19 <param-name>cors.supportedHeaders</param-name> 20 <param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified</param-value> 21 </init-param> 22 <init-param> 23 <param-name>cors.exposedHeaders</param-name> 24 <param-value>Set-Cookie</param-value> 25 </init-param> 26 <init-param> 27 <param-name>cors.supportsCredentials</param-name> 28 <param-value>true</param-value> 29 </init-param> 30 </filter> 31 <filter-mapping> 32 <filter-name>CORS</filter-name> 33 <!--容許跨域的路徑,這裏只容許咱們發佈的Web服務跨域--> 34 <url-pattern>/ws/*</url-pattern> 35 </filter-mapping> 36 <servlet> 37 <servlet-name>cxf</servlet-name> 38 <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> 39 <init-param> 40 <param-name>config-location</param-name> 41 <param-value>classpath:cxf.xml</param-value> 42 </init-param> 43 </servlet> 44 <!--web服務的地址--> 45 <servlet-mapping> 46 <servlet-name>cxf</servlet-name> 47 <url-pattern>/ws/*</url-pattern> 48 </servlet-mapping> 49 50 51 </web-app>
1 //實體類 2 public class User { 3 private String username; 4 private String password; 5 6 public String getUsername() { 7 return username; 8 } 9 10 public void setUsername(String username) { 11 this.username = username; 12 } 13 14 public String getPassword() { 15 return password; 16 } 17 18 public void setPassword(String password) { 19 this.password = password; 20 } 21 } 22 23 //接口 24 @WebService 25 public interface UserService { 26 public User getUser(String name); 27 } 28 29 //接口實現類 30 public class UserServiceImpl implements UserService{ 31 public User getUser(String name) { 32 User u=new User(); 33 u.setUsername(name); 34 u.setPassword("123456"); 35 return u; 36 } 37 }
1 //實體類(注意要實現接口Serializable) 2 public class Person implements Serializable{ 3 private String name; 4 private int age; 5 public String getName() { 6 return name; 7 } 8 public void setName(String name) { 9 this.name = name; 10 } 11 public int getAge() { 12 return age; 13 } 14 public void setAge(int age) { 15 this.age = age; 16 } 17 } 18 19 //接口 20 @Produces( {MediaType.APPLICATION_JSON }) 21 public interface PersonService { 22 @GET 23 @Path("/person/{name}") 24 public Person getPerson(@PathParam("name") String name); 25 @GET 26 @Path("/persons") 27 public List<Person> getPersons(); 28 } 29 30 //實現類 31 public class PersonServiceImpl implements PersonService{ 32 public Person getPerson(String name) { 33 Person p=new Person(); 34 p.setName(name); 35 p.setAge(100); 36 return p; 37 } 38 39 public List<Person> getPersons() { 40 List<Person> persons=new ArrayList<Person>(); 41 Person p1=new Person(); 42 p1.setName("wpx"); 43 p1.setAge(100); 44 persons.add(p1); 45 Person p2=new Person(); 46 p2.setName("zlr"); 47 p2.setAge(100); 48 persons.add(p2); 49 return persons; 50 } 51 }
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" 4 xmlns:soap="http://cxf.apache.org/bindings/soap" xmlns:jaxrs="http://cxf.apache.org/jaxrs" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://cxf.apache.org/bindings/soap 8 http://cxf.apache.org/schemas/configuration/soap.xsd 9 http://cxf.apache.org/jaxws 10 http://cxf.apache.org/schemas/jaxws.xsd 11 http://cxf.apache.org/jaxrs 12 http://cxf.apache.org/schemas/jaxrs.xsd 13 "> 14 <!-- 15 id:當前服務的惟一標識 address:當前服務對應的請求url serviceClass:接口類型 16 --> 17 <jaxws:server id="soapuser" address="/user" 18 serviceClass="com.skd.service.UserService"> 19 <jaxws:serviceBean> 20 <bean class="com.skd.service.impl.UserServiceImpl" /> 21 </jaxws:serviceBean> 22 <jaxws:inInterceptors> 23 <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean> 24 </jaxws:inInterceptors> 25 </jaxws:server> 26 <!-- 發佈一個Restful方式的WebService服務 --> 27 <bean id="personServiceImpl" class="com.skd.service.impl.PersonServiceImpl"></bean> 28 <jaxrs:server id="personService" address="/p"> 29 <jaxrs:serviceBeans> 30 <ref bean="personServiceImpl" /> 31 </jaxrs:serviceBeans> 32 <!--提供序列化爲json數據的實現類--> 33 <jaxrs:providers> 34 <bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"></bean> 35 </jaxrs:providers> 36 <jaxrs:inInterceptors> 37 <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean> 38 </jaxrs:inInterceptors> 39 <jaxrs:outInterceptors> 40 <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean> 41 </jaxrs:outInterceptors> 42 </jaxrs:server> 43 </beans>
所實現的功能有:
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 <groupId>spring</groupId> 5 <artifactId>cxf</artifactId> 6 <packaging>war</packaging> 7 <version>1.0-SNAPSHOT</version> 8 <name>cxf Maven Webapp</name> 9 <url>http://maven.apache.org</url> 10 <properties> 11 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 12 <cxf.version>3.1.9</cxf.version> 13 <jackson.version>1.9.13</jackson.version> 14 <spring.version>4.1.9.RELEASE</spring.version> 15 </properties> 16 <dependencies> 17 <!-- Spring --> 18 <dependency> 19 <groupId>org.springframework</groupId> 20 <artifactId>spring-context</artifactId> 21 <version>${spring.version}</version> 22 </dependency> 23 <dependency> 24 <groupId>org.springframework</groupId> 25 <artifactId>spring-web</artifactId> 26 <version>${spring.version}</version> 27 </dependency> 28 <!-- CXF --> 29 <!--cxf-rt-frontend-jaxws支持soap類型服務--> 30 <dependency> 31 <groupId>org.apache.cxf</groupId> 32 <artifactId>cxf-rt-frontend-jaxws</artifactId> 33 <version>${cxf.version}</version> 34 </dependency> 35 <!--cxf-rt-frontend-jaxrs支持rest服務--> 36 <dependency> 37 <groupId>org.apache.cxf</groupId> 38 <artifactId>cxf-rt-frontend-jaxrs</artifactId> 39 <version>${cxf.version}</version> 40 </dependency> 41 <dependency> 42 <groupId>org.apache.cxf</groupId> 43 <artifactId>cxf-rt-transports-http</artifactId> 44 <version>${cxf.version}</version> 45 </dependency> 46 <!--用於跨域的jar包--> 47 <dependency> 48 <groupId>com.thetransactioncompany</groupId> 49 <artifactId>java-property-utils</artifactId> 50 <version>1.9</version> 51 </dependency> 52 <dependency> 53 <groupId>com.thetransactioncompany</groupId> 54 <artifactId>cors-filter</artifactId> 55 <version>1.7</version> 56 </dependency> 57 <!-- 用於序列化json服務 --> 58 <dependency> 59 <groupId>org.codehaus.jackson</groupId> 60 <artifactId>jackson-jaxrs</artifactId> 61 <version>${jackson.version}</version> 62 </dependency> 63 <!--測試框架--> 64 <dependency> 65 <groupId>junit</groupId> 66 <artifactId>junit</artifactId> 67 <version>4.9</version> 68 <scope>test</scope> 69 </dependency> 70 </dependencies> 71 <build> 72 <finalName>cxf</finalName> 73 </build> 74 </project>
1 <!DOCTYPE web-app PUBLIC 2 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 3 "http://java.sun.com/dtd/web-app_2_3.dtd" > 4 5 <web-app> 6 <display-name>Archetype Created Web Application</display-name> 7 <!-- 經過上下文參數指定spring配置文件的位置 --> 8 <context-param> 9 <param-name>contextConfigLocation</param-name> 10 <param-value>classpath:spring.xml</param-value> 11 </context-param> 12 <!--用於設置跨域的攔截器--> 13 <filter> 14 <filter-name>CORS</filter-name> 15 <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class> 16 <!--容許哪一些客戶端跨域--> 17 <init-param> 18 <param-name>cors.allowOrigin</param-name> 19 <param-value>*</param-value> 20 </init-param> 21 <init-param> 22 <param-name>cors.supportedMethods</param-name> 23 <param-value>GET, POST, HEAD, PUT, DELETE</param-value> 24 </init-param> 25 <init-param> 26 <param-name>cors.supportedHeaders</param-name> 27 <param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified</param-value> 28 </init-param> 29 <init-param> 30 <param-name>cors.exposedHeaders</param-name> 31 <param-value>Set-Cookie</param-value> 32 </init-param> 33 <init-param> 34 <param-name>cors.supportsCredentials</param-name> 35 <param-value>true</param-value> 36 </init-param> 37 </filter> 38 <!-- 編碼過濾器 --> 39 <filter> 40 <filter-name>encodingFilter</filter-name> 41 <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 42 <init-param> 43 <param-name>encoding</param-name> 44 <param-value>UTF-8</param-value> 45 </init-param> 46 </filter> 47 <filter-mapping> 48 <filter-name>encodingFilter</filter-name> 49 <url-pattern>/*</url-pattern> 50 </filter-mapping> 51 <filter-mapping> 52 <filter-name>CORS</filter-name> 53 <!--容許跨域的路徑,這裏只容許咱們發佈的Web服務跨域--> 54 <url-pattern>/ws/*</url-pattern> 55 </filter-mapping> 56 <!-- 配置spring提供的上下文載入器監聽器,當項目啓動時加載spring配置文件,初始化spring工廠 --> 57 <listener> 58 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 59 </listener> 60 <servlet> 61 <servlet-name>cxf</servlet-name> 62 <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> 63 </servlet> 64 <servlet-mapping> 65 <servlet-name>cxf</servlet-name> 66 <url-pattern>/ws/*</url-pattern> 67 </servlet-mapping> 68 <!--springmvc的配置--> 69 </web-app>
1 public class User { 2 private String username; 3 private String password; 4 5 public String getUsername() { 6 return username; 7 } 8 9 public void setUsername(String username) { 10 this.username = username; 11 } 12 13 public String getPassword() { 14 return password; 15 } 16 17 public void setPassword(String password) { 18 this.password = password; 19 } 20 } 21 22 //------------------------ 23 @WebService 24 public interface UserService { 25 public User getUser(String name); 26 } 27 28 29 30 31 //-------------------------- 32 public class UserServiceImpl implements UserService{ 33 public User getUser(String name) { 34 User u=new User(); 35 u.setUsername(name); 36 u.setPassword("123456"); 37 return u; 38 } 39 }
1 public class Person implements Serializable{ 2 private String name; 3 private int age; 4 public String getName() { 5 return name; 6 } 7 public void setName(String name) { 8 this.name = name; 9 } 10 public int getAge() { 11 return age; 12 } 13 public void setAge(int age) { 14 this.age = age; 15 } 16 } 17 18 19 //interface 20 @Produces( {MediaType.APPLICATION_JSON }) 21 public interface PersonService { 22 @POST 23 @Path("/person/{name}") 24 public Person getPerson(@PathParam("name") String name); 25 @POST 26 @Path("/persons") 27 public List<Person> getPersons(); 28 } 29 30 31 //------------ 32 public class PersonServiceImpl implements PersonService{ 33 public Person getPerson(String name) { 34 Person p=new Person(); 35 p.setName(name); 36 p.setAge(100); 37 return p; 38 } 39 40 public List<Person> getPersons() { 41 List<Person> persons=new ArrayList<Person>(); 42 Person p1=new Person(); 43 p1.setName("wpx"); 44 p1.setAge(100); 45 persons.add(p1); 46 Person p2=new Person(); 47 p2.setName("zlr"); 48 p2.setAge(100); 49 persons.add(p2); 50 return persons; 51 } 52 }
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:jaxws="http://cxf.apache.org/jaxws" 5 xmlns:jaxrs="http://cxf.apache.org/jaxrs" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 8 http://cxf.apache.org/jaxws 9 http://cxf.apache.org/schemas/jaxws.xsd 10 http://cxf.apache.org/jaxrs 11 http://cxf.apache.org/schemas/jaxrs.xsd"> 12 <!-- 13 id:當前服務的惟一標識 address:當前服務對應的請求url serviceClass:接口類型 14 --> 15 <jaxws:server id="soapuser" address="/user" 16 serviceClass="com.skd.service.UserService"> 17 <jaxws:serviceBean> 18 <bean class="com.skd.service.impl.UserServiceImpl" /> 19 </jaxws:serviceBean> 20 </jaxws:server> 21 <!-- 發佈一個Restful方式的WebService服務 --> 22 <bean id="personServiceImpl" class="com.skd.service.impl.PersonServiceImpl"></bean> 23 <jaxrs:server id="personService" address="/rest"> 24 <jaxrs:serviceBeans> 25 <ref bean="personServiceImpl" /> 26 </jaxrs:serviceBeans> 27 <jaxrs:providers> 28 <!--提供序列化爲json數據的實現類--> 29 <bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"></bean> 30 </jaxrs:providers> 31 <jaxrs:inInterceptors> 32 <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean> 33 </jaxrs:inInterceptors> 34 <jaxrs:outInterceptors> 35 <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean> 36 </jaxrs:outInterceptors> 37 </jaxrs:server> 38 </beans>
Spring爲JAX-WS Servlet 終端實現類(SpringBeanAutowiringSupport
)提供了一個方便的基類。爲暴露咱們的AccountService
,咱們擴展了Spring的SpringBeanAutowiringSupport
類並在這裏實現了業務邏輯,一般委託這個調用給業務層。咱們將簡單地在Spring管理的beans的依賴上使用Spring的@Autowired註解。
Spring之集成之Web Services:http://www.javashuo.com/article/p-vvswqsdq-de.html
spring-web在version2.5.1的時候,在package org.springframework.web.context.support下加入了一個工具類叫SpringBeanAutowiringSupport,主要用來對Spring Web Application Context以外的類提供@Autowired注入功能。
具體來說,Servlet中原本不能使用@Autowired注入bean,解決辦法是在Servlet的init(ServletConfig)方法中調用SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this),就能夠直接使用@Autowired來注入Web Application Context下的一些Service等Bean了。(見下例)
又或者使用Quartz Job的時候,能夠在Job類中使用SpringBeanAutowiringSupport,就能夠直接直使Spring的bean了。(固然若是Job比較多的話,這種方法仍是很不方便,推薦使用SchedulerFactoryBean來集成。另外一種更方便的辦法是直接將Job集成到Spring Context中,當作一個bean)。
值得注意的是,這個類的做用域是Web Application Context,若是應用中實現的是一個好比ConfigurableApplicationContext,那就不能用該方法來對Servlet或是Job或是其它目標類提供@Autowired。
1. 例子:在Servlet中使用:
1 public class InitServlet extends HttpServlet { 2 3 @Autowired 4 private ServiceA serviceA; 5 6 public void init(ServletConfig config) throws ServletException { 7 super.init(config); 8 SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); 9 assertNotNull("Service should be injected.", serviceA); 10 } 11 12 // Omitted doGet(req, res), doPost(req, res); 13 }
2. 例子:在Quartz Job中使用:
1 public class DumpJob implements Job { 2 3 @Autowired 4 private ServiceA serviceA; 5 6 public void execute(JobExecutionContext context) throws JobExecutionException { 7 SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); 8 assertNotNull("Service should be injected.", serviceA); 9 } 10 }
3. SpringBeanAutowiringSupport源碼分析:
1 /** 2 * Process {@code @Autowired} injection for the given target object, 3 * based on the current web application context. 4 * <p>Intended for use as a delegate. 5 * @param target the target object to process 6 * @see org.springframework.web.context.ContextLoader#getCurrentWebApplicationContext() 7 */ 8 public static void processInjectionBasedOnCurrentContext(Object target) { 9 Assert.notNull(target, "Target object must not be null"); 10 WebApplicationContext cc = ContextLoader.getCurrentWebApplicationContext(); 11 if (cc != null) { 12 AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor(); 13 bpp.setBeanFactory(cc.getAutowireCapableBeanFactory()); 14 bpp.processInjection(target); 15 } 16 else { 17 if (logger.isDebugEnabled()) { 18 logger.debug("Current WebApplicationContext is not available for processing of " + 19 ClassUtils.getShortName(target.getClass()) + ": " + 20 "Make sure this class gets constructed in a Spring web application. Proceeding without injection."); 21 } 22 } 23 }
從方法第2行能夠看出經過ContextLoader拿到當前的WebApplicationContext對象,再經過AutowiredAnnotationBeanPostProcessor類來解決當前傳入的目標class的@Autowired注入能力。
(AutowiredAnnotationBeanPostProcessor在Spring2.5隨着Annotation功能的擴展而增長的,咱們平時用context namepace的標籤<context:component-scan>時,Spring會默認生成註冊AutowiredAnnotationBeanPostProcessor類來幫助解析@Autowired @Value @Inject等標籤。)
4. 使用另外一個工具類WebApplicationContextUtils來獲取Service Bean:
1 WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(config.getServletContext()); 2 ServiceA ServiceA = context.getBean(ServiceA.class);
固然這個方法更強大,由於直接拿到WebApplicationContext對象了!
5. 補充WebApplicationContext相關:
對於Web項目,一般使用org.springframework.web.context.ContextLoaderListener,設置屬性contextConfigLocation來生成WebApplicationContext。
WebApplicationContext類圖(用StarUML畫的):