其實在實際中,我們自定義ws的可能性比較小,一般都是去調用已有的ws較多,除非項目需要發佈一個ws。但是爲了更好的理解ws,這一篇博文主要來總結一下如何自定義ws,然後如何去調用自定義的ws,內容比較基礎,完全針對小白。
1. 自定義webservice
1.1 原生態jdk定義
使用jdk自定義一個ws只需要做兩件事:一是使用註解@WebService,二是調用Endpoint類的靜態方法publish創建一個服務端點即可。如下:
/**
* @Description 自定義ws,jdk1.7版本及以上才支持soap1.2
* @author Ni Shengwu
*
*/
@WebService //默認靜態方法是不能發不成ws服務的
public class MyWebService {
//提供一個方法,供下面測試用的
public String sayHello(String name) {
return name + " 你好!";
}
public static void main(String[] args) {
// 一個端口可以發佈多個ws服務,所以後面還有 /+服務名
String address = "http://192.168.1.105:6666/ws";
String address2 = "http://192.168.1.105:6666/ws2";
// 創建一個服務端點
Endpoint.publish(address, new MyWebService());
Endpoint.publish(address2, new MyWebService());
System.out.println("訪問WSDL的地址爲:" + address + "?WSDL");
System.out.println("訪問WSDL的地址爲:" + address2 + "?WSDL");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
這個192.168.1.105是我的ip地址,6666是自己設定的端口號,後面爲啥還要跟個名稱ws呢?因爲一個端口可以發佈多個ws服務,所以可以自己起個名兒,我這裏創建了兩個ws服務地址,分別命名爲ws和ws2。然後通過調用Endpoint類的靜態方法publish創建服務端點,傳進去剛剛定義好的ws服務地址和自定義ws的類即可。後面兩個輸出地址是用來根據WSDL生成java代碼方便用的。
這樣的話,一個ws就定義好了,運行一下,控制檯會輸出兩個地址,分別在瀏覽器中輸入這兩個地址就會顯示兩個相同的xml文檔,我們待會兒根據這個WSDL來生成java代碼。
1.2 使用CXF自定義ws
CXF是ws的一個框架,使用很方便,想要更多的瞭解CXF可以去百度或者谷歌一下。爲了更加規範點,我將需要發佈爲ws的類單獨寫出來,並抽取接口,如下:
//這是接口
@WebService
public interface HelloWorld {
public String sayHello(String str);
}
//這是實現類
@WebService
public class HelloWorldImpl implements HelloWorld{
public String sayHello(String str) {
return "Hello" + str;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
這裏建立的是maven工程,porm.xml需要導入相關的jar包,我導入的是目前最新版的3.1.6。如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>webservice</groupId>
<artifactId>WS_Server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.6</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-core</artifactId>
<version>3.1.6</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.1.6</version>
</dependency>
</dependencies>
</project>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
接下來就是創建ws了,如下:
public class Server {
public static void main(String[] args) {
System.out.println("web service start");
HelloWorld implementor = new HelloWorldImpl();
String address = "http://192.168.1.105/ws";
JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean();
factoryBean.setAddress(address); // 設置暴露地址
factoryBean.setServiceClass(HelloWorld.class); // 接口類
factoryBean.setServiceBean(implementor); // 設置實現類
factoryBean.create(); // 創建webservice接口
System.out.println("web service started");
System.out.println("請求地址爲爲:" + address + "?WSDL");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
這樣就使用CXF創建好了ws了,下面就是調用這個ws服務了,下面的調用我用的是上面原生態jdk生成的ws服務,其實都一樣的。
2. 調用自定義的webservice
2.1 使用普通java程序調用
剛剛已經生成了對應的WSDL了,在調用自定義的ws前,我們需要先通過解析這個WSDL,然後生成一些Java代碼,可以看成是我們自定義ws的API。打開命令行,輸入 wsimport -s . -p ws.client.d http://192.168.1.105:6666/ws?WSDL
就能生成一個目錄ws/client/d/,以及目錄中的一些class文件和java文件,刪掉class文件,然後拷貝ws目錄,直接貼到工程另一個工程中,如下:
裏面框框圈的都是自定義ws相關的API,然後自己寫一個_Main類來調用自定義ws,如下:
/**
* @Description 調用自己發佈的ws服務
* @author Ni Shengwu
*
*/
public class _Main {
public static void main(String[] args) {
// 獲取ws服務名稱(獲取一個ws服務)
MyWebServiceService service = new MyWebServiceService();
//獲取服務的類型,有get post soap1.1 soap1.2 jdk1.7及以上才支持soap1.2
MyWebService port = service.getMyWebServicePort();
//調用服務提供的方法
System.out.println(port.sayHello("hello"));
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
根據上面的代碼,即傳入一個hello去調用自定義ws中的sayHello方法,所以控制檯會打印出 “hello 你好!”。這樣自定義ws以及調用就完成了。
2.2 使用Ajax調用
使用Ajax調用的話,流程也很簡單,從前臺發送Ajax請求,然後調用ws服務,再將結果返回給前臺。但是Ajax不支持跨域調用,也就是說我們發佈的ws服務,如http://192.168.1.105:6666/ws是不行的,Ajax要想正常調用必須通過wsimport命令轉化的java bean,換句話說,我們需要在中間加上一個servlet(或者struts,springmvc),在servlet中調用ws服務,把數據返回到前臺。寫個demo如下:
servlet:
public class _MyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
// 創建ws服務
MyWebServiceService ws = new MyWebServiceService();
MyWebService port = ws.getMyWebServicePort();
String result = port.sayHello(name);
// 返回結果
response.getWriter().write(result);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
這個servlet映射的url爲/MyServlet。
jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script type="text/javascript" src="jquery-1.3.js"></script>
</head>
<script type="text/javascript">
$(function() {
$("#btn").click(function() {
$.post("MyServlet", {name:$("#txt").val()}, function(msg) {
alert(msg);
}, "text");
});
})
</script>
<body>
<input type="text" id="txt" />
<input type="button" id="btn" value="ajax調用ws服務演示">
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
jsp中通過發送Ajax請求,將輸入的值帶給servlet,然後在servlet中獲取該值,調用ws獲取結果返回給前臺顯示,完成Ajax調用。