天天看點

十幾年前的一段20天項目經曆往事

時間轉眼過去一年多了 ,我離開 H公司也已經一年多了 。往事不堪回首 ,世事也總是以成敗論英雄的 ,因為我知道前面的一個接口項目先後導緻 3個人離職 ,2個人被處罰 ;而這個項目隻有我一個人 ,在項目割接的當天我總算不辱使命完成了 ;我既是成功者 ,也是失敗者 ;我證明了自己是可以笑着離開H公司的 。其實我一直不太想寫出來,畢竟申請離職也不是一件很光彩的事情。

2006年是全國号碼百事通風起雲湧的一年,而Z電信公司正是第一個勇于吃螃蟹的人且率業界之先的公司;我就是2006年初被派到電信公司跟着另外一個項目經理讨論接口需求的(原因很簡單,為了避免壟斷,Z電信公司把省中心業務給了Q公司,而12各地市給了H公司是以在省中心和地市之間需要通過Web Service接口進行互連),其實在這之前的一年内我是做BI和資料庫優化的,對于所謂的接口和114是一竅不通的。估計看出了點苗頭,項目經理當了甩手掌櫃,隻好由我一個人來負責此事了。

2月8号,春節還沒過完,我便來到了H市,經過反複的讨論和調研,其實我做的工作隻是号碼百事通業務的一部分,即實作對現有知識庫的智能通路,當然通路是需要通過接口來完成的,此外還要實作一定的功能,例如發送短信,來電轉接,記錄計費資訊,當然也是通過接口來實作。

十幾年前的一段20天項目經曆往事

其實我很早就已經有了初步的想法,最簡單的就是我自動生成存儲過程和自動生成html網頁(其實基本上已經實作了),但是了解到存儲過程需要在友商的資料庫中建立,以及考慮到相關的風險和雙方的劍拔弩張的氣氛,這顯然是不可能實作的任務。現在隻能自己另辟蹊徑建一個獨立的Web Server伺服器,通過正在流行的Web Service接口來實作這一切功能了。

上述的圖檔顯示的架構源于我對BI和資料庫的了解,隻要有一個開放的資料字典,基本上就可以實作任何的自定義查詢和自定義組合如果複雜一點的話,甚至可以實作一套簡單的報表系統。正是基于這樣的想法和相關資料結構開始和Q公司談相關的接口。但是有幾個問題一直纏繞着我:

1. 采用什麼樣的 WEB伺服器 ,Tomcat還是 Resin

2. 采用什麼樣的程式設計工具 ,Jbuilder還是 Eclipse?

3. Web Service接口到底是什麼 ,如何完成釋出和調用

4. 采用什麼樣的 Java架構 (Struct還是 Spring還是純粹的 JSP)

5. Ajax技術

6. 關于樹型目錄的實作 (需要高效 ,無延遲 )

7. 最難纏的還是和 Q公司的談判和交流 (要面對對方 5,6人的輪番轟炸 )

也許對于java高手而言這根本不算什麼,可對于我而言,那簡直是一場噩夢,我的Java水準和HTML水準僅限于寫一些簡單的JSP頁面和JavaBean完成簡單的封裝,我自認為自己水準最高的還是HTML和javascript水準,不管多麼複雜的頁面和frame我都可以整理出一個頭緒出來。我從來不是一個唯工具論者,我相信任何工具都隻是手段,而條條馬路都可以通向羅馬的。可惜給我留的時間太短了,隻有3周的時間。說真的,那時候天天對着西湖的美景,沒有一絲絲觀看的心情,真的想撲通一聲跳下去,一了百了。

言規正傳首先需要确定系統大體的架構,Tomcat和Eclipse都是開源的架構,不涉及到版權和費用,從網上down的Tomcat,呵呵,如果Z電信公司知道了非要氣個半死不可。按照從網上搜尋的資料把Tomcat和Eclipse環境配置完畢,然後按照公司的java高手指點,配置架構。Spring

關于Spring架構的配置

Spring是一個開源架構,是為了解決企業應用程式開發複雜性而建立的。架構的主要優勢之一就是其分層架構,分層架構允許您選擇使用哪一個元件,同時為J2EE應用程式開發提供內建的架構。

其實在這樣的小型系統裡,它提供了一個便于調試和控制的開關;至少在本文中,是為了解決無法使用接口環境進行調試的時候,改用資料庫接口方式。

<!-- ====== 如果是和 soap 接口連接配接,請去掉該 bean 的注釋 ===========-->
<bean id="QueryData" class="com.xxx.yyy.inf.SoapInterface">
<property name="endpoint">
<value>http://192.168.1.2/Forxxx/ForQuery.asmx</value>
</property>
<property name="nameSpace">
<value>http://tempuri.org/</value>
</property>
</bean>
<!-- =========== 如果是和 db 接口連接配接測試 , 請去掉該 bean 的注釋 =====-->
<!--
<bean id="QueryData" class="com.xxx.yyy.inf.DBInterface">
<property name="dataSource">
<ref local="DataSource"/>
</property>
</bean>
-->           

複制

關于樹型目錄的架構

嚴格說來寫一個樹型目錄的架構是一項非常複雜的工作,樹型目錄的實作有兩種方式:全部畫出所有的樹節點和當觸發時實時畫出下一層節點。前一種的實作相對簡單一些,但是當節點數量超過1000之後,采用遞歸算法會導緻頁面首次顯示時出奇的緩慢,我曾經做過對js腳本和相應的存儲過程做過調優,但是效果還是不甚理想;觸發時才實時畫出下一層節點技術難度很高,還好公司有比較現成的架構,光java類和接口就有10幾個,完全閱讀并了解顯然是不現實的,隻能通過摸索把先有的業務和原來的接口進行不斷的測試,花費了一天時間才得以完成。

關于 Web Service

Web Service是一種可以接收從Internet或者Intranet上的其它系統中傳遞過來的請求,輕量級的獨立的通訊技術。總得來講它能夠突破平台限制,穿越企業防火牆,通過開放的接口和認證實作資訊的共享和傳遞。

關于 WSDL

對于商業使用者來說,要找到一個自己需要使用的服務,他必須知道如何來調用。WSDL(Web Services Description Language) 規範是一個描述接口,語義以及Web服務為了響應請求需要經常處理的工作的XML文檔。這将使簡單地服務友善,快速地被描述和記錄。

對于 .Net的WSDL調用來說是很簡單的,例如一個簡單的VBS腳本

Dim obj
set obj=createobject("MSSOAP.SoapClient30")
obj.MSSoapInit "QueryService.wsdl"
MsgBox obj.getPhoneByName("0578","XXX 機關 ",10)           

複制

但是對于java而言調用一個.Net産生的WSDL簡直被折磨了半死,Q公司又不肯提供技術支援,不斷的進行調試跟蹤最後才發現是一個setEncodingStyle參數設定的問題。

public class CpSpInterface {
protected Log logger = LogFactory.getLog(this.getClass());
private String endpoint = "http://192.168.1.2/Service1.asmx";
private String nameSpace = "GetSPInfo";
public String callGetIndexByType(String strTypeID, String strParaList,String strResultType)
{
String ret = "<?xml version="1.0" encoding="gb2312" ?><root status="1" lines="0"></root>";
try {
String methodName = "GetIndexByType";
Service service = new Service();
Call call = (Call) service.createCall();
call.setTimeout(new Integer(120000));
call.setTargetEndpointAddress(new java.net.URL(endpoint));
call.setUseSOAPAction(true);
call.setSOAPActionURI(nameSpace + "/GetIndexByType");
call.setOperationStyle(org.apache.axis.constants.Style.WRAPPED);
call.setEncodingStyle("literal");
call.setOperationName(new QName(nameSpace, methodName));
StringHolder holder = new StringHolder("0");
// Set Call Parameter
call.addParameter(new QName(nameSpace, "strTypeID"),
Constants.XSD_STRING, ParameterMode.IN);
………… 略
//Set back Parameter
call.setReturnType(Constants.XSD_STRING);
ret = (String) call.invoke(new Object[] { strTypeID, strParaList,strResultType });
ret = ret.replaceAll("utf-8","gb2312");
logger.debug("ret = "+ret);
logger.info("return errorcode = " + holder.value);
} catch (Exception e) {
logger.error("Error " + e);
}
return ret;
}
}           

複制

關于Ajax

單純從Ajax本身來說,其最主要不過就是解決在網頁上一個無重新整理擷取資料的問題,再加上減少了資料的傳輸量,将資料解析的工作推到了用戶端,的确能解決很多傳統的問題,很友善的實作一些動态效果。Ajax的應用本來是為了增強使用者體驗,于是就有了一個新的名詞WEB2.0.

其實在該系統的應用很簡單即擷取到COM元件傳過來的主叫号碼和被叫号碼,記錄到Session中,具體的JSP頁面是一個非常簡單的頁面,就不必再寫了,呵呵

Xh = new ActiveXObject(“Microsoft.XMLHTTP");
var link = "./beginSession.do?callID="+callid+"&callerNo="+callerno+"&calleeNo="+calleeno;           

複制

關于交流

其實整個系統過程中,最頭疼的問題還是和Q公司的交流,Q公司是一家新型的在電信領域剛剛展露頭腳的公司,面對這樣一個揚名立萬的機會,當然不會錯過了,于是派了40個現場人員進行現場開發,真不知道他們的項目成本控制是怎麼做的;而我方總計也隻有3個人,參與接口的讨論最多也隻有2個人;每次都要面對對方嗡嗡的一群人的輪番轟炸;最後不得已拉着Z電信公司一起參與讨論。還好對方也有很多的軟肋(雙方都要提供一些接口),才不至于被折磨的太慘。

2006年2月28日,是個特殊的日子,當天下午Q公司終于把接口調試完畢,當天晚上我也把相應的功能完善起來,終于到了一個milestone。彷佛經曆了一場噩夢。連續3周的時間,每天從早9點到晚上3點不停的寫代碼,調試代碼,查詢資料,讨論需求;極度厭煩了這樣的生活,最後終于借口身體不好,倉惶逃離了這個地方,把工作交接給一位新來的同僚,他又繼續維護了6個月。我回去後休整了1個多月,身體仍然比較虛弱,再過了一個月就黯然離職了。