前兩天學習了使用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" >
<frame src="top.html" noresize="false" name="top" frame>
<frame src="bottom.jsp" noresize="true" name="bottom" frame>
</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="查詢" οnclick="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.關于再次釋出的問題