基于WebService的应用

前段日子看到了一个提供WEB服务的网站-www.webxml.com.cn.它提供各种适用的Web服务。如天气预报、火车时刻表。

 

 

 

 

 

于是就通过它提供的接口,实验了一下,看看它提供的那些接口有什么效果。但是因为是免费用户,所以每次访问的次数有限制,所以只是测试一下。

但是你需要从WSDL文档中生成客户端支持代码,可以使用axis的wsdl2java:

%AXIS2_HOME%\bin\wsdl2java -uri http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl -p client -s -o stub

其中-url参数指定了wsdl文件的路径,可以是本地路径,也可以是网络路径。-p参数指定了生成的Java类的包名,-o参数指定了生成的一系列文件保存的根目录。

在执行完上面的命令后,读者就会发现在当前目录下多了个stub目录,在."stub"src"client目录可以找到一个SimpleServiceStub.java文件,该文件复杂调用WebService

可以在程序中直接使用这个类。

 

我用了好几个服务,火车,天气,城市代码等。

先贴我的pojo,pojo需要和它提供的入口的属性一致,代码如下:

 Train.java

 

package com.jushi.pojo;

public class Train {

	private String trainStation;
	private String arriveTime;
	private String startTime;
	private String km;
	
	private String firstStation;
	private String lastStation;
	private String trainCode;
	private String startStation;
	private String arriveStation;
	private String useDate;
	
	public String getTrainStation() {
		return trainStation;
	}
	public void setTrainStation(String trainStation) {
		this.trainStation = trainStation;
	}
	public String getArriveTime() {
		return arriveTime;
	}
	public void setArriveTime(String arriveTime) {
		this.arriveTime = arriveTime;
	}
	public String getStartTime() {
		return startTime;
	}
	public void setStartTime(String startTime) {
		this.startTime = startTime;
	}
	public String getKm() {
		return km;
	}
	public void setKm(String km) {
		this.km = km;
	}
	public String getFirstStation() {
		return firstStation;
	}
	public void setFirstStation(String firstStation) {
		this.firstStation = firstStation;
	}
	public String getLastStation() {
		return lastStation;
	}
	public void setLastStation(String lastStation) {
		this.lastStation = lastStation;
	}
	public String getTrainCode() {
		return trainCode;
	}
	public void setTrainCode(String trainCode) {
		this.trainCode = trainCode;
	}
	public String getStartStation() {
		return startStation;
	}
	public void setStartStation(String startStation) {
		this.startStation = startStation;
	}
	public String getArriveStation() {
		return arriveStation;
	}
	public void setArriveStation(String arriveStation) {
		this.arriveStation = arriveStation;
	}
	public String getUseDate() {
		return useDate;
	}
	public void setUseDate(String useDate) {
		this.useDate = useDate;
	}
	
}

 

City.java

 

package com.jushi.pojo;

public class City {
	
	private String cityId;
	private String cityName;
	public String getCityId() {
		return cityId;
	}
	public void setCityId(String cityId) {
		this.cityId = cityId;
	}
	public String getCityName() {
		return cityName;
	}
	public void setCityName(String cityName) {
		this.cityName = cityName;
	}
}

  

接下来就是业务了。我们需要将它返回的数据集处理成我们需要的结果,所以用到了jdom。

 代码如下:

TrainInfo.java

package com.jushi.service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.axis.message.MessageElement;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

import cn.com.WebXml.GetDetailInfoByTrainCodeResponseGetDetailInfoByTrainCodeResult;
import cn.com.WebXml.GetStationAndTimeByStationNameResponseGetStationAndTimeByStationNameResult;
import cn.com.WebXml.TrainTimeWebServiceLocator;
import cn.com.WebXml.TrainTimeWebServiceSoap;

import com.jushi.pojo.Train;

public class TrainInfo {

	//通过车次得到列车信息 
	public ArrayList getInfo(String traincode){
		ArrayList trainlist = null;
		try{
			java.net.URLEncoder.encode("参数","UTF-8");
			TrainTimeWebServiceLocator service = new TrainTimeWebServiceLocator();
			TrainTimeWebServiceSoap client = service.getTrainTimeWebServiceSoap();
			GetDetailInfoByTrainCodeResponseGetDetailInfoByTrainCodeResult traininfo =
				client.getDetailInfoByTrainCode(traincode, "");//后面的是我新注册的userID: eb01f699583d44d4bdee0ed47c0397d5
			MessageElement[] msg = traininfo.get_any();
			List elementHead = msg[0].getChildren();//消息头,DataSet对象
			List elementBody = msg[1].getChildren();//消息体信息,DataSet对象
			if(elementBody.size()<=0){
				return null;
			}
			String str = elementBody.get(0).toString();//消息体的字符串形式
			saveXMLString(str,"train.xml");
			trainlist = loadXML("train.xml");
			
		}catch(Exception e){
			e.printStackTrace();
		}
		return trainlist;
	}
	
	public static void saveXMLString(String xmlString,String filename) throws IOException{
			File file = new File(filename);
			if(file.exists()){
				file.delete();
			}		
			file.createNewFile();
			if(file.canWrite()){
				FileWriter out = new FileWriter(file);
				out.write(xmlString);
				out.close();
			}
	}
	
	//车次查询读取xml文件
	public static ArrayList loadXML(String filepath) throws IOException{
		ArrayList<Train> list = null;
		FileInputStream fis = null;
		try{
			
			fis = new FileInputStream(filepath);
			list = new ArrayList<Train>();
			SAXBuilder builder = new SAXBuilder();
			Document doc = builder.build(fis);
			Element root = doc.getRootElement();
			List doclist = root.getChildren();
			Element info = null;
			Train train = null;
			
			for(int i=0; i<doclist.size(); i++){
				train = new Train();
				info = (Element) doclist.get(i);
				train.setArriveTime(info.getChild("ArriveTime").getText().equals("http://www.webxml.com.cn")?"没有数据":info.getChild("ArriveTime").getText());
				train.setKm(info.getChild("KM").getText().equals("")?"没有数据":info.getChild("KM").getText());
				train.setStartTime(info.getChild("StartTime").getText().equals("")?"没有数据":info.getChild("StartTime").getText());
				train.setTrainStation(info.getChild("TrainStation").getText().equals("免费用户24小时内访问超过规定数量")?"没有数据":info.getChild("TrainStation").getText());
				
				list.add(train);
			}		
		}catch(Exception e){
			e.printStackTrace();
		}
		
		return list;
	}
	
	//始发站和终点站查询
	public static ArrayList loadXMLByStation(String filepath) throws IOException{
		ArrayList<Train> list = null;
		FileInputStream fis = null;
		try{
			
			fis = new FileInputStream(filepath);
			list = new ArrayList<Train>();
			SAXBuilder builder = new SAXBuilder();
			Document doc = builder.build(fis);
			Element root = doc.getRootElement();
			List doclist = root.getChildren();
			Element info = null;
			Train train = null;
			
			for(int i=0; i<doclist.size(); i++){
				train = new Train();
				info = (Element) doclist.get(i);
				train.setArriveTime(info.getChild("ArriveTime").getText());
				train.setKm(info.getChild("KM").getText());
				train.setTrainCode(info.getChild("TrainCode").getText());
				train.setFirstStation(info.getChild("FirstStation").getText().equals("数据没有被发现")?"没有数据":info.getChild("FirstStation").getText());
				train.setLastStation(info.getChild("LastStation").getText().equals("http://www.webxml.com.cn")?"没有数据":info.getChild("LastStation").getText());
				train.setStartStation(info.getChild("StartStation").getText());
				train.setStartTime(info.getChild("StartTime").getText());
				train.setArriveStation(info.getChild("ArriveStation").getText());
				train.setUseDate(info.getChild("UseDate").getText());
				
				list.add(train);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		
		return list;
	}
	
	
	public ArrayList getTrainByStation(String startStation, String arriveStation){
		ArrayList trainlist = null;
		try{
			TrainTimeWebServiceLocator service = new TrainTimeWebServiceLocator();
			TrainTimeWebServiceSoap client = service.getTrainTimeWebServiceSoap();
			GetStationAndTimeByStationNameResponseGetStationAndTimeByStationNameResult traininfo =
				client.getStationAndTimeByStationName(startStation, arriveStation,"");//userID: eb01f699583d44d4bdee0ed47c0397d5
			MessageElement[] msg = traininfo.get_any();
			List elementHead = msg[0].getChildren();//消息头,DataSet对象
			List elementBody = msg[1].getChildren();//消息体信息,DataSet对象
			if(elementBody.size()<=0){
				return null;
			}
			String str = elementBody.get(0).toString();//消息体的字符串形式
			saveXMLString(str,"train2.xml");
			trainlist = loadXMLByStation("train2.xml");
			
		}catch(Exception e){
			e.printStackTrace();
		}
		return trainlist;
	}
	
	public static void main(String as[]){
//		ArrayList list = new TrainInfo().getInfo("K7003");
//		for(int i=0; i<list.size(); i++){
//			Train train = (Train) list.get(i);
//			System.out.println("车站:"+train.getTrainStation());
//			System.out.println("开车时间:"+train.getStartTime());
//			System.out.println("到站时间:"+train.getArriveTime());
//			System.out.println("路程(KM):"+train.getKm());
//		}
		
		
		ArrayList list2 = new TrainInfo().getTrainByStation("北京", "哈尔滨");
		for(int i=0; i<list2.size(); i++){
			Train train = (Train) list2.get(i);
			System.out.println("车次:"+train.getTrainCode());
			System.out.println("始发站:"+train.getFirstStation());
			System.out.println("终点站:"+train.getLastStation());
			System.out.println("路程(KM):"+train.getKm());
			System.out.println("发车站:"+train.getStartStation());
			System.out.println("发车时间:"+train.getStartTime());
			System.out.println("到达站:"+train.getArriveStation());
			System.out.println("到达时间:"+train.getArriveTime());
			System.out.println("历时:"+train.getUseDate());
		}
	}
}

 

 再接下来,因为我要做一个页面提供给用户一个互动,所以一个jsp,当然还是servlet加jsp的经典配合。

 index.jsp 

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%@ page import="com.jushi.pojo.*" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<title>列车时刻查询</title>
  <head>
  	<script type="text/javascript">
  		
  		function query_code(){
  			if(document.form1.traincode.value == ''){
  				alert("请输入一个车次!!");
  				return;
  			}
  			var traincode = document.form1.traincode.value;
  			document.form1.action = "TrainService?traincode="+traincode;
  			document.form1.submit();
  		}
  		
  		function _showDivs(obj){
  			if(obj.value == '0'){
  				showstation.style.display="none";
  				showcode.style.display="block";
  			}
  			else{
  				showstation.style.display="block";
  				showcode.style.display="none";
  			}
  		}
  		
  		function query_station(){
  			if(document.form1.firststation.value == ''||document.form1.laststation.value == ''){
  				alert("请填写完整始发站和终点站!!");
  				return;
  			}
  			var firststation = document.form1.firststation.value;
  			var laststation = document.form1.laststation.value;
  			document.form1.action = "TrainService?firststation="+firststation+"&laststation="+laststation;
  			document.form1.submit();
  		}
  	</script>
  </head>
  
  <body>
  	<%	
  		request.setCharacterEncoding("GBK");
  		ArrayList trainList = null,trainListStation=null;
  		response.setCharacterEncoding("GBK");
  		if(request.getAttribute("trainlist")!=null){
  			trainList = (ArrayList) request.getAttribute("trainlist");
  		}
  		
  		if(request.getAttribute("trainlistStation")!=null){
  			trainListStation = (ArrayList) request.getAttribute("trainlistStation");
  		}
  		
  	 %>
  	 <center>
  	 <h2>列车查询</h2>
  	 <select name="queryfor" id="queryfor" onchange="_showDivs(this)">
  	 	<option value="0" selected="selected">--按车次--</option>
  	 	<option value="1" >--按始发终点站--</option>
  	 </select>
  	 <br/>
  	 <form name="form1">
  	 	<div id='showcode' name="showcode" style="display: block">
  	 	<table id="tab" align="center" border="1" style="border: thin;">		
  	 		<tr>
  	 			<td>请输入车次:<input type="text" name="traincode" id="traincode" size="20"/></td>
  	 			<td>
  	 				<button id="btok" name="btok" onclick="query_code()">查 询</button>
  	 			</td>
  	 		</tr>	
  	 	</table>
  	 	</div>
  	 	<div id="showstation" name="showstation" style="display: none">
  	 	<table id="tab" align="center" border="1" style="border: thin;">		
  	 		<tr>
  	 			<td>始发站:<input type="text" name="firststation" id="firststation" size="20"/>
					终点站:<input type="text" name="laststation" id="laststation" size="20"/></td>
  	 			<td>
  	 				<button id="btok" name="btok" onclick="query_station()">查 询</button>
  	 			</td>
  	 		</tr> 		
  	 	</table>
  	 	</div>
  	 </form>
  	 <hr/>
  	 <table id="tab" align="center" border="1" bordercolor="green" style="border: thick;">
  	 	<%if(trainList!=null){ %>
  	 	<tr>
  	 		<td colspan="4" align="center" bgcolor="#FFF000">【 列车时刻表 】</td>
  	 	</tr>	
  	 	<tr>
  	 		<td colspan="4" align="center"><font color=red>查询结果 (从上至下为:始发站-终点站) 如下:</font></td>
  	 	</tr>
  	 	<%
  	 		for(int i=0; i<trainList.size(); i++){
  	 			Train train = (Train) trainList.get(i);
  	 	%>
  	 	<tr>	 		
  	 		<td bgcolor="#FFCCFF" align="center"> 车站</td>
  	 		<td bgcolor="#FFCCFF" align="center"> 开车时间</td>
  	 		<td bgcolor="#FFCCFF" align="center"> 到站时间</td>
  	 		<td bgcolor="#FFCCFF" align="center"> 路程(KM)</td> 		
  	 	</tr>	
  	 	<tr>
  	 		<td align="center"><%=train.getTrainStation().equals("")?"--":train.getTrainStation() %></td>
  	 		<td align="center"><%=train.getStartTime().equals("")?"--":train.getStartTime() %></td>
  	 		<td align="center"><%=train.getArriveTime().equals("")?"--":train.getArriveTime() %></td>
  	 		<td align="center"><%=train.getKm().equals("")?"--":train.getKm() %></td>
  	 	</tr>
  	 	 <%}} %>
  	 	<%
  	 		if(trainListStation!=null){
  	 	 %>
  	 	<tr>
  	 		<td colspan="9" align="center" bgcolor="#FFF000">【 列车时刻表 】</td>
  	 	</tr>
  	 	<%
  	 		for(int i=0; i<trainListStation.size(); i++){
  	 			Train train = (Train) trainListStation.get(i);
  	 	%>
  	 	<tr>	 		
  	 		<td bgcolor="#FFCCCC" align="center"> 车次</td>
  	 		<td bgcolor="#FFCCCC" align="center"> 始发站</td>
  	 		<td bgcolor="#FFCCCC" align="center"> 终点站</td>
  	 		<td bgcolor="#FFCCCC" align="center"> 路程(KM)</td> 		
  	 		<td bgcolor="#FFCCCC" align="center"> 发车站</td> 		
  	 		<td bgcolor="#FFCCCC" align="center"> 发车时间</td> 		
  	 		<td bgcolor="#FFCCCC" align="center"> 到达站</td> 		
  	 		<td bgcolor="#FFCCCC" align="center"> 到达时间</td> 		
  	 		<td bgcolor="#FFCCCC" align="center"> 历时</td>
  	 	</tr>
  	 	<tr>
  	 		<td align="center"><%=train.getTrainCode().equals("")?"--":train.getTrainCode() %></td>
  	 		<td align="center"><%=train.getFirstStation().equals("")?"--":train.getFirstStation() %></td>
  	 		<td align="center"><%=train.getLastStation().equals("")?"--":train.getLastStation() %></td>
  	 		<td align="center"><%=train.getKm().equals("")?"--":train.getKm() %></td>
  	 		<td align="center"><%=train.getStartStation().equals("")?"--":train.getStartStation() %></td>
  	 		<td align="center"><%=train.getStartTime().equals("")?"--":train.getStartTime() %></td>
  	 		<td align="center"><%=train.getArriveStation().equals("")?"--":train.getArriveStation() %></td>
  	 		<td align="center"><%=train.getArriveTime().equals("")?"--":train.getArriveTime() %></td>
  	 		<td align="center"><%=train.getUseDate().equals("")?"--":train.getUseDate() %></td>
  	 	</tr>
  	 	<%}} %>
  	 </table>
  	 </center>
  </body>
</html>
<%
	request.removeAttribute("trainlist");
	request.removeAttribute("trainlistStation");	
%>

 

TrainService.java

 

package com.jushi.service;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TrainService extends HttpServlet {

	private TrainInfo trainMain = new TrainInfo();
	
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request,response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html; charset=GBK");
		PrintWriter out = response.getWriter();
		String traincode = request.getParameter("traincode");
		String firststation="",laststation="";
		if(!request.getParameter("firststation").equals("")&&!request.getParameter("laststation").equals("")){
			firststation = request.getParameter("firststation");
			firststation = new String(firststation.getBytes("ISO-8859-1"),"GBK");
			laststation = request.getParameter("laststation");
			laststation = new String(laststation.getBytes("ISO-8859-1"),"GBK");
			ArrayList trainlist = trainMain.getTrainByStation(firststation, laststation);
			request.setAttribute("trainlistStation", trainlist);
		}
		else{
			ArrayList trainlist = trainMain.getInfo(traincode);
			request.setAttribute("trainlist", trainlist);
		}
		
		request.getRequestDispatcher("index.jsp").forward(request, response);
	}
}

 

之后,写了测试类,可以让大家试试效果。个人觉得webservice的用途真的很大。在做项目时,需要访问客户提供的入口来得到我们需要的数据。那么它确实是个有效的工具。

 

Test.java

package com.jushi.test;

import java.awt.Font;
import java.awt.GridLayout;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.xml.namespace.QName;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.message.MessageElement;
import org.apache.axis.types.Schema;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

import com.jushi.pojo.City;

public class Test {

	public static void main(String as[]){
	
	try{
		String theRegionCode = "3113";//此处为省市国家 ID 黑龙江省
		new Test().getSupportCityAndCityName(theRegionCode);
		System.out.println("===============================【下面为相应代号的城市天气情况】=================================");
		new Test().getWeather("633"); //该ID为牡丹江代号
		
	}catch(Exception e){
		e.printStackTrace();
	}
}
	
	public void getSupportCityAndCityName(String id) throws Exception{
		
		String endpoint = "http://www.webxml.com.cn/WebServices/WeatherWS.asmx";
		Service service = new Service();
		Call call = (Call)service.createCall();
		call.setTargetEndpointAddress(new java.net.URL(endpoint));
		call.setOperationName(new QName("http://WebXml.com.cn/","getSupportCityDataset"));
		call.addParameter(new QName("http://WebXml.com.cn/","theRegionCode"),org.apache.axis.encoding.XMLType.XSD_STRING,javax.xml.rpc.ParameterMode.IN);
		call.setReturnType(org.apache.axis.encoding.XMLType.XSD_SCHEMA);
		call.setUseSOAPAction(true);
		call.setSOAPActionURI("http://WebXml.com.cn/getSupportCityDataset");
		
		Schema result =  (Schema)call.invoke(new Object[]{id});
		MessageElement[] msg = result.get_any();
		List elementBody = msg[1].getChildren();//消息体信息,DataSet对象
		String str = elementBody.get(0).toString();//消息体的字符串形式
		saveXMLString(str,"supportcity.xml");//生成xml文件 
		ArrayList<City> list = loadXML("supportcity.xml");//读取xml文件 按节点依次读取数据
		
		
		for (int i = 0; i < list.size(); i++) {
			City city = (City) list.get(i);
			System.out.println("城市代号:"+city.getCityId());
			System.out.println("城市名称:"+city.getCityName());
		}
	}
	
	public void getWeather(String cityID) throws Exception{
		
		String endpoint = "http://www.webxml.com.cn/WebServices/WeatherWS.asmx";
		Service service = new Service();
		Call call = (Call)service.createCall();
		call.setTargetEndpointAddress(new java.net.URL(endpoint));
		call.setOperationName(new QName("http://WebXml.com.cn/","getWeather"));
		call.addParameter(new QName("http://WebXml.com.cn/","theCityCode"),org.apache.axis.encoding.XMLType.XSD_STRING,javax.xml.rpc.ParameterMode.IN);
		call.setReturnType(org.apache.axis.encoding.XMLType.XSD_SCHEMA);
		call.setUseSOAPAction(true);
		call.setSOAPActionURI("http://WebXml.com.cn/getWeather");
		
		Schema result = (Schema) call.invoke(new Object[]{cityID});
		MessageElement[] msg = (MessageElement[]) result.get_any();//返回为一维字符串数组
		ArrayList<List> arr = new ArrayList<List>();
		for(int i=0; i<msg.length; i++){
			arr.add(msg[i].getChildren());
		}
		StringBuffer sbb = new StringBuffer();
		for(int i=0; i<arr.size(); i++){
			String res = (String) arr.get(i).toString();
			if(res.equals("[发现错误:免费用户24小时内访问超过规定数量。http://www.webxml.com.cn/]")){
				res="服务器暂时无法连接..\n";
			}
			sbb.append(res+"\n");
			System.out.println(res);
			}
		String title = msg[0].getChildren().
								toString().
								equals("[发现错误:免费用户24小时内访问超过规定数量。http://www.webxml.com.cn/]")?
								"服务器连接失败":msg[0].getChildren().toString();
		JFrame jf = new JFrame();
		jf.setTitle(title+" --天气预报");
		jf.setLocation(400,50);
		jf.setSize(700,800);
		jf.setLayout(new GridLayout(1,1));
		
		JPanel panel = new JPanel();
		JTextArea text = new JTextArea();
		text.setFont(new Font("宋体",Font.PLAIN,13));
		text.setText(sbb.toString());
		panel.add(text);
		jf.add(panel);
		jf.setVisible(true);
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
	}
	
	public static void saveXMLString(String xmlString,String filename) throws IOException{
		File file = new File(filename);
		if(file.exists()){
			file.delete();
		}		
		file.createNewFile();
		if(file.canWrite()){
			FileWriter out = new FileWriter(file);
			out.write(xmlString);
			out.close();
		}
	}
	
	public static ArrayList loadXML(String filepath) throws IOException{
		ArrayList<City> list = null;
		FileInputStream fis = null;
		try{
			
			fis = new FileInputStream(filepath);
			list = new ArrayList<City>();
			SAXBuilder builder = new SAXBuilder();
			Document doc = builder.build(fis);
			Element root = doc.getRootElement();
			List doclist = root.getChildren();
			Element info = null;
			City city = null;
			for(int i=0; i<doclist.size(); i++){
				city = new City();
				info = (Element) doclist.get(i);
				city.setCityId(info.getChild("CityID").getText());
				city.setCityName(info.getChild("CityName").getText());
				list.add(city);
			}		
		}catch(Exception e){
			e.printStackTrace();
		}
		
		return list;
	}
	
}

  

 好了。简单的测试demo做完了,运行服务,测试。但是我是免费用户,所以在使用次数上webxml.com有限制。不过是使用它提供给我们的入口,真正在项目中需要你自己做了。

 再附上源码。

 

 

 

 

 

 

你可能感兴趣的:(apache,xml,应用服务器,webservice,网络应用)