一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Never End...

 我是賴 2009-12-20

第 16 章 Never End...

學習到此為止告一段落

對教程內(nèi)容和jsp有什么建議的話,可以跟叮咚姐姐聯(lián)系,隨著技術(shù)的進步,我們也會同步更新教程的內(nèi)容。

16.1. 對session何時生成的無用討論

提出問題:“session是在什么時候生成的?”

現(xiàn)象:

  1. 如果寫一個servlet,在里邊調(diào)用getSession(false),得到的是null。(這里的參數(shù)表示當session不存在時是否新建,返回null表示還沒為當前用戶生成對應(yīng)的session)。

  2. 如果寫一個jsp,在里邊打印session,可以看到打印的信息,說明session已經(jīng)創(chuàng)建了。

對現(xiàn)象的感性認識:jsp會自動創(chuàng)建HttpSession對象,而servlet則不會,只有在servlet中顯式調(diào)用getSession()方法時才創(chuàng)建session。

對現(xiàn)象的理性說明

  1. 只有執(zhí)行了getSession()才會生成session。(此處無參數(shù),默認與getSession(true)功能相同)。

  2. jsp轉(zhuǎn)換成servlet后,生成的servlet代碼中包含getSession()。

    例子中見tomcat目錄下,work\Catalina\localhost\99-01\org\apache\jsp\test1.jsp,其中包含了pageContext.getSession()。

  3. 我們可以在jsp中使用<%@ page session="false"%>禁止生成session的代碼,這樣即使訪問此jsp頁面,也不會創(chuàng)建session。

    例子中見tomcat目錄下,work\Catalina\localhost\99-01\org\apache\jsp\test2.jsp,這里已經(jīng)看不到getSession()的代碼了。

因為<%@ page session="false"%>不會生成默認的session,在這個jsp頁面里就無法直接使用session變量了。下面的代碼會導致jsp無法編譯的錯誤。

<%@ page session="false"%>
<%
out.println(session);
%>
<hr />

訪問test3.jsp會出現(xiàn)500服務(wù)器內(nèi)部錯誤

在使用過<%@ page session="false"%>的頁面里只能使用getSession()手工獲得session才能使用了。

演示用代碼放在99-01目錄下,TestServlet映射到/請求路徑,test1.jsp會自動創(chuàng)建session,test2.jsp禁用了session,test3.jsp直接使用session會出現(xiàn)錯誤。

這個問題是典型的無用研究之一,實際工作中會有人使用getSession(false)嗎?

16.2. 對手工將jsp轉(zhuǎn)換為servlet的無用討論

有同學提到了一個問題:讓用戶自己編寫jsp上傳到服務(wù)器,服務(wù)器接收后保存入數(shù)據(jù)庫,在用戶訪問的時候從數(shù)據(jù)庫中取出對應(yīng)的jsp,運行后返回響應(yīng)。

這個效果從理論上講是可以實現(xiàn)的,我們已經(jīng)對jsp的運行機制非常熟悉了,第 6.2 節(jié) “jsp與servlet的關(guān)系”,我們只需要將jsp轉(zhuǎn)換為對應(yīng)servlet的java文件,再編譯為class,最后使用ClassLoader加載生成的class執(zhí)行即可。

好消息是tomcat為我們提供了批量轉(zhuǎn)換jsp的工具,使用以下的ant腳本就可以將指定目錄下的jsp轉(zhuǎn)換成對應(yīng)servlet的java代碼。(ant的使用方法已經(jīng)超出了本文的討論范圍,如果有興趣請自行參閱官方網(wǎng)站。http://ant./

<project name="jspc" default="jspc" basedir=".">
<property name="CATALINA_HOME" location="../../"/>
<path id="build.lib">
<pathelement location="WEB-INF/classes"/>
<fileset dir="WEB-INF/lib">
<include name="*.jar"/>
</fileset>
</path>
<target name="jspc">
<taskdef classname="org.apache.jasper.JspC" name="jasper2">
<classpath>
<pathelement location="${java.home}/../lib/tools.jar"/>
<fileset dir="${CATALINA_HOME}/server/lib">
<include name="*.jar"/>
</fileset>
<fileset dir="${CATALINA_HOME}/common/lib">
<include name="*.jar"/>
</fileset>
<path refid="build.lib"/>
</classpath>
</taskdef>
<jasper2 verbose="1"
package="org.apache.jsp"
uriroot="."
webXmlFragment="WEB-INF/generated_web.xml"
outputDir="./WEB-INF/src/" />
</target>
</project>

為了順利完成轉(zhuǎn)換工作,我們需要把一系列jar文件放入classpath中:

  1. WEB-INF/lib/*.jar(星號代表所有)

  2. ${java.home}/../lib/tools.jar(${java.home}表示jdk安裝目錄)

  3. ${CATALINA_HOME}/server/lib/*.jar(${CATALINA_HOME}表示tomcat的安裝目錄)

  4. ${CATALINA_HOME}/common/lib/*.jar

簡要介紹一下jasper2的配置參數(shù)。

  1. verbose="1"表示打印進度信息,如果verbose="0"則不打印信息。

  2. package="org.apache.jsp"表示生成servlet中的包名(package)。

  3. uriroot="."表示會把當前目錄下的所有jsp都轉(zhuǎn)換成servlet。

  4. webXmlFragment="WEB-INF/generated_web.xml"會在WEB-INF目錄下生成servlet的默認配置。

    比如我們轉(zhuǎn)換的test.jsp將生成如下部分。

    <servlet>
        <servlet-name>org.apache.jsp.test_jsp</servlet-name>
        <servlet-class>org.apache.jsp.test_jsp</servlet-class>
        </servlet>
        <servlet-mapping>
        <servlet-name>org.apache.jsp.test_jsp</servlet-name>
        <url-pattern>/test.jsp</url-pattern>
        </servlet-mapping>
        

    將這部分復(fù)制到你項目中的web.xml中就可以通過/test.jsp請求來訪問生成的servlet了。

  5. outputDir="./WEB-INF/src/"表示生成的servlet文件放在WEB-INF/src目錄下,tomcat會自動生成package對應(yīng)的目錄,比如test.jsp生成的最終路徑是WEB-INF/src/org/apache/jsp/test_jsp.java。

接著把生成的servlet編譯成class,這次除了common/lib/servlet-api.jar以外我們還需要common/lib/jasper-runtime.jar加入classpath中,編譯腳本參考WEB-INF/src/compile.bat。

現(xiàn)在可以刪除test.jsp了,web.xml中已經(jīng)將/test.jsp請求轉(zhuǎn)發(fā)至對應(yīng)的servlet處理,我們甚至不需要修改任何鏈接。

jspc的主要功能在于預(yù)先編譯jsp發(fā)現(xiàn)其中的語法錯誤,有些公司也使用這種方式進行加密(毫無意義的做法,把jsp唯一的靈活性都浪費了)。

演示程序在99-02目錄下,需要安裝ant之后才可能執(zhí)行run.bat將jsp轉(zhuǎn)換成servlet。

在了解如何手工轉(zhuǎn)換jsp之后,我們可以來討論在數(shù)據(jù)庫中保存jsp的問題了。

將jsp從數(shù)據(jù)庫中提取出來,將這些數(shù)據(jù)保存成本地文件,使用jspc轉(zhuǎn)換成servlet再編譯為class,最后使用自定義的ClassLoader讀取到j(luò)vm中執(zhí)行。

難點在于生成文件要保證互不影響和自定義ClassLoader如何加載管理這些生成的class。

這個問題是典型的無用研究之一,任何想獲得靈活模板功能的同學都應(yīng)該亦然決然的拋棄jsp,jsp這種先解釋編譯再執(zhí)行的機制不僅沒有幫助我們提升效率,反而大大增加技術(shù)難度并降低響應(yīng)效率。需要自定義模板的同志務(wù)必考慮velocity, freemarker此類模板引擎或者groovy一類腳本語言,這時使用jsp無異于給自己帶上一副沉重的枷鎖。

16.3. 胡亂解釋一下session

會話都保存在服務(wù)器端。

每個用戶打開瀏覽器就服務(wù)器就會給它生成一個sessionId,瀏覽器或者把這個sessionId放到cookie里,或者每次請求都帶在url后邊(自動的),然后服務(wù)器就拿到這個sessionid,在內(nèi)存里翻啊翻啊,翻出對應(yīng)的session來,就這么對應(yīng)上的。

ServletContext和session就沒多大關(guān)系了,雖然ServletContext也是在服務(wù)器端,每個web應(yīng)用發(fā)布的時候,就要創(chuàng)建這么一塊空間放置ServletContext,這個web應(yīng)用中的所有的servlet, jsp, filter, listener都可以訪問這塊空間。你可以把他看作是一個全局變量,所有共享數(shù)據(jù)都放到里邊。

16.4. 下載文件亂碼

參考 如何在PHP下載文件名中解決亂碼。

基本代碼如下:

<%@page contentType="text/html;charset=UTF-8"%><%request.setCharacterEncoding("utf-8");%><%
String client = request.getHeader("User-Agent");
String fileName = "中文";
if (client.indexOf("MSIE") > 0) {
fileName = "attachment; filename=\"" + java.net.URLEncoder.encode(fileName, "utf-8") + ".txt\"";
} else {
fileName = "attachment; filename*=\"utf8''" + java.net.URLEncoder.encode(fileName, "utf-8") + ".txt\"";
}
String content = "xml格式內(nèi)容." ;
response.setContentType("application/octet-stream;charset=UTF-8");
response.setHeader("Content-Disposition", fileName);
out.print(content);
%>

按照RFC2231的定義, 多語言編碼的Content-Disposition應(yīng)該這么定義:

Content-Disposition: attachment; filename*="utf8''%E4%B8%AD%E6%96%87%20%E6%96%87%E4%BB%B6%E5%90%8D.txt"
  • filename后面的等號之前要加 *

  • filename的值用單引號分成三段,分別是字符集(utf8)、語言(空)和urlencode過的文件名。

  • 最好加上雙引號,否則文件名中空格后面的部分在Firefox中顯示不出來。

  • 使用urlencode對非iso-8859-1字符進行編碼。

經(jīng)過試驗,發(fā)現(xiàn)幾種主流瀏覽器的支持情況如下:

  • IE6

    attachment; filename="<URL編碼之后的UTF-8文件名>"
        
  • FF3

    attachment; filename="UTF-8文件名"
        attachment; filename*="utf8''<URL編碼之后的UTF-8文件名>"
        
  • O9

    attachment; filename="UTF-8文件名"
        
  • Safari3(Win)

    貌似不支持?上述方法都不行
        

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    日韩中文高清在线专区| 老司机精品视频免费入口| 太香蕉久久国产精品视频| 午夜国产福利在线播放| 婷婷亚洲综合五月天麻豆| 欧美一本在线免费观看| 国产欧美一区二区久久| 人妻乱近亲奸中文字幕| 亚洲永久一区二区三区在线| 国产精品免费视频专区| 人妻久久一区二区三区精品99| 日本加勒比系列在线播放| 中文字幕禁断介一区二区| 亚洲国产精品av在线观看| 日本成人三级在线播放| 福利视频一区二区在线| 欧美精品在线观看国产| 欧美韩日在线观看一区| 久久午夜福利精品日韩| 九九热视频网在线观看| 欧美一区二区不卡专区| 亚洲一区二区三区有码| 91亚洲熟女少妇在线观看| 粉嫩内射av一区二区| 久久中文字幕中文字幕中文| 亚洲男人天堂网在线视频| 国产在线观看不卡一区二区| 丁香七月啪啪激情综合| 日韩精品日韩激情日韩综合| 人妻中文一区二区三区| 开心久久综合激情五月天| 欧美午夜一区二区福利视频| 色婷婷亚洲精品综合网| 欧美日韩国产成人高潮| 成人午夜激情在线免费观看 | 亚洲黄香蕉视频免费看| 在线观看视频日韩精品| 乱女午夜精品一区二区三区| 精品欧美日韩一区二区三区| 夜夜躁狠狠躁日日躁视频黑人| 亚洲国产av在线观看一区 |