1.12 網(wǎng) 站 發(fā) 布
如今有很多網(wǎng)絡(luò)用戶(hù)以自己的計(jì)算機(jī)作為服務(wù)器,發(fā)布網(wǎng)站到Internet,這也是一個(gè)不錯(cuò)的選擇,為網(wǎng)站的更新和維護(hù)提供了很大的便利。
在發(fā)布Java Web程序到Internet之前,需具備如下前提條件(假設(shè)使用的是Tomcat服務(wù)器):
擁有一臺(tái)可連接到Internet的計(jì)算機(jī),并且是固定IP。
擁有一個(gè)域名。
在可連接到Internet的計(jì)算機(jī)上要有Java Web程序的運(yùn)行環(huán)境,即已經(jīng)成功安裝了JDK和Tomcat服務(wù)器。
擁有一個(gè)可運(yùn)行的Java Web應(yīng)用程序。
擁有了上述條件,就可以將已經(jīng)擁有的Java Web程序發(fā)布到Internet了。發(fā)布步驟如下:
(1)申請(qǐng)一個(gè)域名,例如www.yxq.com。
(2)將域名的A記錄的IP指向自己的計(jì)算機(jī)的IP。
(3)在本地計(jì)算機(jī)中創(chuàng)建一個(gè)目錄用來(lái)存放Java Web程序,如D:\JSPWeb。
(4)將Java Web程序復(fù)制到D:\JSPWeb目錄下,可對(duì)其重命名,如命名為01_CityInfo。
(5)將Tomcat服務(wù)器端口改為80。修改方法為:打開(kāi)Tomcat安裝目錄下conf目錄中的server.xml文件,并找到以下配置代碼。
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
修改<Connector>元素中port屬性的值為80。
(6)建立虛擬主機(jī),主機(jī)名為申請(qǐng)的域名。創(chuàng)建方法為:打開(kāi)Tomcat安裝目錄下conf目錄中的server.xml文件,找到<Host>元素并進(jìn)行如下配置。
<Host name="www.yxq.com" appBase="D:/JSPWeb"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Context path="/city" docBase="01_CityInfo" debug='0' reaload="true"/>
</Host>
<Host>元素用來(lái)創(chuàng)建主機(jī),name屬性指定了主機(jī)名(域名),appBase屬性指定了Java Web應(yīng)用程序存放在本地計(jì)算機(jī)中的位置。<Context>元素用來(lái)配置主機(jī)的Web應(yīng)用程序,path屬性指定了訪問(wèn)主機(jī)中某個(gè)Web應(yīng)用的路徑,docBase屬性指定了相對(duì)于D:/JSPWeb目錄下的Java Web應(yīng)用程序路徑。所以,若訪問(wèn)www.yxq.com/city路徑,既可訪問(wèn)D:/JSPWeb目錄下的01_CityInfoWeb應(yīng)用程序,也可以將path屬性設(shè)置為“/”,這樣直接訪問(wèn)www.yxq.com即可訪問(wèn)01_CityInfoWeb應(yīng)用程序。
(7)訪問(wèn)站點(diǎn)。啟動(dòng)Tomcat服務(wù)器,在瀏覽器地址欄中輸入“https://www.yxq.com/city”,訪問(wèn)發(fā)布的Java Web應(yīng)用程序。
也可通過(guò)該方法將網(wǎng)站發(fā)布到局域網(wǎng)內(nèi),只不過(guò)在<Host>元素中name屬性指定的是計(jì)算機(jī)名稱(chēng),并且該計(jì)算機(jī)名稱(chēng)不能包含空格或“.”等非法字符,否則,局域網(wǎng)內(nèi)的其他計(jì)算機(jī)將不能訪問(wèn)發(fā)布的網(wǎng)站。
1.13 開(kāi)發(fā)技巧與難點(diǎn)分析
1.13.1 實(shí)現(xiàn)頁(yè)面中的超鏈接
雖然在應(yīng)用Struts框架開(kāi)發(fā)Web應(yīng)用時(shí),推薦使用Struts中提供的標(biāo)簽,但有些時(shí)候不妨靈活地使用原始的HTML語(yǔ)言中的一些標(biāo)識(shí)。例如,在頁(yè)面中實(shí)現(xiàn)一個(gè)超鏈接,鏈接請(qǐng)求的資源為welcome.jsp頁(yè)面,若使用Struts 2.0的a標(biāo)簽實(shí)現(xiàn):
<s2:a href="<s2:url value='/welcome.jsp'/>">轉(zhuǎn)發(fā)</s2:a>
則上述代碼將生成如下HTML代碼:
<a href="<s2:url value='/welcome.jsp'/>">轉(zhuǎn)發(fā)</a>
所以該超鏈接請(qǐng)求的資源為<s2:url value='/welcome.jsp'/>,很顯然不是預(yù)期的效果??梢詫?xiě)為如下形式:
<s2:a href="welcome.jsp">轉(zhuǎn)發(fā)</s2:a>
但是,如果超鏈接請(qǐng)求的資源是動(dòng)態(tài)改變的,或者傳遞的參數(shù)也是動(dòng)態(tài)改變的,這時(shí)可以使用HTML語(yǔ)言中的標(biāo)識(shí)來(lái)實(shí)現(xiàn):
<a href="<s2:url value="/welcome.jsp"/>">轉(zhuǎn)發(fā)</a>
<a href="welcome.jsp?name=<s2:url value='yxq'/>">傳參</a>
則上述代碼將生成如下HTML代碼:
<a href="welcome.jsp">轉(zhuǎn)發(fā)</a>
<a href="welcome.jsp?name=yxq">傳參</a>
1.13.2 Struts 2.0中的中文亂碼問(wèn)題
為在Struts 2.0中解決中文亂碼問(wèn)題,可在struts.properties文件中進(jìn)行如下配置。
struts.i18n.encoding=gb2312
struts.i18n.encoding用來(lái)設(shè)置Web應(yīng)用默認(rèn)的編碼,gb2312則指定了默認(rèn)的編碼。
該方法可以解決提交表單后出現(xiàn)的中文亂碼問(wèn)題。此時(shí),表單的method屬性值必須為post,若使用Struts 2.0中的form標(biāo)簽實(shí)現(xiàn)的表單,可省略method屬性,默認(rèn)值為post;若是通過(guò)原始的HTML語(yǔ)言的form標(biāo)識(shí)實(shí)現(xiàn)的表單,則需要設(shè)置method屬性,并賦值為post。
如果某個(gè)超鏈接傳遞的參數(shù)的值是中文字符,則在Action業(yè)務(wù)控制器中獲取該參數(shù)值后,必須進(jìn)行如下轉(zhuǎn)碼操作,否則獲取的值為亂碼。
String sqlvalue=request.getParameter("sqlvalue"); //獲取超鏈接傳遞的參數(shù)
sqlvalue=new String(sqlvalue.getBytes("ISO-8859-1"),"gb2312"); //進(jìn)行轉(zhuǎn)碼操作
1.14 Struts 2.0框架搭建與介紹
1.14.1 搭建Struts 2.0框架
本系統(tǒng)使用的Struts 2.0框架為Struts 2.0.11版本,讀者可到網(wǎng)站https://struts.apache.org/download.cgi # struts2011下載Full Distribution,F(xiàn)ull Distribution為Struts 2.0.11的完整版本,其中包含了Struts 2.0的類(lèi)庫(kù)、示例應(yīng)用、說(shuō)明文檔和源代碼等資源。解壓下載后的文件的目錄結(jié)構(gòu)如圖1.59所示。
下面介紹Struts 2.0框架的搭建。
1.導(dǎo)入Struts 2.0類(lèi)包文件
通常情況下,如果將如圖1.59所示的lib目錄下的commons-logging- 1.0.4.jar、freemarker-2.3.8.jar、ognl-2.6.11.jar、struts2-core-2.0.11.jar和xwork-2.0.4.jar包文件復(fù)制到Web應(yīng)用中的WEB-INF/lib目錄下,就可應(yīng)用Struts 2.0開(kāi)發(fā)項(xiàng)目了。如果想使用Struts 2.0中的更多功能,將其他的JAR包文件復(fù)制到WEB-INF/lib目錄下即可。
圖1.59 Struts 2.0框架目錄結(jié)構(gòu)
2.配置Web應(yīng)用的web.xml文件
打開(kāi)Web應(yīng)用中WEB-INF目錄下的web.xml文件,并進(jìn)行如下配置。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="https://java.sun.com/xml/ns/j2ee"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://java.sun.com/xml/ns/j2ee
https://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<filter>
<filter-name>struts2</filter-name> <!-- 命名Struts 2.0核心類(lèi) -->
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> <!-- 指定Struts 2.0核心類(lèi) -->
</filter>
<filter-mapping> <!-- 配置核心類(lèi)處理的請(qǐng)求 -->
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern> <!-- 指定處理用戶(hù)所有請(qǐng)求 -->
</filter-mapping>
</web-app>
經(jīng)過(guò)如上操作就完成了Struts 2.0框架的搭建。
Struts 2.0中提供的標(biāo)簽并沒(méi)有像Struts之前的版本那樣進(jìn)行分類(lèi),但在頁(yè)面中的使用方法是相同的,都需要通過(guò)taglib指令來(lái)引入,并指定一個(gè)前綴。Struts 2.0的標(biāo)簽描述文件存放在struts2-core-2.0.11.jar包中的META-INF目錄下,文件名為struts-tags.tld。以下為struts-tags.tld描述文件中的代碼片段:
<taglib>
<tlib-version>2.2.3</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>s</short-name>
<uri>/struts-tags</uri>
<display-name>"Struts Tags"</display-name>
……
</taglib>
代碼中的<uri>元素將該標(biāo)簽描述文件與/struts-tags名稱(chēng)進(jìn)行了映射,所以在JSP頁(yè)面中可直接通過(guò)如下代碼引入Struts 2.0標(biāo)簽。
<%@ taglib prefix="s2" uri="/struts-tags" %>
當(dāng)然也可以將標(biāo)簽復(fù)制到其他位置,然后在web.xml文件中指定。例如,將struts-tags.tld文件復(fù)制到Web應(yīng)用中的WEB-INF/tld目錄下,并在web.xml文件中進(jìn)行如下配置。
<taglib>
<taglib-uri>struts2</taglib-uri>
<taglib-location>/WEB-INF/tld/struts-tags.tld</taglib-location>
</taglib>
然后在JSP頁(yè)面中通過(guò)如下代碼引入Struts 2.0標(biāo)簽:
<%@ taglib prefix="s2" uri="struts2" %>
1.14.2 Struts 2.0框架介紹
Struts 2.0與Struts1.0存在很大的差別,因?yàn)镾truts 2.0是以WebWork為核心,可以說(shuō)是WebWork框架的升級(jí)版本,因此具有WebWork開(kāi)發(fā)經(jīng)驗(yàn)的讀者,會(huì)更容易學(xué)習(xí)Struts 2.0框架。
1.控制器
Struts 2.0中的控制器分為核心控制器和業(yè)務(wù)控制器(用戶(hù)控制器),其中業(yè)務(wù)控制器是用戶(hù)創(chuàng)建的Action類(lèi)。下面介紹這兩種控制器。
核心控制器:FilterDispatcher。
FilterDispatcher類(lèi)存在于org.apache.struts2.dispatcher包下,繼承了javax.servlet.Filter接口。在應(yīng)用的web.xml文件中需要配置該控制器,用來(lái)接收用戶(hù)的所有請(qǐng)求,F(xiàn)ilterDispatcher會(huì)判斷請(qǐng)求是否為*.action模式,如果匹配,則FilterDispatcher將請(qǐng)求轉(zhuǎn)發(fā)給Struts 2.0框架進(jìn)行處理。在web.xml文件中對(duì)FilterDispatcher的配置可查看1.14.1節(jié)中的介紹。
業(yè)務(wù)控制器。
由用戶(hù)創(chuàng)建的Action類(lèi)實(shí)例,充當(dāng)著Struts 2.0中的業(yè)務(wù)控制器,也可稱(chēng)為用戶(hù)控制器。創(chuàng)建Action類(lèi)時(shí),通常使其繼承Struts 2.0包中的com.opensymphony.xwork2.ActionSupport類(lèi)。在Action類(lèi)中可實(shí)現(xiàn)execute()方法,當(dāng)有請(qǐng)求訪問(wèn)該Action類(lèi)時(shí),execute()方法會(huì)被調(diào)用來(lái)處理請(qǐng)求,這與Struts之前的版本中Action的處理是相同的。
在Struts之前的版本中,若Action類(lèi)繼承自org.apache.struts.actions.DispatchAction父類(lèi),那么該Action會(huì)根據(jù)用戶(hù)請(qǐng)求調(diào)用相應(yīng)的自定義方法來(lái)處理請(qǐng)求,不必實(shí)現(xiàn)execute()方法。同樣,在Struts 2.0中要實(shí)現(xiàn)這樣的功能,可通過(guò)兩種方法,即在配置文件中的指明調(diào)用方法和在請(qǐng)求路徑中的指明調(diào)用方法。具體的使用方法在前面已經(jīng)作了講解,讀者可查看1.7.3節(jié)“列表顯示信息的實(shí)現(xiàn)過(guò)程”中的 內(nèi)容。
同之前的版本一樣,Struts 2.0也需要在配置文件中對(duì)Action進(jìn)行配置。該配置主要就是將用戶(hù)請(qǐng)求與業(yè)務(wù)控制器進(jìn)行關(guān)聯(lián),然后指定請(qǐng)求處理結(jié)束后返回的視圖資源。例如:
<!-- 若請(qǐng)求路徑中包含“userLogin.action”,則轉(zhuǎn)發(fā)給LoginAction業(yè)務(wù)控制器 -->
<action name="userLogin" class="com.yxq.action.LoginAction">
<result>/welcome.jsp</result> <!-- 登錄成功后,轉(zhuǎn)發(fā)到welcome.jsp頁(yè)面 -->
<result name="loginError">/login.jsp</result> <!-- 登錄失敗后,轉(zhuǎn)發(fā)到login.jsp頁(yè)面 -->
</action>
在Struts 2.0中可使用攔截器處理請(qǐng)求。在一些攔截器中通過(guò)com.opensymphony.xwork2.Action- Context類(lèi)將請(qǐng)求、會(huì)話與Map對(duì)象進(jìn)行了映射。在開(kāi)發(fā)程序時(shí),若僅僅是對(duì)請(qǐng)求或會(huì)話進(jìn)行存取數(shù)據(jù)的操作,則可使創(chuàng)建的Action控制器繼承相應(yīng)的接口,在攔截器中來(lái)判斷該Action控制器是哪個(gè)接口的實(shí)例,根據(jù)判斷,生成一個(gè)與請(qǐng)求進(jìn)行映射的Map對(duì)象或與會(huì)話進(jìn)行映射的Map對(duì)象。在用戶(hù)的Action控制器中,對(duì)這些Map對(duì)象進(jìn)行數(shù)據(jù)存取操作,即可實(shí)現(xiàn)對(duì)請(qǐng)求或會(huì)話的數(shù)據(jù)存取操作。
Struts 2.0中實(shí)現(xiàn)該功能的攔截器為ServletConfigInterceptor,它存放在struts2-core-2.0.11.jar中的org.apache.struts2.interceptor包下,其部分代碼如下:
public String intercept(ActionInvocation invocation) throws Exception {
final Object action = invocation.getAction(); //獲取請(qǐng)求要訪問(wèn)的Action控制器
final ActionContext context = invocation.getInvocationContext(); //獲取Action上下文
if (action instanceof ParameterAware) { //如果控制器是ParameterAware類(lèi)實(shí)例
((ParameterAware) action).setParameters(context.getParameters());
}
if (action instanceof RequestAware) { //如果控制器是RequestAware類(lèi)實(shí)例
((RequestAware) action).setRequest((Map) context.get("request"));
}
if (action instanceof SessionAware) { //如果控制器是SessionAware類(lèi)實(shí)例
((SessionAware) action).setSession(context.getSession());
}
……
return invocation.invoke(); //調(diào)用Action控制器
}