国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Never End...

第 16 章 Never End...

學習到此為止告一段落

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

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

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

現象:

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

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

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

對現象的理性說明

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

  2. jsp轉換成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,這里已經看不到getSession()的代碼了。

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

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

訪問test3.jsp會出現500服務器內部錯誤

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

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

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

16.2. 對手工將jsp轉換為servlet的無用討論

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

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

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

<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>

為了順利完成轉換工作,我們需要把一系列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的配置參數。

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

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

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

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

    比如我們轉換的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>    

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

  5. outputDir="./WEB-INF/src/"表示生成的servlet文件放在WEB-INF/src目錄下,tomcat會自動生成package對應的目錄,比如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。

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

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

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

在了解如何手工轉換jsp之后,我們可以來討論在數據庫中保存jsp的問題了。

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

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

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

16.3. 胡亂解釋一下session

會話都保存在服務器端。

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

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

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格式內容." ;response.setContentType("application/octet-stream;charset=UTF-8");response.setHeader("Content-Disposition", fileName);out.print(content);%>

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

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字符進行編碼。

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

  • IE6

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

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

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

    貌似不支持?上述方法都不行    
本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現有害或侵權內容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
深入理解Servlet/JSP之“Cookie和Session原理”
當你訪問網站時,Session會立刻建立嗎?
Resin服務器的使用(一篇不錯的文章,如果想使用resin做服務器建議看看)-JSP編程-華夏名網資訊中心 虛擬主機,域名注冊,雙線虛擬主機,服務器租賃,為7萬用戶提供服務
使用 Spring 2 Portlet MVC 框架構建 Portlet 應用
利用Servlet完成簡單的登錄注冊
關于servlet 和jsp 中的 session對象
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯系客服!

聯系客服