WebService之soap類型的服務和rest類型的服務

1.引言

      WebService顧名思義就是web服務,web服務主要有兩種,一種是基於soap類型的服務,一種是基於rest類型的服務,其中soap類型的服務有兩種版本,一種是soap1.1版本,一種是soap1.2版本,soap服務類型的數據是xml數據格式的,而rest服務的數據類型是json格式的。html

2.什麼是WSDL?

      wsdl(網絡服務描述語言)是Web Service的描述語言,也就是說wsdl文件是soap的使用說明書。在學習soap以前,認識WSDL是很是有必要的,只有能看懂WSDL文件,咱們才能夠去調用soap類型的Web服務,下面是一個很是簡單的wsdl文件。java

3.在WSDL文件中咱們能夠得到什麼信息?

  • soap服務的名稱
  • soap服務的地址
  • soap服務暴露的方法
  • soap服務方法的參數
  • soap服務方法參數的類型和相應的返回值執行

4.利用Java發佈soap服務

      接下來咱們利用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 }
View Code

5.利用JDK註釋控制WSDL文件

代碼以下: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 }
View Code

6.1利用wsimport進行soap服務進行調用

      wsimport原理是根據wsdl文件生成本地代理。apache

  • 首先咱們使用wsimport命令生成java文件(須要安裝JDK)
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
  • 建立一個方法,調用Web服務,代碼以下

  

 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 }
View Code

總結:wsimport調用web服務的java代碼是有規律的,總共分爲三步:json

  • 建立服務名對象
  • 經過服務名得到接口對象(通常是getXXX,其中XXX表明服務名的port屬性)
  • 經過接口對象調用服務方法

  

6.2經過UrlConnection訪問Soap服務

 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 }
View Code

6.3利用JDK的Service方法

      在前兩種方法中,第一種方案生成的代碼很是多,第二種方案服務器返回的數據須要咱們來解析,都不是很是的完美,咱們可使用第三種方法,生成的代碼不是很是的多,對於服務器返回的數據也不須要咱們本身來解析,過程以下。api

  • 首先咱們使用wsimport生成本地代碼(可是咱們只把接口文件拷貝到咱們項目中來)
 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 }
View Code
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("\\", "/");
View Code

  注: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元素,其做用主要是增長了名字空間,好比有一樣的元素名稱,而名字空間不一樣的狀況。網絡

7.CXF發佈服務

7.1 CXF發佈SOAP類型的服務-無接口(http://localhost:8080/hello

  • 首先引用cxf的jar包
  • 利用CXF發佈沒有接口的SOAP服務
 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 }
View Code
 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 }
View Code

7.2 CXF發佈SOAP類型的服務-有接口(服務地址:」http://localhost:8080/hello「)

接口:

1 package com.skd.service;
2 @WebService
3 public interface IHi {
4     public String sayHi(String name);
5 }
View Code

實現類:

 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 }
View Code

發佈服務:

 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 }
View Code

7.3.cxf發佈rest服務(服務地址:http://localhost:8080/hello/*)

建立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 }
View Code

接口:

 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 }
View Code

實現類:

 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 }
View Code

發佈服務(注意必須添加序列化類此處用的是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 }
View Code

8.CXF與Web程序的整合

8.1 POM.xml文件

 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>
View Code

8.2 web.xml文件

 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>
View Code

8.3 SOAP服務的接口,類,實體類

 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 }
View Code

8.4 rest服務的實體類,接口,接口的實現類

 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 }
View Code

8.5 CXF的配置文件(cxf.xml)

 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>
View Code

查看網址http://localhost:8080/ws

9.CXF與spring的整合

所實現的功能有:

  • 將Person,PersonService,PersonServiceImpl發佈爲Rest類型的服務
  • 將User ,UserService,UserServiceImpl發佈爲Soap類型的服務
  • 容許咱們的Web服務能夠跨域請求

9.1POM.xml文件

 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>
View Code

9.2web.xml文件

 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>
View Code

9.3soap接口,實現類,實體類

 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 }
View Code

9.4rest接口,實現類,實體類

 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 }
View Code

9.5spring-cxf配置文件

 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>
View Code

訪問地址http://localhost:8080/ws

10.SpringBeanAutowiringSupport介紹

  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。 

官方Doc: 
http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/context/support/SpringBeanAutowiringSupport.html 

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 }  
View Code

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 }  
View Code

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     }  
View Code

  從方法第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);  
View Code

固然這個方法更強大,由於直接拿到WebApplicationContext對象了! 

5. 補充WebApplicationContext相關: 
對於Web項目,一般使用org.springframework.web.context.ContextLoaderListener,設置屬性contextConfigLocation來生成WebApplicationContext。 

WebApplicationContext類圖(用StarUML畫的): 

webservice發佈使用spring的SpringBeanAutowiringSupport自動裝配不了屬性

相關文章
相關標籤/搜索