Java開發(fā)WebService實例--計數(shù)器
網(wǎng)上關(guān)于WebService的例子,多是一些簡單得不能再簡單的hello
world的例子,簡單得以至于你對WebService沒有什么感覺。有了WebService的基本知識后,我一直再想,可以把什么樣的即簡單又實用
的東東做成WebService,開展示一下其功能特點。今天終于想到一個:計數(shù)器,計數(shù)器用得比較多,功能比較獨立,做成WebService可以一勞
永逸為不同系統(tǒng)(不管是JSP還ASP,這是WebService的突出優(yōu)點)、不同應(yīng)用節(jié)省此類編碼工作,可以說以后再也不用寫計數(shù)器了。只要用就行
了。
說了這么多廢話,下面我們開始。本教程介紹一下WebService環(huán)境搭建、服務(wù)部署的相關(guān)知識,然后介紹一個計數(shù)器的開發(fā)。
運行圖:
二、基礎(chǔ)工作
1.開發(fā)環(huán)境
我使用axis做為Web
Service引擎,它是Apache的一個開源web service引擎。它目前最為成熟的開源web
service引擎之一。下面我主要介紹一下如何使用Axis搭建web service 服務(wù)的環(huán)境。
①安裝tomcat5.0應(yīng)用服務(wù)器(也可以裝5.5,不過我一直在用5.0);
②解壓下載(
http://ws.apache.org/Axis)后的axis包,將包中axis目錄復(fù)制到tomcat目錄下的webapps目錄下;
③將axis/WEB-INF/lib目錄下類文件復(fù)制到tomcat目錄下的common/lib目錄下;
④重新啟動tomcat,訪問http://localhost:8080/axis/happyaxis.jsp,如果能訪問,表示安裝成功;
注意,axis有幾個可選的包,如email.jar....,你可以找來放到tomcat目錄下的common/lib目錄下,如果不使用相關(guān)的功能也可以不用。
這樣,開發(fā)環(huán)境就搭建好了。
2.如何部署Web Service
部署有三種方式:Dynamic Invocation
Interface(DII)、Stubs方式、Dynamic Proxy方式;這里就介紹一下簡單,也是我使用的方式:DII。
DII方式中,先寫好服務(wù)的JAVA文件(假設(shè)名字為helloworld.java),然后把它(注意是源文件)拷貝到webapps/axis目錄
中,后綴改成jws(此時文件名為:helloworld.jws),然后訪問連接http://localhost:
8080/Axis/helloworld.jws?wsdl,頁面顯示Axis自動生成的wsdl,這樣一個Web
Service就部署好了。怎么樣,是不是很簡。
我的計數(shù)器服務(wù)就是以這種方式部署的,下文中我會只說將計數(shù)器服務(wù)部署好,你可不要說:怎么部署,我不會呀。那在古代就要被打手板了。所以我想,古代只學四書五經(jīng)也是件好事呀。現(xiàn)在要學這么多東西,半天學不會,手要被打爛了。
三、計數(shù)器服務(wù)的編寫
計數(shù)器大家都知道了,比較簡單。我的計數(shù)器也同樣簡單,有以下功能及特點:提供四種計數(shù)器(總數(shù)器、月計數(shù)器、周計數(shù)器及日計數(shù)器);考慮到Web
Service要服務(wù)于多種應(yīng)用,這個計數(shù)器還支持多個用戶;使用XML文件來記錄數(shù)據(jù)。
記錄文件名為:d:"counter.xml。注意,此文件在服務(wù)里是硬編碼,如果修改名字,請在服務(wù)程序中也進行相應(yīng)的修改。文件內(nèi)容格式如下:
<?xml version="1.0"
encoding="UTF-8"?>
<counter>
<item>
<name>wallimn</name>
<password>123</password>
<dc>59</dc>
<wc>59</wc>
<mc>59</mc>
<tc>59</tc>
<rt>2007-4-16
16:01:29</rt>
</item>
<counter>
說是計數(shù)器服務(wù),其實跟編寫普通的JAVA應(yīng)用沒有什么兩樣。我的計數(shù)器代碼比較簡單,我就不做過多的介紹了,把它貼在下面,源碼中有少量注釋,相信大家不看注釋也看得懂。服務(wù)有只有一個接口:Counter(String
name, String
password),以后在客戶端拿來用就可以了。還多說一句,我和程序使用到了dom4j解析xml包,要調(diào)試的請自行準備好jar包。部署方法請參照上文。
import java.io.File;
import java.io.FileWriter;
import
java.io.IOException;
import java.text.DateFormat;
import
java.text.ParseException;
import java.util.Calendar;
import
java.util.Date;
import java.util.Iterator;
import
org.dom4j.Document;
import org.dom4j.DocumentException;
import
org.dom4j.Element;
import org.dom4j.io.SAXReader;
import
org.dom4j.io.XMLWriter;
/**
*功能:提供計數(shù)器服務(wù)的WebService,可以為多用戶提供服務(wù)。<br/>
*
@version : V1.0
* @author : 王力猛(Email: wallimn@sohu.com QQ: 54871876)
*
@date : 2007-4-16 下午04:32:45
*/
public class WsCounterByWallimn
{
//計數(shù)器文檔,注意名字名路徑。
private final String FileN =
"d:/counter.xml";
private final static DateFormat DATEFORMATER =
DateFormat.getDateTimeInstance();
//出錯的情況下返回的值
private final static String
ERRORINFO="-1;-1;-1;-1";
public WsCounterByWallimn(){
}
/**
*功能:打開計數(shù)器文檔<br/>
*編碼:王力猛 時間:2007-4-16
下午04:44:29<br/>
*/
private Document openDocument(){
Document
doc=null;
SAXReader reader = new SAXReader();
try {
File xmlfile = new
File(FileN);
doc = reader.read(xmlfile);
xmlfile=null;
}
catch
(DocumentException e) {
e.printStackTrace();
}
return
doc;
}
/**
*功能:取指定名稱計數(shù)器的詳細信息,并設(shè)置計數(shù)器加1。<br/>
*編碼:王力猛
時間:2007-4-16 下午04:49:57<br/>
*/
private synchronized String
countertick( String name, String password){
Document doc =
openDocument();
Date currdt = new java.util.Date();
//mc:month
counter(月計數(shù)器); dc: day counter(日計數(shù)器);
//tc: total counter(總計數(shù)器); wc: week
counter(周計數(shù)器);
//rt: registe time登記時間
String
mc="-1",dc="-1",tc="-1",wc="-1",rt="-1";
Element root =
doc.getRootElement();
Element selitem=null,item=null;
for(Iterator it =
root.elementIterator("item"); it.hasNext();){
item =
(Element)it.next();
if(name.equals(item.element("name").getText())){
selitem=item;
String pwd =
item.elementText("password");
if(!password.equals(pwd)){
return
ERRORINFO;//密碼不對,直接返回
}
mc=item.element("mc").getText();
dc=item.element("dc").getText();
tc=item.element("tc").getText();
wc=item.element("wc").getText();
rt=item.element("rt").getText();
break;
}
}
//如果selitem為空,說明沒有個名字的計數(shù)器。則添加一個。
if(selitem==null){
//System.out.println("沒有找到這個名字的計數(shù)器:"+name);
rt=DATEFORMATER.format(currdt);
selitem
=
doc.getRootElement().addElement("item");
selitem.addElement("name").setText(name);
selitem.addElement("tc").setText("0");
selitem.addElement("mc").setText("0");
selitem.addElement("wc").setText("0");
selitem.addElement("dc").setText("0");
selitem.addElement("rt").setText(rt);
selitem.addElement("password").setText(password);
mc="0";
wc="0";
dc="0";
tc="0";
}
//處理計數(shù)器加一操作。
Calendar
currcr=Calendar.getInstance();
//總數(shù)器總是加1。
tc
=String.valueOf(Integer.parseInt(tc)+1);
selitem.element("tc").setText(tc);
Date
lastdt = null;
try {
lastdt = DATEFORMATER.parse(rt);
}
catch
(ParseException e) {
lastdt = new java.util.Date();
}
Calendar lastcr =
Calendar.getInstance();
lastcr.setTime(lastdt);
currcr.setTime(currdt);
//System.out.println("上次登記時間:"+DATEFORMATER.format(lastdt));
//System.out.println("本次登記時間:"+DATEFORMATER.format(currdt));
if(lastcr.get(Calendar.YEAR)==currcr.get(Calendar.YEAR)){
//月相同,月計數(shù)加1
if(lastcr.get(Calendar.MONTH)==currcr.get(Calendar.MONTH)){
mc
=
String.valueOf(Integer.parseInt(mc)+1);
}
else{
mc="1";
}
//日相同,日計數(shù)加1
if(lastcr.get(Calendar.DAY_OF_YEAR)==currcr.get(Calendar.DAY_OF_YEAR))
dc
= String.valueOf(Integer.parseInt(dc)+1);
else
dc =
"1";
if(lastcr.get(Calendar.WEEK_OF_YEAR)==currcr.get(Calendar.WEEK_OF_YEAR))
wc
= String.valueOf(Integer.parseInt(wc)+1);
else
wc = "1";
}
else{//年不一樣,則月計數(shù)器、周計數(shù)器日計數(shù)器肯定也不一樣。
mc="1"; dc="1"; wc="1";
}
selitem.element("mc").setText(mc);
selitem.element("wc").setText(wc);
selitem.element("dc").setText(dc);
//登記記錄時間
selitem.element("rt").setText(DATEFORMATER.format(currdt));
try {
XMLWriter xw = new XMLWriter(new
FileWriter(FileN));
xw.write(doc);
xw.close();
}
catch (IOException
e) {
e.printStackTrace();
}
return
tc+";"+mc+";"+wc+";"+dc;
}
/**
*功能:服務(wù)暴露的接口,也就是指定名稱、密碼,返回指定的計數(shù),并將計數(shù)器加1。<br/>
*編碼:王力猛
時間:2007-4-17 上午10:05:22<br/>
*/
public String Counter(String name,
String password){
if(password==null || name==null)return ERRORINFO;
return
countertick(name, password);
}
}
四、客戶端編寫
客戶端是個頁面,為了條理清晰,我先寫個調(diào)用Web
Service的類,其內(nèi)容如下:
package com.wallimn.WebService;//調(diào)試請注意包名
import org.apache.axis.client.Call;
import
org.apache.axis.client.Service;
public class CounterServiceClient {
private String counterarr[];
public boolean getCounter(String CounterName, String password) {
boolean
res = false;
try {
String endpoint =
"http://localhost:8080/axis/WsCounterByWallimn.jws";//此處注意,請與你的開發(fā)環(huán)境匹配
Service
service = new Service();
Call call = (Call)
service.createCall();
call.setTargetEndpointAddress(new
java.net.URL(endpoint));
call.setOperationName("Counter");
//
填寫你要調(diào)用的方法名稱
String counter = (String) call.invoke(new Object[] { CounterName,
password });
counterarr = counter.split(";");
res = (counterarr != null
&& counterarr.length == 4);
}
catch (Exception e)
{
}
return res;
}
public String getDc() {
return counterarr[3];
}
public String getMc() {
return counterarr[1];
}
public String getTc() {
return counterarr[0];
}
public String getWc() {
return counterarr[2];
}
}
到頁面(test.jsp)上就簡單了,我也把它貼在下面:
<%@ page language="java"
import="com.wallimn.WebService.CounterServiceClient"
pageEncoding="GB18030"%>
<%
CounterServiceClient client = new
CounterServiceClient();
client.getCounter("hello","123");
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN">
<html>
<head>
<title>計數(shù)器測試頁面</title>
<meta
http-equiv="pragma" content="no-cache">
<meta
http-equiv="cache-control" content="no-cache">
<meta
http-equiv="expires" content="0">
<meta http-equiv="keywords"
content="wallimn,計數(shù)器,WebService">
<meta http-equiv="description"
content="計數(shù)器使用示例">
</head>
<body>
<h2
align="center">計數(shù)器詳情</h2>
<hr/>
總訪問量:<%=client.getTc()%>
<br/>
今天訪問量:<%=client.getDc()%>
<br/>
本周訪問量:<%=client.getWc()%>
<br/>
本月訪問量:<%=client.getMc()%> <br/>
<hr/>
<p>歡迎交流<br/>博客:http://blog.csdn.net/wallimn<br/>電郵:wallimn@sohu.com</p>
</body>
</html>
五、結(jié)束語
至此一個完整計數(shù)器的Web Service開發(fā)、使用的程序的全部完成了。將上面的類、及頁面部署到任意的一個上下文中,通過瀏覽器打開test.jsp,就可以看了結(jié)果了。歡迎訪問我的博客(http://blob.csdn.net/wallimn)留言或發(fā)郵件(wallimn@sohu.com)交流。
posted on 2008-04-25 17:02 々上善若水々 閱讀(10717) 評論(2) 編輯 收藏 所屬分類: WebService