J2EE 7 SDKhtml
Eclipsejava
Tomcatweb
Mavenwindows
SEI,全稱Service Endpoint Interface或Service Endpoint Implemention。是服務器端和客戶端開發真正要接觸的類。tomcat
JAX-WS RI,全稱JAX-WS Reference Implementation。這是JAX-WS的實現。與之相對立的應該是JAX-WS和JAXB API。
服務器
JAXB,全稱Java Architecture for XML Binding。這是將Java類和XML schema相互映射的標準,此標準能夠將Java實例轉爲XML,也能夠將XML轉爲Java實例。併發
SAAJ,全稱SOAP with Attachment API for Java。這是用於解析和生成SOAP協議數據的類庫。oracle
SEI中的方法中的參數,是由JAXB從SOAP中的XML數據轉變而來,方法返回值,則由JAXB轉爲XML數據,而後經過SAAJ封裝在SOAP消息中傳回。因此,SEI中的方法參數和返回值,必須符合JAVA和XML Type的對應關係。
app
這裏有一張映射表 http://docs.oracle.com/javaee/7/tutorial/doc/jaxws002.htm eclipse
用圖表示,JAX-WS的工做原理就是
SEI成功工做所依賴的自定義java類,均可以使用JEE SDK所提供的工具,自動產生。
通常存在兩種開發流程,從開發SEI開始,另外一種是從開發WSDL開始。
這種方式適合Java程序猿。
首先開發SEI。
使用JEE SDK中的工具wsgen,生成運行所依賴的全部Java類,class以及WSDL,XSD。
例如:wsgen -wsdl -r resource -s src -d stock -cp myclasspath stock.StockService
-wsdl 表示產生wsdl xsd文件
-r 表示wsdl產生在那個目錄
-s 表示source放在哪一個目錄
-d 表示生成的最終文件放在哪一個目錄
編寫配置文件
打包成WAR併發布。
這種方式適合跨平臺
開發,或者從其它平臺獲取WSDL文件。
使用JEE SDK中的工具wsimport,生成SEI接口以及全部Java文件。
例如: wsimport -p stockquote http://stockquote.xyz/quote?wsdl
爲SEI接口編寫SEI實現類。
打包併發布。
JAX-WS提供了Maven plugin,可使用Maven簡化上面的流程。詳細過程請看後面的實例。
下面我將一步一步的開發一個實例。
添加圖書。
根據編號查詢圖書。
刪除圖書。
在eclipse中,建立一個webApp的maven項目。JAXWS的Maven Plugin使用方法,能夠在https://jax-ws-commons.java.net/jaxws-maven-plugin/ 找到。Plugin中包含了最重要的兩個goal, wsimport和wsgen。
因爲JRE的lib中已經包含了JAXWS的全部包,但其版本可能不是你想要的。因此,在開發開發部署JAXWS的時候,存在着兩種依賴方式:
使用JDK中自帶的JAXWS版本。
使用其它版本。這須要Java Endorsed Standards Override Mechanism .
本實驗對JAXWS的版本要求不高,因此使用JDK自帶的便可。
修改pom.xml,引入plugin。請加入如下代碼:
<build> <pluginManagement> <plugins> <plugin> <groupId>org.eclipse.m2e</groupId> <artifactId>lifecycle-mapping</artifactId> <version>1.0.0</version> <configuration> <lifecycleMappingMetadata> <pluginExecutions> <pluginExecution> <pluginExecutionFilter> <groupId>org.jvnet.jax-ws-commons</groupId> <artifactId>jaxws-maven-plugin</artifactId> <versionRange>[1.0,)</versionRange> <goals> <goal>wsgen</goal> </goals> </pluginExecutionFilter> <action> <execute /> </action> </pluginExecution> </pluginExecutions> </lifecycleMappingMetadata> </configuration> </plugin> </plugins> </pluginManagement> <plugins> <plugin> <groupId>org.jvnet.jax-ws-commons</groupId> <artifactId>jaxws-maven-plugin</artifactId> <version>2.3</version> <executions> <execution> <id>wsgen-from-jdk</id> <phase>process-classes</phase> <goals> <goal>wsgen</goal> </goals> <configuration> <executable>${tool.wsgen}</executable> <sei>com.mycompany.Library</sei> <genWsdl>true</genWsdl> </configuration> </execution> </executions> </plugin> </plugins> </build> <!-- setup corresponding executables on win --> <profiles> <profile> <id>win</id> <activation> <os> <family>windows</family> </os> </activation> <properties> <tool.wsgen>D:/sts/jdk1.7.0_10/bin/wsgen.exe</tool.wsgen> <tool.wsimport>D:/sts/jdk1.7.0_10/bin/wsimport.exe</tool.wsimport> </properties> </profile> </profiles>
以上POM中的代碼,將wsgen goal掛到process-classes phase上。其中PluginManagement部分是專門爲eclipse m2e寫的,由於execution沒法在m2e中被cover。若是是獨立maven環境,則不須要寫PluginManagement.
建立完Maven項目之後,接下來,咱們就能夠建立WebService SEI了。
Library.java
package com.mycompany; import java.util.ArrayList; import java.util.List; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; @WebService(targetNamespace="http://library.mycompany.com") public class Library { private static List<Book> bookList = new ArrayList<Book>(); private static int currentId = 0; public Library() { } @WebMethod @WebResult(name="id") public int addRawBook(@WebParam(name="name") String name, @WebParam(name="author") String author) { Book book = new Book(); book.setId(++currentId); book.setName(name); book.setAuthor(author); bookList.add(book); return currentId; } @WebMethod @WebResult(name="rawBook") public String getRawBook(@WebParam(name="id") int id) { Book goal=null; for(Book b: bookList) { if (id == b.getId()) { goal = b; break; } } StringBuilder result = new StringBuilder(); if (goal == null) { result.append("No Book Found"); } else { result.append("[id=").append(goal.getId()).append(";name=").append(goal.getName()).append(";author=").append(goal.getAuthor()); } return result.toString(); } @WebMethod public void deleteBook(@WebParam(name="id") int id) throws LibraryException { Book goal=null; for(Book b: bookList) { if (id == b.getId()) { goal = b; break; } } if(goal == null) { throw new LibraryException("Fail to delete", "Id not exist."); } else { bookList.remove(goal); } } }
另外還有Book和Exception的實現:
Book.java
package com.mycompany; public class Book { public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } private int id; private String name; private String author; }
LibraryException.java
package com.mycompany; public class LibraryException extends Exception { private String detail; public LibraryException(String message, String detail) { super(message); this.detail=detail; } public String getDetail() { return detail; } }
在servlet3.0容器中,並不須要web.xml,請忽略下面。若是部署在2.5中,則須要聲明webservice的servlet。
<listener> <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class> </listener> <servlet> <servlet-name>Library</servlet-name> <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Library</servlet-name> <url-pattern>/service</url-pattern> </servlet-mapping>
若是是glassfish,則不須要sun-jaxws.xml,自從java跟了oracle,oracle對java的各類規範極力支持,glassfish就是一個極度遵循j2ee規範的server。若是部署在tomcat及其它server上,則須要在WEB-INF下面建立sun-jaxws.xml.
<?xml version="1.0" encoding="UTF-8"?> <endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime' version='2.0'> <endpoint name='Library' implementation='com.mycompany.Library' url-pattern='/service'/> </endpoints>
運行maven package命令,將獲得的library.war複製到tomcat的目錄下。訪問頁面http://127.0.0.1:8080/library/service?wsdl
建立一個Maven project。在pom.xml中加入wsimport的命令。跟上面pom.xml同樣,我只寫出不同的地方:
<plugin> <groupId>org.jvnet.jax-ws-commons</groupId> <artifactId>jaxws-maven-plugin</artifactId> <version>2.3</version> <executions> <execution> <id>wsimport-from-jdk</id> <goals> <goal>wsimport</goal> </goals> <configuration> <executable>${tool.wsimport}</executable> <wsdlUrls> <wsdlUrl>http://127.0.0.1:8080/library/service?wsdl</wsdlUrl> </wsdlUrls> </configuration> </execution> </executions> </plugin>
在eclipse中,運行命令maven jaxws:wsimport,而後在target下面找到產生的java文件。將這些文件導入到src/main/java中。
public class App { public static void main( String[] args ) throws LibraryException_Exception { int id; String rawBook; id = createPort().addRawBook("java", "Tom"); System.out.println("Add id="+id); id=createPort().addRawBook("C", "Sam"); System.out.println("Add id="+id); rawBook = createPort().getRawBook(2); System.out.println("find"+rawBook); createPort().deleteBook(2); rawBook = createPort().getRawBook(2); System.out.println("find"+rawBook); createPort().deleteBook(2); } public static Library createPort() { Library port = new LibraryService().getLibraryPort(); return port; } }