我的漫漫程序之旅

          專注于JavaWeb開(kāi)發(fā)
          隨筆 - 39, 文章 - 310, 評(píng)論 - 411, 引用 - 0
          數(shù)據(jù)加載中……

          Java開(kāi)發(fā)WebService實(shí)例--計(jì)數(shù)器

            如果使用GOOGLE、BAIDU等搜索工具,搜索WebService的相關(guān)知識(shí),可以查到N多的網(wǎng)頁(yè),我就是通過(guò)這些網(wǎng)頁(yè)的學(xué)習(xí),逐漸掌握了些WebService的相關(guān)知識(shí)。這里對(duì)那些無(wú)私奉獻(xiàn)知識(shí)的人一并表示感謝。

          網(wǎng)上關(guān)于WebService的例子,多是一些簡(jiǎn)單得不能再簡(jiǎn)單的hello world的例子,簡(jiǎn)單得以至于你對(duì)WebService沒(méi)有什么感覺(jué)。有了WebService的基本知識(shí)后,我一直再想,可以把什么樣的即簡(jiǎn)單又實(shí)用 的東東做成WebService,開(kāi)展示一下其功能特點(diǎn)。今天終于想到一個(gè):計(jì)數(shù)器,計(jì)數(shù)器用得比較多,功能比較獨(dú)立,做成WebService可以一勞 永逸為不同系統(tǒng)(不管是JSP還ASP,這是WebService的突出優(yōu)點(diǎn))、不同應(yīng)用節(jié)省此類編碼工作,可以說(shuō)以后再也不用寫(xiě)計(jì)數(shù)器了。只要用就行 了。

            說(shuō)了這么多廢話,下面我們開(kāi)始。本教程介紹一下WebService環(huán)境搭建、服務(wù)部署的相關(guān)知識(shí),然后介紹一個(gè)計(jì)數(shù)器的開(kāi)發(fā)。

          運(yùn)行圖:



          二、基礎(chǔ)工作


          1.開(kāi)發(fā)環(huán)境
          我使用axis做為Web Service引擎,它是Apache的一個(gè)開(kāi)源web service引擎。它目前最為成熟的開(kāi)源web service引擎之一。下面我主要介紹一下如何使用Axis搭建web service 服務(wù)的環(huán)境。
          ①安裝tomcat5.0應(yīng)用服務(wù)器(也可以裝5.5,不過(guò)我一直在用5.0);
          ②解壓下載( http://ws.apache.org/Axis)后的axis包,將包中axis目錄復(fù)制到tomcat目錄下的webapps目錄下;  
          ③將axis/WEB-INF/lib目錄下類文件復(fù)制到tomcat目錄下的common/lib目錄下;
          ④重新啟動(dòng)tomcat,訪問(wèn)http://localhost:8080/axis/happyaxis.jsp,如果能訪問(wèn),表示安裝成功;
          注意,axis有幾個(gè)可選的包,如email.jar....,你可以找來(lái)放到tomcat目錄下的common/lib目錄下,如果不使用相關(guān)的功能也可以不用。
          這樣,開(kāi)發(fā)環(huán)境就搭建好了。


          2.如何部署Web Service
          部署有三種方式:Dynamic Invocation Interface(DII)、Stubs方式、Dynamic Proxy方式;這里就介紹一下簡(jiǎn)單,也是我使用的方式:DII。
          DII方式中,先寫(xiě)好服務(wù)的JAVA文件(假設(shè)名字為helloworld.java),然后把它(注意是源文件)拷貝到webapps/axis目錄 中,后綴改成jws(此時(shí)文件名為:helloworld.jws),然后訪問(wèn)連接http://localhost: 8080/Axis/helloworld.jws?wsdl,頁(yè)面顯示Axis自動(dòng)生成的wsdl,這樣一個(gè)Web Service就部署好了。怎么樣,是不是很簡(jiǎn)。
          我的計(jì)數(shù)器服務(wù)就是以這種方式部署的,下文中我會(huì)只說(shuō)將計(jì)數(shù)器服務(wù)部署好,你可不要說(shuō):怎么部署,我不會(huì)呀。那在古代就要被打手板了。所以我想,古代只學(xué)四書(shū)五經(jīng)也是件好事呀。現(xiàn)在要學(xué)這么多東西,半天學(xué)不會(huì),手要被打爛了。

          三、計(jì)數(shù)器服務(wù)的編寫(xiě)
          計(jì)數(shù)器大家都知道了,比較簡(jiǎn)單。我的計(jì)數(shù)器也同樣簡(jiǎn)單,有以下功能及特點(diǎn):提供四種計(jì)數(shù)器(總數(shù)器、月計(jì)數(shù)器、周計(jì)數(shù)器及日計(jì)數(shù)器);考慮到Web Service要服務(wù)于多種應(yīng)用,這個(gè)計(jì)數(shù)器還支持多個(gè)用戶;使用XML文件來(lái)記錄數(shù)據(jù)。
          記錄文件名為:d:"counter.xml。注意,此文件在服務(wù)里是硬編碼,如果修改名字,請(qǐng)?jiān)诜?wù)程序中也進(jìn)行相應(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>
          說(shuō)是計(jì)數(shù)器服務(wù),其實(shí)跟編寫(xiě)普通的JAVA應(yīng)用沒(méi)有什么兩樣。我的計(jì)數(shù)器代碼比較簡(jiǎn)單,我就不做過(guò)多的介紹了,把它貼在下面,源碼中有少量注釋,相信大家不看注釋也看得懂。服務(wù)有只有一個(gè)接口:Counter(String name, String password),以后在客戶端拿來(lái)用就可以了。還多說(shuō)一句,我和程序使用到了dom4j解析xml包,要調(diào)試的請(qǐng)自行準(zhǔn)備好jar包。部署方法請(qǐng)參照上文。
          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;
          /**
          *功能:提供計(jì)數(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 {
          //計(jì)數(shù)器文檔,注意名字名路徑。
          private final String FileN = "d:/counter.xml";
          private final static DateFormat DATEFORMATER = DateFormat.getDateTimeInstance();
          //出錯(cuò)的情況下返回的值
          private final static String ERRORINFO="-1;-1;-1;-1";
          public WsCounterByWallimn(){ }


          /**
          *功能:打開(kāi)計(jì)數(shù)器文檔<br/>
          *編碼:王力猛 時(shí)間: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;
          }


          /**
          *功能:取指定名稱計(jì)數(shù)器的詳細(xì)信息,并設(shè)置計(jì)數(shù)器加1。<br/>
          *編碼:王力猛 時(shí)間: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(月計(jì)數(shù)器); dc: day counter(日計(jì)數(shù)器);
          //tc: total counter(總計(jì)數(shù)器); wc: week counter(周計(jì)數(shù)器);
          //rt: registe time登記時(shí)間
          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;//密碼不對(duì),直接返回
          }
          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為空,說(shuō)明沒(méi)有個(gè)名字的計(jì)數(shù)器。則添加一個(gè)。
          if(selitem==null){
          //System.out.println("沒(méi)有找到這個(gè)名字的計(jì)數(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";
          }

          //處理計(jì)數(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("上次登記時(shí)間:"+DATEFORMATER.format(lastdt));
          //System.out.println("本次登記時(shí)間:"+DATEFORMATER.format(currdt));
          if(lastcr.get(Calendar.YEAR)==currcr.get(Calendar.YEAR)){
          //月相同,月計(jì)數(shù)加1
          if(lastcr.get(Calendar.MONTH)==currcr.get(Calendar.MONTH)){
          mc = String.valueOf(Integer.parseInt(mc)+1);
          }
          else{
          mc="1";
          }
          //日相同,日計(jì)數(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{//年不一樣,則月計(jì)數(shù)器、周計(jì)數(shù)器日計(jì)數(shù)器肯定也不一樣。
          mc="1"; dc="1"; wc="1";
          }
          selitem.element("mc").setText(mc);
          selitem.element("wc").setText(wc);
          selitem.element("dc").setText(dc);
          //登記記錄時(shí)間
          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ù)暴露的接口,也就是指定名稱、密碼,返回指定的計(jì)數(shù),并將計(jì)數(shù)器加1。<br/>
          *編碼:王力猛 時(shí)間: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);
          }
          }

          四、客戶端編寫(xiě)
          客戶端是個(gè)頁(yè)面,為了條理清晰,我先寫(xiě)個(gè)調(diào)用Web Service的類,其內(nèi)容如下:
          package com.wallimn.WebService;//調(diào)試請(qǐng)注意包名

          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";//此處注意,請(qǐng)與你的開(kāi)發(fā)環(huán)境匹配
          Service service = new Service();
          Call call = (Call) service.createCall();
          call.setTargetEndpointAddress(new java.net.URL(endpoint));
          call.setOperationName("Counter");
          // 填寫(xiě)你要調(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];
          }
          }

            到頁(yè)面(test.jsp)上就簡(jiǎn)單了,我也把它貼在下面:
          <%@ 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>計(jì)數(shù)器測(cè)試頁(yè)面</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,計(jì)數(shù)器,WebService">
          <meta http-equiv="description" content="計(jì)數(shù)器使用示例">
          </head>

          <body>
          <h2 align="center">計(jì)數(shù)器詳情</h2>
          <hr/>
          總訪問(wèn)量:<%=client.getTc()%> <br/>
          今天訪問(wèn)量:<%=client.getDc()%> <br/>
          本周訪問(wèn)量:<%=client.getWc()%> <br/>
          本月訪問(wèn)量:<%=client.getMc()%> <br/>
          <hr/>
          <p>歡迎交流<br/>博客:http://blog.csdn.net/wallimn<br/>電郵:wallimn@sohu.com</p>
          </body>
          </html>

          五、結(jié)束語(yǔ)

          至此一個(gè)完整計(jì)數(shù)器的Web Service開(kāi)發(fā)、使用的程序的全部完成了。將上面的類、及頁(yè)面部署到任意的一個(gè)上下文中,通過(guò)瀏覽器打開(kāi)test.jsp,就可以看了結(jié)果了。
          歡迎訪問(wèn)我的博客(http://blob.csdn.net/wallimn)留言或發(fā)郵件(wallimn@sohu.com)交流。

          posted on 2008-04-25 17:02 々上善若水々 閱讀(10723) 評(píng)論(2)  編輯  收藏 所屬分類: WebService

          評(píng)論

          # re: Jav  回復(fù)  更多評(píng)論   

          111111111111111
          2012-05-23 14:41 | 1111111111111111111111111

          # re: Java開(kāi)發(fā)WebService實(shí)例--計(jì)數(shù)器  回復(fù)  更多評(píng)論   

          沒(méi)看到WSDL,soap的使用!能否也出一個(gè)例子。
          2012-08-03 10:14 | huigang10086
          主站蜘蛛池模板: 吴堡县| 应城市| 彰化县| 霍山县| 清新县| 枣强县| 固镇县| 清远市| 通城县| 水城县| 武威市| 霸州市| 景宁| 七台河市| 澄江县| 搜索| 屏边| 云阳县| 保山市| 隆安县| 柳河县| 长武县| 社旗县| 崇礼县| 大化| 松滋市| 河东区| 彭州市| 手机| 紫金县| 伊宁市| 宁都县| 加查县| 武安市| 华安县| 延津县| 义马市| 电白县| 广水市| 沅陵县| 开封市|