java web service 开发 具体实例
来源:互联网 发布:淘宝什么时候搞大打折 编辑:程序博客网 时间:2024/06/11 02:41
以一个工作中编写的安全域信息同步为例进行描述;
安全域信息同步其实就是一个XML文件的传输,WEB SERVICE 本质上就是通过XML进行数据的传输.
传输的XML格式如下:
<?xml version="1.0" encoding="UTF-8" ?>
- <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
- <SOAP-ENV:Body>
- <simota:SynSecurityDomain xmlns:simota="http://www.chinamobile.com">
<simota:SeqNum>1111</simota:SeqNum>
<simota:SessionID>1111</simota:SessionID>
<simota:SynType>01</simota:SynType>
- <simota:SecurityDomain>
<simota:AppAID>123456789</simota:AppAID>
<simota:InstallParams>222222</simota:InstallParams>
<simota:MinAppSize>33</simota:MinAppSize>
<simota:ManageMaxSize>44</simota:ManageMaxSize>
<simota:ManageMinSize>55</simota:ManageMinSize>
<simota:DomainType>66</simota:DomainType>
<simota:DeleteRule>77</simota:DeleteRule>
<simota:SIN>8</simota:SIN>
<simota:TAR>99</simota:TAR>
</simota:SecurityDomain>
</simota:SynSecurityDomain>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
根据该XML需要编写响应的解析类来接收XML文件传输过来的数据:
解析类如下:
package com.watchdata.raadtinterface.common.syn;
import org.jdom.Element;
import org.jdom.Namespace;
import org.apache.commons.logging.*;
import com.watchdata.raadtinterface.common.*;
public class SynSecurityDomainRequest
implements BaseMsg {
public SynSecurityDomainRequest() {
}
private String seqNum;
private String sessionID;
private String synType;
private SecurityDomainBean securityDomain;
/**
* getObject
* 安全域信息同步
* @param methodElement Element
* @param nameSpace Namespace
* @return BaseMsg
*/
public BaseMsg getObject(Element methodElement, Namespace nameSpace) {
System.out.println("SynSecurityDomainRequest============");
Log log = LogFactory.getLog(getClass().getName());
SynSecurityDomainRequest syndomain = new SynSecurityDomainRequest();
Element SeqNum = methodElement.getChild("SeqNum", nameSpace);
log.info("SeqNum==" + SeqNum.getText());
Element SessionID = methodElement.getChild("SessionID", nameSpace);
log.info("SessionID==" + SessionID.getText());
Element SynType = methodElement.getChild("SynType", nameSpace);
log.info("SynType==" + SynType.getText());
Element SecurityDomain = methodElement.getChild("SecurityDomain", nameSpace);
Element AppAID = SecurityDomain.getChild("AppAID", nameSpace);
log.info("-------AppAID==" + AppAID.getText());
Element InstallParams = SecurityDomain.getChild("InstallParams", nameSpace);
log.info("--InstallParams---" + InstallParams.getTextTrim());
Element MinAppSize = SecurityDomain.getChild("MinAppSize", nameSpace);
log.info("MinAppSize==" + MinAppSize.getText());
Element ManageMaxSize = SecurityDomain.getChild("ManageMaxSize", nameSpace);
log.info("ManageMaxSize=" + ManageMaxSize.getText());
Element ManageMinSize = SecurityDomain.getChild("ManageMinSize", nameSpace);
log.info("ManageMinSize" + ManageMinSize.getText());
Element DomainType = SecurityDomain.getChild("DomainType", nameSpace);
log.info("DomainType=" + DomainType.getText());
Element DeleteRule = SecurityDomain.getChild("DeleteRule", nameSpace);
log.info("DeleteRule==" + DeleteRule.getText());
Element SIN = SecurityDomain.getChild("SIN", nameSpace);
log.info("SIN=" + SIN.getText());
Element TAR = SecurityDomain.getChild("TAR", nameSpace);
log.info("TAR==" + TAR.getText());
if (null == SeqNum || null == SessionID ||
null == SynType || null == AppAID || null == InstallParams ||
null == MinAppSize || null == ManageMaxSize || null == ManageMinSize ||
null == DomainType || null == DeleteRule ||
null == SIN || null == TAR
) {
log.error("数据转换模块传的参数错误!");
return null;
}
syndomain.setSeqNum(SeqNum.getTextTrim());
syndomain.setSessionID(SessionID.getTextTrim());
syndomain.setSynType(SynType.getTextTrim());
SecurityDomainBean sdbean = new SecurityDomainBean();
sdbean.setAppAID(AppAID.getTextTrim());
sdbean.setDeleteRule(DeleteRule.getTextTrim());
sdbean.setDomainType(DomainType.getTextTrim());
sdbean.setInstallParams(InstallParams.getTextTrim());
sdbean.setManageMaxSize(Long.parseLong(ManageMaxSize.
getTextTrim()));
sdbean.setManageMinSize(Long.parseLong(ManageMinSize.
getTextTrim()));
sdbean.setMinAppSize(Long.parseLong(MinAppSize.
getTextTrim()));
sdbean.setSin(SIN.getTextTrim());
sdbean.setTar(TAR.getTextTrim());
syndomain.setSecurityDomain(sdbean);
return syndomain;
}
public SecurityDomainBean getSecurityDomain() {
return securityDomain;
}
public String getSeqNum() {
return seqNum;
}
public String getSessionID() {
return sessionID;
}
public String getSynType() {
return synType;
}
public void setSecurityDomain(SecurityDomainBean securityDomain) {
this.securityDomain = securityDomain;
}
public void setSeqNum(String seqNum) {
this.seqNum = seqNum;
}
public void setSessionID(String sessionID) {
this.sessionID = sessionID;
}
public void setSynType(String synType) {
this.synType = synType;
}
}
其中类中实现的一个类BaseMsg 是一个接口:
package com.watchdata.raadtinterface.common;
import org.jdom.*;
public abstract interface BaseMsg {
public abstract BaseMsg getObject(Element methodElement, Namespace nameSpace);
}
每个解析类需要实现这个接口,然后通过接口中定义的方法getObject 来获得解析的结果数据BEAN
基本数据准备好后需要提供一个servlet,在这里我定义为InterfaceServiceServlet
package com.watchdata.raadtinterface.center;
import javax.servlet.*;
import java.io.*;
import javax.xml.messaging.JAXMServlet;
import javax.xml.messaging.ReqRespListener;
import javax.xml.soap.*;
import java.util.*;
import javax.servlet.*;
import javax.xml.soap.*;
import org.apache.commons.logging.*;
import org.bouncycastle.crypto.*;
import javax.xml.transform.stream.*;
import org.apache.commons.logging.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* <p>Title:RAADataTrans作为服务器端的接口发布类,用JAXM实现 </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2007</p>
* <p>Company: </p>
* @author liwei 080912
* @version 1.0
*/
public class InterfaceServiceServlet
extends JAXMServlet
implements ReqRespListener {
public static final String ATTACH_SEPERATOR = ",";
ServletConfig config;
public void init(ServletConfig servletconfig) throws ServletException {
super.init(servletconfig);
config = servletconfig;
}
* 接口入口,所有JAXM实现webservice的接口
* @param message SOAPMessage
* @return SOAPMessage
*/
public SOAPMessage onMessage(SOAPMessage message) {
Log log = LogFactory.getLog(getClass().getName());
/*获取接口信息*/
SOAPMessage resultSOAP = null;
ReqDistribute reqdis = new ReqDistribute();
try {
resultSOAP = reqdis.doRequest(message, config);
}
catch (Exception ex) {
ex.printStackTrace();
log.error(ex.getMessage(), ex);
}
return resultSOAP;
}
}
/**
* 按照SOAP报文中要访问的不同方法,对数据进行分发
* @param soapMsg String
* @throws CryptoException
* @throws IOException
* @return SOAPMessage
*/
public SOAPMessage doRequest(SOAPMessage message, ServletConfig servletconfig) throws
CryptoException,
IOException {
Communal comm = new Communal();
Log log = LogFactory.getLog(getClass().getName());
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
SOAPMessage resultSOAP = null;
int result = -2;
try {
//获取附件
int attachmentCount = message.countAttachments();
log.info("获取附件--" + attachmentCount);
Iterator it = message.getAttachments();
String filePath=”E://test”;
//删除所有的附件
message.removeAllAttachments();
message.saveChanges();
message.writeTo(outStream);
byte[] soapData = outStream.toByteArray();
outStream.close();
String soapMsg = new String(soapData, "UTF-8");
log.info(soapMsg);
/*有附件 处理附件吧附件存储起来*/
if (attachmentCount > 0) {
log.info("deal ..");
result = comm.dealAttachments(it, filePath);
}
}
catch (Exception ex) {
ex.printStackTrace();
log.error(ex.getMessage(), ex);
}
String soapMsg = comm.sopeToString(message);
InterfaceService interfaceS = new InterfaceService();
log.info("---begin----doRequest---");
String resultMsg = "";
if (soapMsg == null || soapMsg.length() < 10) {
return null;
}
if (soapMsg.indexOf("SynSecurityDomain") != -1) { //安全域信息同步
resultMsg = new SynSDOper().SynSDserver(requestXml);//这里需要导入该类
//具体逻辑处理
}
// else if (soapMsg.indexOf("LogoutServer") != -1) { //退出登录
// resultMsg = interfaceS.LogoutServer(soapMsg);
// }
// else if(soapMsg.indexOf("DataConvertRequest") != -1){ //数据转换模块到数据传输模块的请求数据
// resultMsg = interfaceS.DataConvertRequest(soapMsg);
// }
//使用正则表达式 去掉> <中间的空格和所有的回车
resultMsg = comm.replaceUseReg(resultMsg, ">//s*<", "><");
resultMsg = comm.replaceUseReg(resultMsg, "//n", "");
SOAPMessage resultSoap = comm.strToSOAPMessage(resultMsg);
log.info("----resultSoap-----" + resultSoap);
log.info("--servletconfig--" + servletconfig.getServletName());
return resultSoap;
}
/**
* 处理文件,根据路径和文件名保存附件
处理附件,把附件保存某个路径下
* */
private boolean dealAttachments (Iterator it, String filePath) {
Log log = LogFactory.getLog("处理附件");
// String fileNames[] = fileName.split(",");
String tempName = "";
int i = 0;
while (it.hasNext()) {
try {
int num = i++;
File filedir = new File(filePath);
if (!filedir.exists()) {
filedir.mkdirs();
filedir = null;
}
AttachmentPart attachPart = (AttachmentPart) it.next();
tempName = attachPart.getContentId();
//如果有多个附件,附件的content_id 为文件名字
// if (fileNames.length > 1) {
// fileNames[num] = tempName;
// }
InputStream inStream = attachPart.getDataHandler().getInputStream();
FileOutputStream fileOutStream = new FileOutputStream(filePath +
tempName);
byte[] data = new byte[1024];
int length = 0;
while ( (length = inStream.read(data)) != -1) {
fileOutStream.write(data, 0, length);
}
fileOutStream.flush();
fileOutStream.close();
inStream.close();
}
catch (SOAPException ex) {
ex.printStackTrace();
return false;
}
catch (Exception ex) {
log.error(ex.getMessage());
return false;
}
}
return true;
}
服务端共有三个JAXM Servlet,它们分别提供三种不同的查询服务。
由于使用了点对点的消息模型,故服务端需要实现javax.xml.messaging. ReqRespListener接口,并且需要继承javax.xml.messaging.JAXMServlet类。javax.xml.messaging.JAXMServlet是一个Servlet,它为开发消息服务的Servlet提供了一个框架。需要指出的是,javax.xml.messaging. ReqRespListener接口定义了一个
其中servlet中的onMessage方法就像servlet中定义的一个doGet() 或doPost()方法,当你请求该servlet时,系统会自动调用该方法,所以在的定义servlet时需要继承JAXMServlet并实现ReqRespListener,
安全域同步类:
package com.watchdata.raadtinterface.center;
import org.apache.commons.logging.*;
import java.io.*;
import javax.xml.soap.*;
import com.watchdata.raadtinterface.common.syn.*;
import com.watchdata.raadtinterface.common.*;
/**
* <p>Description: 安全域同步处理类 </p>
* @
* @version 1.0
*/
public class SynSDOper {
public SynSDOper() {
}
/**
*
*/
Log log = LogFactory.getLog(getClass().getName());
public String SynSDserver(String requestXml) {
//对传来的xml信息解析,并封装为SynSecurityDomainRequest对象
SynSecurityDomainRequest requestObj = (SynSecurityDomainRequest)
SOAPRequest.getMoRequest("SynSecurityDomain",
requestXml, SOAPRequest.raaNameSpace,
new SynSecurityDomainRequest());
// InterfaceConfig config = InterfaceConfig.getInstance();
StatusResponse response = new StatusResponse();
//到该处已经传递XML信息到此,通过getMoRequest即可获取同步过来的安全域信息BEAN
//获取接口参数值
String SeqNum = requestObj.getSeqNum();
String SessionID = requestObj.getSessionID();
String SynType = requestObj.getSynType();
SecurityDomainBean sdbean = requestObj.getSecurityDomain();
try {
//获取数据入库
System.out.println("SeqNum=" + SeqNum);
System.out.println("sdbean==" + sdbean.getAppAID());
if (true) { //如果处理成功
response.setStatusCode("01");
response.setStatusDescription("success");
}
}
catch (Exception ex) {
log.error("SysSDserver error", ex);
ex.printStackTrace();
}
//将封装为StatusResponse对象的信息以xml形式返回给RAADataConvert
return SOAPRequest.getRespStrXml(Constants.RAA_PREFIX,
"SynSecurityDomainResponse", response);
}
/**
*处理安全域同步响应报文
* @param soapmessage SOAPMessage server 返回的SOAPMessage
* @return SynSecurityDomainResponse 返回一个安全域同步响应的对象
*/
public SynSecurityDomainResponse SysSDResponse(SOAPMessage soapmessage) {
SynSecurityDomainResponse synsdRes = new SynSecurityDomainResponse();
try {
/**
* 一下处理server返回的报文.
*/
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
soapmessage.writeTo(outStream);
byte[] soapData = outStream.toByteArray();
outStream.close();
String soapMsg = new String(soapData, "UTF-8");
SynSecurityDomainResponse responseObj = (SynSecurityDomainResponse)
SOAPRequest.getMoRequest("SynSecurityDomainResponse",
soapMsg, SOAPRequest.raaNameSpace,
new SynSecurityDomainResponse());
/**
* 取得server返回的操作状态返回给sim卡应用管理平台
*/
synsdRes = responseObj;
System.out.println(responseObj.getStatus().getStatusCode());
System.out.println("----sopamessage----=" + soapMsg);
}
catch (Exception e) {
log.error("get synsdResponse error", e);
e.printStackTrace();
}
return synsdRes;
}
}
如果使用需要在web.xml中进行配置,具体配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>SOAPMonitorService</servlet-name>
<display-name>SOAP Monitor Service</display-name>
<servlet-class>org.apache.axis.monitor.SOAPMonitorService</servlet-class>
<init-param>
<param-name>SOAPMonitorPort</param-name>
<param-value>5001</param-value>
</init-param>
<load-on-startup>100</load-on-startup>
</servlet>
<servlet>
<servlet-name>AxisServlet</servlet-name>
<display-name>Apache-Axis Servlet</display-name>
<servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>interfaceservice1</servlet-name>
<servlet-class>com.watchdata.raadtinterface.center.InterfaceServiceServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>MSSPService</servlet-name>
<servlet-class>com.watchdata.raadtinterface.center.DataSignatureServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>SimulatorInterface</servlet-name>
<servlet-class>com.watchdata.raadtinterface.simulator.SimulatorServerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SOAPMonitorService</servlet-name>
<url-pattern>/SOAPMonitor</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/servlet/AxisServlet/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>*.jws</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>interfaceservice1</servlet-name>
<url-pattern>/RAADTSOAP/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MSSPService</servlet-name>
<url-pattern>/MSSPSOAP/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>SimulatorInterface</servlet-name>
<url-pattern>/RAADTTEST/*</url-pattern>
</servlet-mapping>
</web-app>
以上完成后部署到服务器,然后通过下面的测试类进行测试.
///测试的主方法
public static void main(String[] args) throws Exception {
String simulatorXmlFile = null; //要模拟的XML请求报文
String method = null; //要调用的方法
String[] attachFileArr = null; //要发送的附件
String url = null;
int length = args.length;
method = "test";
simulatorXmlFile = "E://xml//SynSecurityDomain.xml";
attachFileArr = new String[] {
"E://xml//01234567891100000000000101.cap"};
// if(length == 0){//方便开发时测试使用
// simulatorXmlFile = "E://xml//SynSecurityDomain.xml";
// method = "AddOrUpdateMsisdnSegment";
// attachFileArr = new String[]{"D://Simular//SEG_INC_20080804_0001.avl"};
// }else if (length >= 2) {//集成测试时使用
// simulatorXmlFile = args[0];
// method = args[1];
// if(length > 2){//有附件
// attachFileArr = new String[length-2];
// for(int i=0;i<length-2;i++){
// attachFileArr[i] = args[i+2];
// }
// }
// }else{
// System.out.println("启动参数错误,个数不够,请检查!");
// return;
// }
// url = InterfaceConfig.getInstance().getSimulatorPortalUrl();
url = "http://127.0.0.1:80/RAADTInterface/RAADTSOAP/i";
SimulatorClientTest sClient = new SimulatorClientTest();
if (method.equals("test")) {
String xmlString = sClient.getStrXml(simulatorXmlFile);
//使用正则表达式 去掉> <中间的空格和所有的回车
xmlString = sClient.replaceUseReg(xmlString, ">//s*<", "><");
xmlString = sClient.replaceUseReg(xmlString, "//n", "");
System.out.println(xmlString);
SOAPMessage resultSoap = sClient.strToSOAPMessage(xmlString);
//定向PUSH查询的返回报文可能需要添加附件
resultSoap = sClient.addAttachments(resultSoap, attachFileArr);
SOAPMessage message= sClient.send(resultSoap, url);
System.out.println("soapMessage=="+message);
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
//获取附件
int attachmentCount = message.countAttachments();
Iterator it = message.getAttachments();
//删除所有的附件
message.removeAllAttachments();
message.saveChanges();
message.writeTo(outStream);
byte[] soapData = outStream.toByteArray();
String soapMsg = new String(soapData, "UTF-8");
SynSecurityDomainResponse responseObj = (SynSecurityDomainResponse)
SOAPRequest.getMoRequest("SynSecurityDomainResponse",
soapMsg, SOAPRequest.raaNameSpace,
new SynSecurityDomainResponse());
outStream.close();
// SOAPMessage message= sClient.send(method,comm.sopeToString(resultSoap),url);
// System.out.println("==message=="+comm.sopeToString(message));
}
else {
SOAPMessage message = sClient.send(method,
sClient.getStrXml(simulatorXmlFile),
url);
/////
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
SOAPMessage resultSOAP = null;
int result = -2;
//获取附件
int attachmentCount = message.countAttachments();
Iterator it = message.getAttachments();
//删除所有的附件
message.removeAllAttachments();
message.saveChanges();
message.writeTo(outStream);
byte[] soapData = outStream.toByteArray();
outStream.close();
//modified by wzguo 081006 修改SOAP协议中出现乱码的问题,可能要根据实际情况选择使用那一个
// soapMsg = new String(soapData,"GBK");
String soapMsg = new String(soapData, "UTF-8");
SynSecurityDomainResponse responseObj = (SynSecurityDomainResponse)
SOAPRequest.getMoRequest("SynSecurityDomainResponse",
soapMsg, SOAPRequest.raaNameSpace,
new SynSecurityDomainResponse());
System.out.println(responseObj.getStatus().getStatusCode());
System.out.println("----sopamessage----=" + soapMsg);
}
}
//把符合SOAP报文的字符串转换成SOAPMessage
public static SOAPMessage strToSOAPMessage(String soapMsg) {
if (soapMsg == null || soapMsg.trim().length() < 10) {
return null;
}
try {
MessageFactory messageFac = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFac.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
byte[] data = soapMsg.getBytes("UTF-8");
ByteArrayInputStream stream = new ByteArrayInputStream(data);
StreamSource source = new StreamSource(stream);
soapPart.setContent(source);
soapMessage.saveChanges();
stream.close();
return soapMessage;
}
catch (SOAPException ex) {
System.out.println("把字符串转化成SOAPMessage出错");
}
catch (IOException ex) {
System.out.println("把字符串转化成SOAPMessage出错");
}
return null;
}
////////////////添加附件的方法
public SOAPMessage addAttachments(SOAPMessage message, String[] attachFileArr) {
//添加SOAP附件
if (attachFileArr != null) {
for (int i = 0; i < attachFileArr.length; i++) {
String fileName = attachFileArr[i];
File file = new File(fileName);
if (!file.exists()) {
System.out.println("指定的附件不存在!");
return null;
}
DataHandler dataHandler = new DataHandler(new FileDataSource(fileName));
AttachmentPart attach = message.createAttachmentPart(dataHandler);
fileName = fileName.substring(fileName.lastIndexOf("//") + 1);
attach.setContentId(fileName);
message.addAttachmentPart(attach);
}
}
//更新SOAP消息
try {
message.saveChanges();
}
catch (SOAPException ex) {
ex.printStackTrace();
}
return message;
}
/////////////////////发送方法
// 访问WebService(会根据SOAPMessage中的方法自动去访问)
public SOAPMessage send(SOAPMessage message, String url) throws SOAPException,
IOException {
//创建SOAP连接
SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance();
SOAPConnection sc = scf.createConnection();
//发送SOAP消息到目的地,并返回一个消息
URLEndpoint urlEndpoint = new URLEndpoint(url);
SOAPMessage response = sc.call(message, urlEndpoint);
if (response != null) {
//输出SOAP消息到控制台
System.out.println("Receive SOAP message from localhost:");
// response.writeTo(System.out);
log.info("return response;---" + response);
}
else {
System.err.println("No response received from partner!");
}
sc.close();
return response;
}
备注:
开发web service 用到得相关jar包:
activation.jar
mail.jar
smtp.jar
commons-betwixt-0.6.jar
xml-apis.jar
resolver.jar
- java web service 开发 具体实例
- Web service开发实例
- java web service实例
- Java web service 实例
- Axis开发Web Service实例
- Axis开发Web Service实例
- XFire开发Web Service 实例
- Axis开发Web Service实例
- Axis开发Web Service实例
- Web Service开发实例 转载
- web service相关实例开发
- Web Service工作原理及JAVA开发实例
- web service开发 java
- web service开发 java
- Axis开发Web Service的实例
- 使用Axis开发Web Service实例
- Web Service简介及开发实例
- Web Service简介及开发实例
- php 日历
- 穷人们的生活
- Windows多媒体API
- Hibernate 疑难异常及处理
- plug.xml文件初步分析
- java web service 开发 具体实例
- CComPtr用法(转)
- 转:[WPF] WPF资源收集 分享
- ASP.NET - 如何:验证 ASP.NET 服务器控件的必需项
- unhide
- Session过期时间的四种设置方式
- XHTML与HTML之间的7个区别
- Tomcat Undefined exploded archive location 项目不能部署
- Arm汇编实例解析