原貼地址:http://www.wujianrong.com/archives/2006/12/e.html
版本0.1
前段時(shí)間開發(fā)聯(lián)通彩e接口,期間遇到很多問題,在朋友的幫助和自己的摸索中總算完成了接口的開發(fā)。在sp聯(lián)盟論壇上也見到許多同行各種各樣的問題,因此將開發(fā)細(xì)節(jié)整理成文,希望能給與我當(dāng)初一樣 困擾的人以幫助。第一次接觸彩e,感覺有點(diǎn)無從下手,接口指南幾百頁之多,我在開發(fā)的時(shí)候不知道聯(lián)通提供測試的接入平臺(tái)以供調(diào)試,而是對(duì)著接口規(guī)范編寫代碼,然后模擬接口規(guī)則生成數(shù)據(jù),這些都是在單元測試中完成 的,到接入uni-wise測試環(huán)境時(shí),問題多多。
目錄
概述
1. SSO接口
??? 1.1. 傳輸安全
??? 1.2. 生成請(qǐng)求票根
??? 1.3. 解析響應(yīng)票根
2. 預(yù)定接口
??? 2.1. 發(fā)起預(yù)定請(qǐng)求
??? 2.2. 解析uni-wise預(yù)定請(qǐng)求
??? 2.3. 驗(yàn)證請(qǐng)求
??? 2.4. 響應(yīng)預(yù)定請(qǐng)求
3. 預(yù)定取消接口
??? 3.1. 發(fā)起取消請(qǐng)求
??? 3.2. 解析uni-wise取消請(qǐng)求
??? 3.3. 驗(yàn)證請(qǐng)求
??? 3.4. 響應(yīng)請(qǐng)求
4. web push接口
??? 4.1. 提交push
本文以java語言為例,講述彩e接口開發(fā)的點(diǎn)滴。參考的接口指南為《中國聯(lián)通增值業(yè)務(wù)綜合管理及接入平臺(tái)SP接口規(guī)范v1.2》, 文中代碼均經(jīng)過測試,且與uni-wise平臺(tái)能正常運(yùn)行。彩e與sp接口包括:sso接口、預(yù)定接口、取消接口、彩e push接口,取 消push接口,查詢push接口、wap push接口。文中除了wap push接口,其余的將會(huì)一一介紹。 彩e接口的開發(fā)其實(shí)就是sp與聯(lián)通uni-wise平臺(tái)之間的通信,uni-wise平臺(tái)是以web方式工作,因此與sp的交互大部分通 過http+xml協(xié)議傳輸。 筆者在開發(fā)的過程中也曾用C#寫過彩e的部分接口代碼,如有此需求,我也將整理成文。
SSO 是 Single sign on的縮寫,即單點(diǎn)登錄,彩e接口中實(shí)現(xiàn)的功能是,用戶在uni-wise平臺(tái)或sp平臺(tái)只需登錄一次,即可 訪問相關(guān)資源。通過cookies機(jī)制實(shí)現(xiàn)。
出于安全考慮,網(wǎng)絡(luò)的傳輸中經(jīng)常對(duì)傳輸數(shù)據(jù)做加密和編碼處理,彩e接口開發(fā)中的一個(gè)關(guān)鍵點(diǎn)也是對(duì)加密解密的代碼編寫。 其中涉及以下幾種:
1、md5加密,該加密算法是單向加密,即加密的數(shù)據(jù)不能再通過解密還原。相關(guān)類包含在java.security.MessageDigest包中。
2、3-DES加密,該加密算法是可逆的,解密方可以通過與加密方約定的密鑰匙進(jìn)行解密。相關(guān)類包含在javax.crypto.*包中。
3、base64編碼,是用于傳輸8bit字節(jié)代碼最常用的編碼方式。相關(guān)類在sun.misc.BASE64Decoder 和sun.misc.BASE64Encoder 中。
4、URLEncoder編碼,是一種字符編碼,保證被傳送的參數(shù)由遵循規(guī)范的文本組成。相關(guān)類在java.net.URLEncoder包中。
當(dāng)用戶從SP平臺(tái)向uni-wise發(fā)起登錄請(qǐng)求時(shí),SP平臺(tái)需要生成一個(gè)合法的票根,以http協(xié)議傳輸給uni-wise平臺(tái)。 生成請(qǐng)求票根的規(guī)則是:SPTicketRequestValue = URLEncoding{UNICODE(SPCode +“$”)+ Base64 [Encrypt (UNICODE(Seed + “$”)+ Digest)]}
1、生成Seed: returnUrl + "$" + timeStamp;returnUrl為登錄成功后接收uni-wise的響應(yīng)票根鏈接。timeStamp為生成的 時(shí)間戳。
例?1.1.?TimeStamp實(shí)現(xiàn)代碼
public String getTimeStamp()
{
Calendar cal=Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss.SSS");
String timeStamp=formatter.format(cal.getTime());
return timeStamp;
}
2、生成Digest :Base64{Hash[UNICODE(SPCode +"$"+ Seed + "$" + SPKey)]},其中Hash算法采用md5
例?1.2.?Digest的實(shí)現(xiàn)代碼
public String getDigest(String strSrc)
{
//String strSrc = spCode + "___FCKpd___1quot; + getSeed() + "___FCKpd___1quot; + spKey;
BASE64Encoder base64en = new BASE64Encoder();
String digest="";
try
{
byte[] srcMD5 = md5Encrypt(strSrc);
digest = base64en.encode(srcMD5); (1)
}
catch(Exception e){
e.printStackTrace();
}
return digest;
}
private byte[] md5Encrypt(String strSrc)
{
byte[] returnByte = null;
try
{
MessageDigest md5 = MessageDigest.getInstance("MD5"); (2)
returnByte = md5.digest(strSrc.getBytes("GBK"));
}
catch(Exception e)
{
e.printStackTrace();
}
return returnByte;
}
3、生成密鑰匙,用聯(lián)通提供的key,進(jìn)行md5加密。
例?1.3.?得到3-DES的密鑰匙
private byte[] getEnKey(String spKey)
{
byte[] desKey=null;
try
{
byte[] desKey1 = md5Encrypt(spKey);
desKey = new byte[24];
int i = 0;
while (i < desKey1.length && i < 24) {
desKey[i] = desKey1[i];
i++;
}
if (i < 24) { (1)
desKey[i] = 0;
i++;
}
}
catch(Exception e){
e.printStackTrace();
}
return desKey;
}
(1)
|
根據(jù)接口規(guī)范,密鑰匙為24個(gè)字節(jié),md5加密出來的是16個(gè)字節(jié),因此后面補(bǔ)8個(gè)字節(jié)的0
|
4、生成SPTicketRequestValue,URLEncoding{UNICODE(SPCode +“$”)+ Base64 [Encrypt (UNICODE(Seed + “$”)+ Digest)]}, Encrypt算法采用3-DES加密,用md5加密的key作為密鑰匙。
例?1.4.?3-DES加密的實(shí)現(xiàn)代碼
public String getSPTicketRequestValue()
{
String SPTicketRequestValue="";
try{
byte[] src = (getSeed() + "___FCKpd___3quot; + getDigest() ).getBytes("UTF-16LE");
byte[] enKey = getEnKey(spKey);
byte[] encryptedData = Encrypt(src,enKey); (1)
String base64Encrypt = filter(base64en.encode(encryptedData)); (2)
String requestValue=spCode + "___FCKpd___3quot; + base64Encrypt;
SPTicketRequestValue=URLEncoder.encode(requestValue);
}
catch(Exception e){
e.printStackTrace();
}
return SPTicketRequestValue;
}
public byte[] Encrypt(byte[] src,byte[] enKey)
{
byte[] encryptedData = null;
try
{
DESedeKeySpec dks = new DESedeKeySpec(enKey); (3)
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede"); (4)
SecretKey key = keyFactory.generateSecret(dks); (5)
Cipher cipher = Cipher.getInstance("DESede"); (6)
cipher.init(Cipher.ENCRYPT_MODE, key); (7)
encryptedData = cipher.doFinal(src); (8)
}
catch(Exception e)
{
e.printStackTrace();
}
return encryptedData;
}
private String filter(String str)
{
String output = null;
StringBuffer sb = new StringBuffer();
for(int i = 0; i < str.length(); i++)
{
int asc = str.charAt(i);
if(asc != 10 && asc != 13)
sb.append(str.subSequence(i, i + 1));
}
output = new String(sb);
return output;
}
(1)
|
調(diào)用3-DES的加密函數(shù)。
|
(2)
|
base64編碼3-DES的數(shù)據(jù)時(shí),得到的字符串有換行符號(hào),一定要去掉,否則uni-wise平臺(tái)解析票根不會(huì)成功, 提示“sp驗(yàn)證失敗”。在開發(fā)的過程中,因?yàn)檫@個(gè)問題讓我束手無策,一個(gè)朋友告訴我可以問聯(lián)通要一段加密后 的文字,然后去和自己生成的字符串比較,這是個(gè)不錯(cuò)的調(diào)試方法。我最后比較發(fā)現(xiàn)我生成的字符串唯一不同的 是多了換行。我用c#語言也寫了票根請(qǐng)求程序,沒有發(fā)現(xiàn)這個(gè)問題。
|
(3)
|
從原始密匙數(shù)據(jù)創(chuàng)建DESedeKeySpec對(duì)象。
|
(4)
|
創(chuàng)建一個(gè)密匙工廠,然后用它把DESKeySpec轉(zhuǎn)換成一個(gè)SecretKey對(duì)象。
|
(5)
|
根據(jù)密匙工廠,得到一個(gè)密鑰匙實(shí)例。
|
(6)
|
創(chuàng)建Cipher對(duì)象。
|
(7)
|
初始化Cipher對(duì)象(帶入密鑰匙)。
|
(8)
|
執(zhí)行加密操作。
|
為方便調(diào)試給出一段加密后的字符串(用自己的代碼加密同樣的字符串后得到的結(jié)果和給出的結(jié)果進(jìn)行比較)
content = key = 1234;
result = base64(3des(contentbyte,keybyte));
result : "25Pxmw/+/qKg2arQpLdvqQ=="
uni-wise平臺(tái)收到請(qǐng)求票根后會(huì)進(jìn)行解析票根,然后用戶登錄后uni-wise又會(huì)將登錄信息放在響應(yīng)票根中,傳回給請(qǐng)求票根者。 (傳回的地址是請(qǐng)求票根中的”returnUrl“)。傳輸?shù)膮f(xié)議也是http+xml.
1、UrlEncoding的解碼(筆者在測試中發(fā)現(xiàn)在uni-wise測試平臺(tái)首先需要對(duì)所得的票根響應(yīng)串進(jìn)行urlEncoding解碼,這也是接口 遵照接口手冊(cè)進(jìn)行的,但是在uni-wise正式平臺(tái)下得到的響應(yīng)票根已經(jīng)是對(duì)urlEncoding解碼的)。
import java.net.URLDecoder;
URLDecoder.decode(strEncoding);
2、分割響應(yīng)票根,得到加密的字符串。分割很簡單,以"$"為分割符,得到"$"后面的字符串即可。
3、對(duì)加密字符串進(jìn)行base64解碼。
import sun.misc.BASE64Decoder;
BASE64Decoder base64Decode = new BASE64Decoder();
base64Decode.decodeBuffer(strEnBase64);
4、對(duì)base64解碼的值進(jìn)行3-DES解密(密鑰匙等同于加密的密鑰匙)。
public String deCrypt(byte[] debase64)
{
String strDe = null;
Cipher cipher = null;
try
{
cipher=Cipher.getInstance("DESede");
byte[] key = getEnKey(spKey); (1)
DESedeKeySpec dks = new DESedeKeySpec(key);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
SecretKey sKey = keyFactory.generateSecret(dks);
cipher.init(Cipher.DECRYPT_MODE, sKey); (2)
byte ciphertext[] = cipher.doFinal(debase64);
strDe = new String(ciphertext,"UTF-16LE");
}
catch(Exception ex)
{
strDe = "";
ex.printStackTrace();
}
return strDe;
}
(1)
|
得到密鑰匙,具體實(shí)現(xiàn)請(qǐng)參考請(qǐng)求票根部分
|
(2)
|
加密、解密其實(shí)就是指定這個(gè)類型 Cipher.ENCRYPT_MODE 或 Cipher.DECRYPT_MODE
|
5、通過"$"分割解密的字符串,然后取得對(duì)應(yīng)的信息,如MDN,UserId等。如果SP需要記錄用戶信息,應(yīng)該在解析票根后 持久存儲(chǔ)。然后根據(jù)實(shí)際需要將用戶信息加入cookies.以實(shí)現(xiàn)SSO。
2.1.?發(fā)起預(yù)定請(qǐng)求
用戶可以從SP平臺(tái)和uni-wise平臺(tái)發(fā)起預(yù)定請(qǐng)求,當(dāng)從SP發(fā)起預(yù)定請(qǐng)求時(shí),SP平臺(tái)需要 構(gòu)建預(yù)定請(qǐng)求的數(shù)據(jù),以htpp協(xié)議傳輸給uni-wise.請(qǐng)求數(shù)據(jù)的構(gòu)建有兩種方式一種是 service方式,一種是product方式.根據(jù)實(shí)際情況構(gòu)建請(qǐng)求參數(shù)。 http://接入平臺(tái)的URL?SPCode=A&ServiceCode=B&ReturnURL=C (service方式) http://接入平臺(tái)的URL?SPCode=A&ProductCode=B&ReturnURL=C (product方式)
2.2.?解析uni-wise預(yù)定請(qǐng)求
所有的預(yù)定操作都是鏈接到uni-wise預(yù)定平臺(tái),然后用戶在此發(fā)生預(yù)定關(guān)系,uni-wise構(gòu)建 預(yù)定信息通知SP平臺(tái),根據(jù)SP的響應(yīng)結(jié)果,決定預(yù)定動(dòng)作成功與否。uni-wise要將預(yù)定信息 通知SP,因此需要預(yù)先知道SP接收預(yù)定的鏈接,這是在申請(qǐng)彩e業(yè)務(wù)時(shí)完成。
例?2.1.?解析預(yù)定請(qǐng)求
InputStream subscriptionRequestStream = request.getInputStream(); (1)
PraseXml(subscriptionRequestStream); (2)
(1)
|
uni-wise將預(yù)定信息以輸出流傳輸?shù)絊P平臺(tái),SP用HttpServletRequest得到輸入流。
|
(2)
|
ParseXml為解析xml的函數(shù)。與解析普通的xml一樣,因此在此不再描述其實(shí)現(xiàn)方法。
|
得到預(yù)定請(qǐng)求信息后,應(yīng)該對(duì)其數(shù)據(jù)進(jìn)行驗(yàn)證,根據(jù)驗(yàn)證的結(jié)果返回相應(yīng)的信息給uni-wise平臺(tái)。
if (mdn == null || mdn.trim().equals(""))
{
errorCode = "16842754";
errorInfo = "cannot find MDN";
}
if ( spCode == null || spCode.trim().equals(""))
{
errorCode = "16973826";
errorInfo = "cannot find SPCode";
}
if (productCode == null || productCode.trim().equals(""))
{
errorCode = "17104898";
errorInfo = "cannot find ProductCode";
}
if (transactionID == null || transactionID.trim().equals(""))
{
errorCode = "17170434";
errorInfo = "cannot find TransactionID";
}
2.4.?響應(yīng)預(yù)定請(qǐng)求
SP接收到uni-wise預(yù)定請(qǐng)求信息后進(jìn)行驗(yàn)證核對(duì),然后響應(yīng)請(qǐng)求,傳輸協(xié)議為http+xml。 uni-wise得到響應(yīng)后執(zhí)行預(yù)定動(dòng)作,返回給用戶預(yù)定相關(guān)信息。SP處理請(qǐng)求結(jié)果有成功 和失敗兩種情況。
例?2.2.?請(qǐng)求成功的響應(yīng)格式
StringBuffer sb = new StringBuffer();
sb.append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");
sb.append("<U-MAX>\n");
sb.append("<PreSubscriptionNotify>\n");
sb.append("<MDN>" + getMdn() + "</MDN>\n");
sb.append("<SPCode>" + getSpCode() + "</SPCode>\n");
sb.append("<ProductCode>" + getProductCode() + "</ProductCode>\n");
sb.append("<TransactionID>" + getTransactionID() + "</TransactionID>\n");
sb.append("</PreSubscriptionNotify>\n");
sb.append("</U-MAX>");
String strResponse = new String(sb);
例?2.3.?請(qǐng)求失敗的響應(yīng)格式
StringBuffer sb = new StringBuffer();
sb.append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");
sb.append("<U-MAX>\n");
sb.append("<ValidError>\n");
sb.append("<ValidErrorCode>");
sb.append(getErrorCode());
sb.append("</ValidErrorCode>");
sb.append("<ValidErrorInfo>");
sb.append(getErrorInfo());
sb.append("</ValidErrorInfo>");
sb.append("</ValidError>\n");
sb.append("</U-MAX>");
String strResponse = new String(sb);
用戶可以從SP平臺(tái)和uni-wise平臺(tái)發(fā)起取消請(qǐng)求,當(dāng)從SP發(fā)起取消請(qǐng)求時(shí),SP平臺(tái)需要 構(gòu)建取消請(qǐng)求的數(shù)據(jù),以htpp協(xié)議傳輸給uni-wise.請(qǐng)求數(shù)據(jù)的構(gòu)建有兩種方式一種是 service方式,一種是product方式.規(guī)則同預(yù)定請(qǐng)求一致。
3.2.?解析uni-wise取消請(qǐng)求
所有的取消操作也是定向到uni-wise平臺(tái),然后用戶在此執(zhí)行取消動(dòng)作,uni-wise接收 到用戶取消動(dòng)作后將取消信息通知SP平臺(tái),根據(jù)SP的響應(yīng)結(jié)果,決定取消動(dòng)作成功與否。 SP的取消接收鏈接,也是在申請(qǐng)彩e業(yè)務(wù)時(shí)完成。實(shí)現(xiàn)代碼與解析預(yù)定請(qǐng)求代碼一致,在此 不再重復(fù)。
請(qǐng)參考預(yù)定請(qǐng)求章節(jié)的相應(yīng)內(nèi)容。
例?3.1.?請(qǐng)求處理成功的響應(yīng)
StringBuffer sb = new StringBuffer();
sb.append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");
sb.append("<U-MAX>\n");
sb.append("<SubscriptionCancel>\n");
sb.append("<MDN>" + getMdn() + "</MDN>\n");
sb.append("<SPCode>" + getSpCode() + "</SPCode>\n");
sb.append("<ProductCode>" + getProductCode() + "</ProductCode>\n");
sb.append("<TransactionID>" + getTransactionID() + "</TransactionID>\n");
sb.append("</SubscriptionCancel>\n");
sb.append("</U-MAX>");
String strResponse = new String(sb);
例?3.2.?請(qǐng)求處理失敗的響應(yīng)
StringBuffer sb = new StringBuffer();
sb.append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");
sb.append("<U-MAX>\n");
sb.append("<ValidError>\n");
sb.append("<ValidErrorCode>");
sb.append(getErrorCode());
sb.append("</ValidErrorCode>");
sb.append("<ValidErrorInfo>");
sb.append(getErrorInfo());
sb.append("</ValidErrorInfo>");
sb.append("</ValidError>\n");
sb.append("</U-MAX>");
String strResponse = new String(sb);
發(fā)送彩e,先提交到uni-wise平臺(tái)的push接口,然后再由uni-wise push到IMAP平臺(tái),如圖:
SP 提交信息到 uni-wise Push接口的數(shù)據(jù)分包頭和包體,其中包體以MIME格式傳輸。
1、構(gòu)建包頭: SP的企業(yè)代碼(不加密)+ SP的密鑰(加密)+付費(fèi)代碼(加密)+條件類別(加密)+條件代碼(加密) +發(fā)送方式(加密)+[發(fā)送開始時(shí)間(加密)+截止時(shí)間(加密)]+ 計(jì)費(fèi)手機(jī)號(hào)碼(加密)+ MIME包體 中的邊界字段Boundary(加密)
import java.net.HttpURLConnection;
import java.net.URL;
private Url url = null;
HttpURLConnection conn = null;
//先建立URL長連接
public void connectUrl(String strUrl)
{
try
{
url = new URL(strUrl);
conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("post");
}
catch(Exception ex)
{
}
}
//設(shè)置包頭
public void setHeader()
{
conn.setRequestProperty("SPCode", spCode);
conn.setHeader("EncryptSPKey",enKey);
conn.setHeader("FeeCode",enFeeCode );
conn.setHeader("ConditionType",enConditionType);
conn.setHeader("ConditionCode", enConditionCode);
conn.setHeader("SendType", enSendType);
conn.setHeader("StartTime", enStartTime);
conn.setHeader("EndTime",enEndTime);
conn.setHeader("ThirdPartyPayPhone",enThirdPartyPayPhone);
conn.setHeader("Boundary", enBoundary);
}
包頭中除了spcode不用加密,其余的都遵行base64(3des(contentbyteplus,keybyte))加密方式。 加密的實(shí)現(xiàn)代碼和前面章節(jié)描述的一致。
2、構(gòu)建包體
MIME (Multipurpose Internet Mail Extensions,多目的Internet郵件擴(kuò)展)是創(chuàng)建用于電子郵件交換, 網(wǎng)絡(luò)文檔,及企業(yè)網(wǎng)和Internet上的其他應(yīng)用程序中的文件格式的規(guī)范.
例?4.1.?構(gòu)建MIME格式的包體
private MimeMessage mime;
//構(gòu)造MIME格式的包體
private void setMimeMessage()
{
try
{
mime.setFrom(new InternetAddress(strFrom)); (1)
mime.addRecipient(javax.mail.Message.RecipientType.TO, new InternetAddress(strTo)); (2)
mime.setSubject(strSubject,"UTF-8"); (3)
mime.setSentDate(new Date());
mime.setContent(getMimeMultipart());
}
catch(Exception ex)
{
}
}
private MimeMultipart getMimeMultipart()
{
MimeMultipart mimeMultipart = new MimeMultipart();
MimeBodyPart mimeBodyPart = new MimeBodyPart();
try
{
mimeBodyPart.setText((String)mimeBodyText.get(i),"UTF-8"); (4)
mimeMultipart.addBodyPart(mimeBodyPart);
Vector filePathes = getFilePaths();
for(int i = 0; i < filePathes.size(); i++)
{
String filePath = (String)filePathes.get(i);
javax.activation.DataSource datasource = new FileDataSource(filePath);
MimeBodyPart mimeFile = new MimeBodyPart();
mimeFile.setDataHandler(new DataHandler(datasource));
mimeFile.setFileName((new File(filePath)).getName());
mimeMultipart.addBodyPart(mimeFile);
}
}
catch(Exception e)
{
}
return mimeMultipart;
}
(1)
|
設(shè)置發(fā)送地址,在手機(jī)上顯示發(fā)送方為該值
|
(2)
|
設(shè)置要發(fā)送到的手機(jī)號(hào)
|
(3)
|
手機(jī)上顯示的標(biāo)題值,經(jīng)過筆者測試如果不指定編碼為UTF-8,手機(jī)上顯示為亂碼(測試手機(jī)京瓷), 不知道其他手機(jī)是否有這種情況。
|
(4)
|
手機(jī)上顯示的正文,經(jīng)過筆者測試如果不指定編碼為UTF-8,手機(jī)上顯示為亂碼(測試手機(jī)京瓷)。
|
3、提交內(nèi)容到push接口
public void write(String body)
{
java.io.OutputStream outStream = conn.getOutputStream(); (1)
DataOutputStream dataOutStream = new DataOutputStream(outStream);
dataOutStream.writeBytes(body);
dataOutStream.flush();
dataOutStream.close();
}
(1)
|
這里的conn對(duì)象是引用第一步中實(shí)例的URLConnection對(duì)象,已經(jīng)處于open狀態(tài)。
|
4、讀取push響應(yīng)信息
提交信息與返回信息是實(shí)時(shí)的,因此應(yīng)該在提交后即實(shí)現(xiàn)讀取操作。
public String responsePush()
{
StringBuffer sb = null;
try
{
sb = new StringBuffer("");
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
for(String line = null; (line = rd.readLine()) != null;)
sb.append(line);
rd.close();
}
catch(Exception ex)
{
}
return new String(sb);
}
responsePush()得到的是一個(gè)標(biāo)準(zhǔn)的xml字符串。格式請(qǐng)參考接口指南。code節(jié)點(diǎn)的值為0代表push成功。
posted on 2007-03-05 16:35
OMG 閱讀(328)
評(píng)論(0) 編輯 收藏 所屬分類:
SSO/加密