前段日子看到了一个提供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有限制。不过是使用它提供给我们的入口,真正在项目中需要你自己做了。
再附上源码。