前兩天學習了使用Axis開發WebService程序,寫了一個HelloWorld程序,感覺流程明白了,可是其中的原理還是不夠清楚,今天在寫一個demo,使用別人發佈的一個天氣預報webservice,根據提供的wsdl文件,生成本地的java框架,寫自己的業務方法,使用jsp做頁面展示.
這個天氣預報的webservice來自於網上http://fhs.6617.com/getweather.asmx,下面我們將使用最原始的開發方法,不實用任何輔助工具來寫代碼,這樣有助於我們瞭解詳細的步驟和其中的原理.
目的:這個demo要做成web項目,在jsp頁面上,用戶輸入城市名稱後,調用webservice,顯示出天氣預報的信息
步驟:
1. 首先建立項目的目錄結構,我們這裏還是使用,axis-bin-1_4.zip包中的axis目錄.本demo的目錄爲D:\jakarta-tomcat-5.5.7\webapps\axis
2.使用 命令提示符 進入D:\jakarta-tomcat-5.5.7\webapps\axis,設置classpath,主要是編譯文件所需要的一些jar包的路徑,關於設置classpath 可以參考我的另一篇博客 使用Axis框架開發webservice的HelloWord 中的init.bat文件
3.得到wsdl(webservice描述文件),使用WSDL2Java 命令將它轉化爲本地java框架,方便自己調用
a.進入http://fhs.6617.com/getweather.asmx?WSDL 你將看到這個webservice的描述,複製其中的內容,保存爲getweather.wsdl ,放在axis目錄下
b.在設置好環境變量,命令提示符爲當前的D:\jakarta-tomcat-5.5.7\webapps\axis 目錄後 運行 java org.apache.axis.wsdl.WSDL2Java getweather.wsdl -s 之後你可以看到該目錄下多了一個文件夾 com 其中的 目錄結構爲 axis\com\_6617\fhs\WeatherService 下面有 11個文件,其中有9個 .java文件 和兩個 wsdd文件
c.由於我們使用了 -s 選項,則生成了兩個wsdd 文件,其中deploy.wsdd 是幫助我們發佈webservice 的,undeploy.wsdd,是卸載webservice服務的.
d.我們也可以不下載getweather.wsdl 文件,使用下面這種方式也可以生成本地java文件框架
java org.apache.axis.wsdl.WSDL2Java http://fhs.6617.com/getweather.asmx?WSDL
4.進入axis\com\_6617\fhs\WeatherService 文件夾下,編譯這些.java文件 javac *.java
如果這一步有問題,一般是classpath變量設置的問題,仔細檢查所需要的jar 包是否都設置正確了嗎?還有我們編譯可能會遇到一大堆警告,沒關係,這是字符編碼的問題,不屬於錯誤,不影響我們後續的使用,將這些.class文件拷貝到axis\WEB-INF\classes 目錄下
5.這時候我們客戶端的框架就搭好了,現在我們可以在寫jsp頁面,servlet,字符集過濾器了,爲了方便開發,我們現在使用eclipse,在eclipse下新建立一個web項目名字交 webservice,按照web項目的目錄結構將 我們的axis目錄下的 文件分門別類的放入到webservice目錄下,比如 java源文件放在src下,.class文件放在web-inf/class下等. 注意把servlet.jar包和 jsp.jar包添加到項目的classpath中
6.在webservice項目的根目錄下寫3個頁面
a.index.html 這是一個框架頁面 一個frameset 中套兩個frame (我們把頁面分成上下兩個部分)
b.top.html 這是頁面上部分的查詢頁面 用戶輸入城市名稱 點擊查詢 在下部分的頁面中顯示查詢結果
c.bottom.jsp 這是西部分的結果顯示頁面
如圖看項目結構,包括時候WSDL2Java 生成的9個java文件
index.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head><title>天氣預報</title></head> <frameset rows="25%,*%" Borders="No" border="0"> <frame src="top.html" noresize="false" name="top" frameborder="0"> <frame src="bottom.jsp" noresize="true" name="bottom" frameborder="0"> </frameset> </html>
top.html
<html> <head><title></title> <style type="text/css"> <!-- .style1 { color: #FF0000; font-weight: bold; font-size: 12px; } --> </style> </head> <script type="text/javascript"> function check() { if(document.getElementById("city").value==null || document.getElementById("city").value=="") { window.alert ('城市名稱必須填寫'); return; } document.forms[0].submit(); } </script> <body> <p><b>WebService 天氣預報(下一個Demo是IP地址查詢,敬請期待!)</b></p> <p class="style1">請輸入需要查詢的城市名稱:</p> <form name="form1" method="post" action="invoke" target="bottom"> <input type="text" name="city" id="city"> <input type="button" name="sub" value="查詢" onclick="check()"> </form> </body> </html>
bottom.jsp
<%@ page contentType="text/html; charset=utf-8"%> <head><title>WebService 天氣預報</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><style type="text/css"> </head>
7.在web開發中,一個頭疼的問題就是字符編碼問題,在這裏我們雖然是一個demo,爲了有好的習慣,我們也來使用一個過濾器,來解決字符編碼的問題,而不是每次在servlet中使用request.setCharacterEncoding(),或者用new String(....)等來手動轉碼.
a.這個過濾器是SetCharacterEncodingFilter.java 它繼承子Filter
package com._6617.fhs.WeatherService; import java.io.IOException; import javax.servlet.*; import org.apache.log4j.Logger; public class SetCharacterEncodingFilter implements Filter { protected String encoding = null; protected FilterConfig filterConfig = null; protected boolean ignore = true; public void init(FilterConfig filterConfig) throws ServletException { Logger log=Logger.getLogger(SetCharacterEncodingFilter.class); log.info("過濾器被調用!!!"); this.filterConfig = filterConfig; this.encoding = filterConfig.getInitParameter("encoding"); String value = filterConfig.getInitParameter("ignore"); if (value == null) this.ignore = true; else if (value.equalsIgnoreCase("true")) this.ignore = true; else if (value.equalsIgnoreCase("yes")) this.ignore = true; else this.ignore = false; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (ignore || (request.getCharacterEncoding() == null)) { String encoding = selectEncoding(request); if (encoding != null) request.setCharacterEncoding(encoding); } response.setContentType("text/html; charset="+encoding); chain.doFilter(request, response); } protected String selectEncoding(ServletRequest request) { return (this.encoding); } public void destroy() { this.encoding = null; this.filterConfig = null; } }
b.部署過濾器,在web.xml中
<filter> <filter-name>SetCharacterEncodingFilter</filter-name> <filter-class>com._6617.fhs.WeatherService.SetCharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>GBK</param-value> </init-param> <init-param> <param-name>ignore</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>SetCharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
8.寫業務方法和處理的servlet
a. InvokeWS.java 這是一個標準的servlet,根據用戶的請求來執行相應的業務方法
package com.business; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.rpc.ServiceException; public class InvokeWS extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { WSWeather wsw= new BaseBusiness().getManage().getWeatherManage(); PrintWriter pw=resp.getWriter(); String city=req.getParameter("city"); if(city!=null && city.length()!=0) { if(wsw.isOK(city)) { String[] weatherinfo; try { weatherinfo = wsw.getWeatherByCity(city); for(int i=0;i<weatherinfo.length;i++) { pw.println("<font size='2' color='blue'>"+weatherinfo[i]+"</font><br>"); } } catch (ServiceException e) { e.printStackTrace(); } } else { pw.println("<font size='2' color='blue'>"+"沒有查到你要的城市,請聯繫:134********"+"</font><br>"); } } } public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
在這裏我們使用了Face模式,這樣方便我們後續IP地址查詢,手機號碼查詢等模塊的開發
b.BaseBusiness.java 獲取所有業務的接口
package com.business; //獲取所有業務的接口 public class BaseBusiness { protected ManageFaced getManage() { return new ManagefacedImp(); } }
c.ManageFaced.java 標準接口,裏面包含了得到單個業務的管理類
package com.business; public interface ManageFaced { //獲取查詢天氣的管理類 public WSWeather getWeatherManage(); //可以在加上查詢IP的管理類 }
d.ManagefacedImp.java 實現接口中的方法,根據不同的業務,實現不同的業務
package com.business; public class ManagefacedImp implements ManageFaced { //獲取天氣信息 public WSWeather getWeatherManage() { return new WSWeather(); } //在這裏可以添加獲取IP信息 }
e.WSWeather.java 單個具體業務的實現類
package com.business; import java.rmi.RemoteException; import javax.xml.rpc.ServiceException; import com._6617.fhs.WeatherService.Weather_x0020_WebServiceLocator; import com._6617.fhs.WeatherService.Weather_x0020_WebServiceSoap; public class WSWeather { //判斷用戶查詢結果是否存在 public boolean isOK(String city) { //getCityWeather()返回的是一個對象數組 Object[] o=null; Weather_x0020_WebServiceLocator locator= new Weather_x0020_WebServiceLocator(); try { Weather_x0020_WebServiceSoap service=locator.getWeather_x0020_WebServiceSoap12(); o=service.getCityWeather(city); } catch(Exception e) { e.printStackTrace(); } String flagcity=(String)o[0]; if(flagcity.indexOf(city)!=-1) { return true; } else { return false; } } public String[] getWeatherByCity(String city) throws ServiceException, RemoteException { Weather_x0020_WebServiceLocator locator= new Weather_x0020_WebServiceLocator(); Weather_x0020_WebServiceSoap service=locator.getWeather_x0020_WebServiceSoap12(); Object[] o=service.getCityWeather(city); System.out.println(o.length); if(o!=null || o.length!=0) { String[] info=new String[o.length]; for(int i=0;i<o.length;i++) { info[i]=o[i].toString(); } return info; } else { return null; } } }
9.在web.xml中配置InvokeWS..java這個servlet,在TocmcatD:\jakarta-tomcat-5.5.7\conf\Catalina\localhost中配置這個項目的訪問路徑
a.在web.xml中
<servlet> <servlet-name>InvokeWS</servlet-name> <servlet-class>com.business.InvokeWS</servlet-class> </servlet> <servlet-mapping> <servlet-name>InvokeWS</servlet-name> <url-pattern>/invoke</url-pattern> </servlet-mapping>
b.配置訪問路徑 axistest.xml (在TocmcatD:\jakarta-tomcat-5.5.7\conf\Catalina\localhost下,根據自己的tomcat安裝路徑)
<Context path="/axistest" docBase="D:\workspace\webservice" reloadable="true"> </Context>
10.啓動Tomcat 訪問 http://localhost:8080/axistest/index2.html 可以看到下面的畫面 輸入 西安 點擊查詢
未處理
1.業務方法中 如何根據生成的java方法 調webservice
2.關於再次發佈的問題