免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

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

開通VIP
JSP技巧匯編
JSP中把動態(tài)頁面轉換成靜態(tài)頁面的技巧
要自動生成靜態(tài)頁面,用Filter截獲jsp請求并先進行預處理,自動生成Html,是個不錯的主意。一個很容易想到的方法是在Filter截獲Request后,導向一個Servlet,在這個Servlet中向本機發(fā)送一個http請求,然后將響應寫入一個文件:
URLConnection urlConn = URLConnection.open(http://localhost/req);
注意要避免遞歸。
另一個方法是不模擬http,而是定制Response,把服務器返回的JSP響應輸出到我們自己的Response中,就可以將響應快速寫入Html文件,然后再發(fā)送給客戶。而且,由于沒有http模擬請求,直接讀取服務器響應速度非常快。
截獲Response的關鍵便是實現(xiàn)一個WrappedResponse,讓服務器將響應寫入我們的WrappedResponse中。這類似于一個代理模式,Servlet2.x已經(jīng)提供了一個WrappedResponse類,我們只需要復寫其中的一些關鍵方法即可。
WrappedResponse實現(xiàn)了Response接口,它需要一個Response作為構造函數(shù)的參數(shù),事實上這正是代理模式的應用:WrappedResponse充當了代理角色,它會將JSP/Servlet容器的某些方法調用進行預處理,我們需要實現(xiàn)自己的方法。
綜上:用Filter實現(xiàn)HTML緩沖的步驟是:
1. 用Filter截獲請求,如/a.jsp?id=123,映射到對應的html文件名為/html/a.jsp$id=123.htm。
2. 查找是否有/html/a.jsp$id=123.htm,如果有,直接forward到此html,結束。
3. 如果沒有,實現(xiàn)一個WrappedResponse,然后調用filterChain(request, wrappedResponse)。
4. 將返回的WrappedResponse寫入文件/html/a.jsp$id=123.htm,然后返回響應給用戶。
5. 下一次用戶發(fā)送相同的請求時,到第2步就結束了。
使用這個方法的好處是不用更改現(xiàn)有的Servlet,JSP頁,限制是,JSP頁面結果不能與Session相關,需要登陸或用戶定制的頁面不能用這種方法緩沖。
JSP效率提升的幾點竅門
方法一:在servlet的init()方法中緩存數(shù)據(jù)
當應用服務器初始化servlet實例之后,為客戶端請求提供服務之前,它會調用這個servlet的init()方法。在一個servlet的生命周期中,init()方法只會被調用一次。通過在init()方法中緩存一些靜態(tài)的數(shù)據(jù)或完成一些只需要執(zhí)行一次的、耗時的操作,就可大大地提高系統(tǒng)性能。
例如,通過在init()方法中建立一個JDBC連接池是一個最佳例子,假設我們是用jdbc2.0的DataSource接口來取得數(shù)據(jù)庫連接,在通常的情況下,我們需要通過JNDI來取得具體的數(shù)據(jù)源。我們可以想象在一個具體的應用中,如果每次SQL請求都要執(zhí)行一次JNDI查詢的話,那系統(tǒng)性能將會急劇下降。解決方法是如下代碼,它通過緩存DataSource,使得下一次SQL調用時仍然可以繼續(xù)利用它:
public class ControllerServlet extends HttpServlet
{
private javax.sql.DataSource testDS = null;
public void init(ServletConfig config) throws ServletException
{
super.init(config);
Context ctx = null;
try
{
ctx = new InitialContext();
testDS = (javax.sql.DataSource)ctx.lookup("jdbc/testDS";
}
catch(NamingException ne)
{
ne.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public javax.sql.DataSource getTestDS()
{
return testDS;
}
...
...
}
方法 2:禁止servlet和JSP 自動重載(auto-reloading)
Servlet/JSP提供了一個實用的技術,即自動重載技術,它為開發(fā)人員提供了一個好的開發(fā)環(huán)境,當你改變servlet和JSP頁面后而不必重啟應用服務器。然而,這種技術在產(chǎn)品運行階段對系統(tǒng)的資源是一個極大的損耗,因為它會給JSP引擎的類裝載器(classloader)帶來極大的負擔。因此關閉自動重載功能對系統(tǒng)性能的提升是一個極大的幫助。
方法 3: 不要濫用HttpSession
在很多應用中,我們的程序需要保持客戶端的狀態(tài),以便頁面之間可以相互聯(lián)系。但不幸的是由于HTTP具有天生無狀態(tài)性,從而無法保存客戶端的狀態(tài)。因此一般的應用服務器都提供了session來保存客戶的狀態(tài)。在JSP應用服務器中,是通過HttpSession對像來實現(xiàn)session的功能的,但在方便的同時,它也給系統(tǒng)帶來了不小的負擔。因為每當你獲得或更新session時,系統(tǒng)者要對它進行費時的序列化操作。你可以通過對HttpSession的以下幾種處理方式來提升系統(tǒng)的性能:
如果沒有必要,就應該關閉JSP頁面中對HttpSession的缺省設置: 如果你沒有明確指定的話,每個JSP頁面都會缺省地創(chuàng)建一個HttpSession。如果你的JSP中不需要使用session的話,那可以通過如下的JSP頁面指示符來禁止它:
<%@ page session="false"%>
不要在HttpSession中存放大的數(shù)據(jù)對像:如果你在HttpSession中存放大的數(shù)據(jù)對像的話,每當對它進行讀寫時,應用服務器都將對其進行序列化,從而增加了系統(tǒng)的額外負擔。你在HttpSession中存放的數(shù)據(jù)對像越大,那系統(tǒng)的性能就下降得越快。
當你不需要HttpSession時,盡快地釋放它:當你不再需要session時,你可以通過調用HttpSession.invalidate()方法來釋放它。
盡量將session的超時時間設得短一點:在JSP應用服務器中,有一個缺省的session的超時時間。當客戶在這個時間之后沒有進行任何操作的話,系統(tǒng)會將相關的session自動從內存中釋放。超時時間設得越大,系統(tǒng)的性能就會越低,因此最好的方法就是盡量使得它的值保持在一個較低的水平。
方法 4: 將頁面輸出進行壓縮
壓縮是解決數(shù)據(jù)冗余的一個好的方法,特別是在網(wǎng)絡帶寬不夠發(fā)達的今天。有的瀏覽器支持gzip(GNUzip)進行來對HTML文件進行壓縮,這種方法可以戲劇性地減少HTML文件的下載時間。因此,如果你將servlet或JSP頁面生成的HTML頁面進行壓縮的話,那用戶就會覺得頁面瀏覽速度會非??臁5恍业氖?,不是所有的瀏覽器都支持gzip壓縮,但你可以通過在你的程序中檢查客戶的瀏覽器是否支持它。下面就是關于這種方法實現(xiàn)的一個代碼片段:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
OutputStream out = null
String encoding = request.getHeader("Accept-Encoding";
if (encoding != null && encoding.indexOf("gzip" != -1)
{
request.setHeader("Content-Encoding" , "gzip";
out = new GZIPOutputStream(request.getOutputStream());
}
else if (encoding != null && encoding.indexOf("comdivss" != -1)
{
request.setHeader("Content-Encoding" , "comdivss";
out = new ZIPOutputStream(request.getOutputStream());
}
else
{
out = request.getOutputStream();
}
...
...
}
方法 5: 使用線程池
應用服務器缺省地為每個不同的客戶端請求創(chuàng)建一個線程進行處理,并為它們分派service()方法,當service()方法調用完成后,與之相應的線程也隨之撤消。由于創(chuàng)建和撤消線程會耗費一定的系統(tǒng)資源,這種缺省模式降低了系統(tǒng)的性能。但所幸的是我們可以通過創(chuàng)建一個線程池來改變這種狀況。另外,我們還要為這個線程池設置一個最小線程數(shù)和一個最大線程數(shù)。在應用服務器啟動時,它會創(chuàng)建數(shù)量等于最小線程數(shù)的一個線程池,當客戶有請求時,相應地從池從取出一個線程來進行處理,當處理完成后,再將線程重新放入到池中。如果池中的線程不夠地話,系統(tǒng)會自動地增加池中線程的數(shù)量,但總量不能超過最大線程數(shù)。通過使用線程池,當客戶端請求急劇增加時,系統(tǒng)的負載就會呈現(xiàn)的平滑的上升曲線,從而提高的系統(tǒng)的可伸縮性。
方法 6: 選擇正確的頁面包含機制
在JSP中有兩種方法可以用來包含另一個頁面:1、使用include指示符(<%@ includee file=”test.jsp” %>)。2、使用jsp指示符(<jsp:includeepage=”test.jsp” flush=”true”/>)。在實際中我發(fā)現(xiàn),如果使用第一種方法的話,可以使得系統(tǒng)性能更高。
方法 7:正確地確定javabean的生命周期
JSP的一個強大的地方就是對javabean的支持。通過在JSP頁面中使用<jsp:useBean>標簽,可以將javabean直接插入到一個JSP頁面中。它的使用方法如下:
<jsp:useBean id="name" scope="page|request|session|application" class=
"package.className" type="typeName">
</jsp:useBean>
其中scope屬性指出了這個bean的生命周期。缺省的生命周期為page。如果你沒有正確地選擇bean的生命周期的話,它將影響系統(tǒng)的性能。
舉例來說,如果你只想在一次請求中使用某個bean,但你卻將這個bean的生命周期設置成了session,那當這次請求結束后,這個bean將仍然保留在內存中,除非session超時或用戶關閉瀏覽器。這樣會耗費一定的內存,并無謂的增加了JVM垃圾收集器的工作量。因此為bean設置正確的生命周期,并在bean的使命結束后盡快地清理它們,會使用系統(tǒng)性能有一個提高
其它一些有用的方法
在字符串連接操作中盡量不使用“+”操作符:在java編程中,我們常常使用“+”操作符來將幾個字符串連接起來,但你或許從來沒有想到過它居然會對系統(tǒng)性能造成影響吧?由于字符串是常量,因此JVM會產(chǎn)生一些臨時的對像。你使用的“+”越多,生成的臨時對像就越多,這樣也會給系統(tǒng)性能帶來一些影響。解決的方法是用StringBuffer對像來代替“+”操作符。
避免使用System.out.println()方法:由于System.out.println()是一種同步調用,即在調用它時,磁盤I/O操作必須等待它的完成,因此我們要盡量避免對它的調用。但我們在調試程序時它又是一個必不可少的方便工具,為了解決這個矛盾,我建議你最好使用Log4j工具(http://Jakarta.apache.org,它既可以方便調試,而不會產(chǎn)生System.out.println()這樣的方法。
ServletOutputStream 與PrintWriter的權衡:使用PrintWriter可能會帶來一些小的開銷,因為它將所有的原始輸出都轉換為字符流來輸出,因此如果使用它來作為頁面輸出的話,系統(tǒng)要負擔一個轉換過程。而使用ServletOutputStream作為頁面輸出的話就不存在一個問題,但它是以二進制進行輸出的。因此在實際應用中要權衡兩者的利弊。
JSP/Servlet重定向
1.RequestDispatcher.forward()
是在服務器端起作用,當使用forward()時,Servletengine傳遞HTTP請求從當前的Servlet or JSP到另外一個Servlet,JSP或普通HTML文件,也即你的form提交至a.jsp,在a.jsp用到了forward()重定向至b.jsp,此時form提交的所有信息在b.jsp都可以獲得,參數(shù)自動傳遞.
但forward()無法重定向至有frame的jsp文件,可以重定向至有frame的html文件,同時forward()無法在后面帶參數(shù)傳遞,比如servlet?name=frank,這樣不行,可以程序內通過response.setAttribute("name",name)來傳至下一個頁面.
重定向后瀏覽器地址欄URL不變.
例:在servlet中進行重定向
public void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException
{
response.setContentType("text/html; charset=gb2312");
ServletContext sc = getServletContext();
RequestDispatcher rd = null;
rd = sc.getRequestDispatcher("/index.jsp"); //定向的頁面
rd.forward(request, response);
}
通常在servlet中使用,不在jsp中使用。
2.response.sendRedirect()
是在用戶的瀏覽器端工作,sendRedirect()可以帶參數(shù)傳遞,比如servlet?name=frank傳至下個頁面,同時它可以重定向至不同的主機上,sendRedirect()可以重定向有frame.的jsp文件.
重定向后在瀏覽器地址欄上會出現(xiàn)重定向頁面的URL
例:在servlet中重定向
public void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException
{
response.setContentType("text/html; charset=gb2312");
response.sendRedirect("/index.jsp");
}
由于response是jsp頁面中的隱含對象,故在jsp頁面中可以用response.sendRedirect()直接實現(xiàn)重定位。
注意:
(1).使用response.sendRedirect時,前面不能有HTML輸出。
這并不是絕對的,不能有HTML輸出其實是指不能有HTML被送到了瀏覽器。事實上現(xiàn)在的server都有cache機制,一般在8K(我是說JSP SERVER),這就意味著,除非你關閉了cache,或者你使用了out.flush()強制刷新,那么在使用sendRedirect之前,有少量的HTML輸出也是允許的。
(2).response.sendRedirect之后,應該緊跟一句return;
我們已經(jīng)知道response.sendRedirect是通過瀏覽器來做轉向的,所以只有在頁面處理完成后,才會有實際的動作。既然你已經(jīng)要做轉向了,那么后的輸出還有什么意義呢?而且有可能會因為后面的輸出導致轉向失敗。
比較:
(1).Request Dispatcher.forward()是容器中控制權的轉向,在客戶端瀏覽器地址欄中不會顯示出轉向后的地址;
(2).response.sendRedirect()則是完全的跳轉,瀏覽器將會得到跳轉的地址,并重新發(fā)送請求鏈接。這樣,從瀏覽器的地址欄中可以看到跳轉后的鏈接地址。
前者更加高效,在前者可以滿足需要時,盡量使用RequestDispatcher.forward()方法.
注:在有些情況下,比如,需要跳轉到一個其它服務器上的資源,則必須使用HttpServletResponse.sendRequest()方法。
3.
<jsp:forward page="" />
它的底層部分是由RequestDispatcher來實現(xiàn)的,因此它帶有RequestDispatcher.forward()方法的印記。
如果在 jsp:forward 之前有很多輸出,前面的輸出已使緩沖區(qū)滿,將自動輸出到客戶端,那么該語句將不起作用,這一點應該特別注意。
另外要注意:它不能改變?yōu)g覽器地址,刷新的話會導致重復提交
4.修改HTTP header的Location屬性來重定向
通過設置直接修改地址欄來實現(xiàn)頁面的重定向。
jsp文件代碼如下:
<%
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
String newLocn = "/newpath/jsa.jsp";
response.setHeader("Location",newLocn);
%>
5.JSP中實現(xiàn)在某頁面停留若干秒后,自動重定向到另一頁面
在html文件中,下面的代碼:
<meta http-equiv="refresh" content="300; url=target.jsp">
它的含義:在5分鐘之后正在瀏覽的頁面將會自動變?yōu)閠arget.html這一頁。代碼中300為刷新的延遲時間,以秒為單位。targer.html為你想轉向的目標頁,若為本頁則為自動刷新本頁。
由上可知,可以通過setHeader來實現(xiàn)某頁面停留若干秒后,自動重定向到另一頁面。
關鍵代碼:
String content=stayTime+";URL="+URL;
response.setHeader("REFRESH",content);
JSP中的pageEncoding和contentType
關于JSP頁面中的pageEncoding和contentType兩種屬性的區(qū)別:
pageEncoding是jsp文件本身的編碼
contentType的charset是指服務器發(fā)送給客戶端時的內容編碼
JSP要經(jīng)過兩次的“編碼”,第一階段會用pageEncoding,第二階段會用utf-8至utf-8,第三階段就是由Tomcat出來的網(wǎng)頁, 用的是contentType。
第一階段是jsp編譯成.java,它會根據(jù)pageEncoding的設定讀取jsp,結果是由指定的編碼方案翻譯成統(tǒng)一的UTF-8 JAVA源碼(即.java),如果pageEncoding設定錯了,或沒有設定,出來的就是中文亂碼。
第二階段是由JAVAC的JAVA源碼至java byteCode的編譯,不論JSP編寫時候用的是什么編碼方案,經(jīng)過這個階段的結果全部是UTF-8的encoding的java源碼。
JAVAC用UTF-8的encoding讀取java源碼,編譯成UTF-8 encoding的二進制碼(即.class),這是JVM對常數(shù)字串在二進制碼(java encoding)內表達的規(guī)范。
第三階段是Tomcat(或其的application container)載入和執(zhí)行階段二的來的JAVA二進制碼,輸出的結果,也就是在客戶端見到的,這時隱藏在階段一和階段二的參數(shù)contentType就發(fā)揮了功效
contentType的設定.
pageEncoding 和contentType的預設都是ISO8859-1. 而隨便設定了其中一個, 另一個就跟著一樣了(TOMCAT4.1.27是如此). 但這不是絕對的,這要看各自JSPC的處理方式. 而pageEncoding不等于contentType, 更有利亞洲區(qū)的文字CJKV系JSP網(wǎng)頁的開發(fā)和展示, (例pageEncoding=GB2312 不等于 contentType=utf-8)。
jsp文件不像.java,.java在被編譯器讀入的時候默認采用的是操作系統(tǒng)所設定的locale所對應的編碼,比如中國大陸就是GBK,臺灣就是BIG5或者MS950。而一般我們不管是在記事本還是在ue中寫代碼,如果沒有經(jīng)過特別轉碼的話,寫出來的都是本地編碼格式的內容。所以編譯器采用的方法剛好可以讓虛擬機得到正確的資料。
但是jsp文件不是這樣,它沒有這個默認轉碼過程,但是指定了pageEncoding就可以實現(xiàn)正確轉碼了。
舉個例子:
<%@ page contentType="text/html;charset=utf-8" %>
大都會打印出亂碼,因為我輸入的“你好嗎”是gbk的,但是服務器是否正確抓到“你好嗎”不得而知。
但是如果更改為
<%@ page contentType="text/html;charset=utf-8" pageEncoding="GBK"%>
這樣就服務器一定會是正確抓到“你好嗎”了。
JSP中的兩種include
我們都知道在jsp中include有兩種形式,分別是
< %@ include file=” ”%>
< jsp:include page=” ” flush=”true”/>
前者是指令元素、后者是行為元素。具體它們將在何處用?如何用及它們有什么區(qū)別?這應該是很多人看到它都會想到的問題。下面一起來看看吧。
通常當應用程序中所有的頁面的某些部分(例如標題、頁腳和導航欄)都相同的時候,我們就可以考慮用include。具體在哪些時候用< %@ include file=” ”%>,哪些時候用<jsp:include page=” ”flush=”true”/>.這種形式。首先要明白的是它們之間的區(qū)別。只有了解了它們用法的不同才理解該在何時去用以及如何選擇。
< %@ include file=” ”%>,jsp的include指令元素讀入指定頁面的內容。并把這些內容和原來的頁面融合到一起。(這個過程是在翻譯階段:也就是jsp被轉化成servlet的階段進行的。
這里對翻譯階段進行一下說明:我們知道,jsp頁面不能原封不動地被傳送給瀏覽器,所有的jsp元素都必須首先由服務器進行處理。這是通過將jsp頁面轉達化成servlet,然后執(zhí)行這個servlet來完成的。服務器需要一個jsp容器來處理jsp頁面。jsp容器通常以servlet的形式來實現(xiàn),這個servlet經(jīng)過配置,可以處理對jsp頁面的所有請求。
Jsp容器負責將jsp頁面轉化成servlet(稱為jsp頁面實現(xiàn)類?JSP Page implementation class),并編譯這個servlet。這兩步就構成了翻譯階段.
由此我們就會知道:jsp頁面是把include指令元素所指定的頁面的實際內容(也就是代碼段)加入到引入它的jsp頁面中,合成一個文件后被jsp容器將它轉化成servlet??梢钥吹竭@時會產(chǎn)生一個臨時class文件和一個java文件。下面舉個例子。
服務器用tomcat,引入頁面的jsp文件叫test.jsp。被引入的頁面叫date.jsp.這個jsp文件里存放的是一個有關時間的jsp代碼,當前的上下文根設為test
//======date.jsp的源文件=====//
<%@ page language=”java” contentType="text/html;charset=gb2312"%>
<%
java.util.Date date=new java.util.Date();
String date_cn ="";
String dateStr = "";
switch(date.getDay())
{
case 0:date_cn ="日"; break;
case 1:date_cn ="一"; break;
case 2:date_cn ="二"; break;
case 3:date_cn ="三"; break;
case 4:date_cn ="四"; break;
case 5:date_cn ="五"; break;
case 6:date_cn ="六"; break;
}
dateStr = (1900+date.getYear())+"年"+(date.getMonth()+1)+"月"+date.getDate()+
"日(星期" + date_cn + ")";
%>
document.write("<%=dateStr%>");
//======以下是test.jsp的源文件=============//
<%@ page language=”java” contentType=”text/html;charset=gb2312”%>
<html>
<head>
<title>include的兩種用法</title>
<jsp:include page=”date.jsp” flush=”true”/>
<%--@ include file=”date.jsp” %-->
//我們在這里用include的兩種不同形式來引入date.jsp這個文件.
<head>
<body>
<table><tr><td>
有關jsp中include的兩種用法.敬請關注。
</td></tr></table>
</body>
</html>
在test.jsp 文件中,我們只輸出了一行文本“有關jsp中include的兩種用法.敬請關注。”,現(xiàn)在讓我們先用<%@ include file=”date.jsp”%>這種形式引入date.jsp這個文件。你想會出現(xiàn)什么問題了嗎?此時出現(xiàn)了錯誤提示:
HTTP Status 500 ?
org.apache.jasper.JasperException: /date.jsp(0,0) Page directive:
can't have multiple occurrences of contentType
以下還有一堆錯誤,但我們只要看這里就知道問題的所在了。狀態(tài)碼為http 500服務器內部錯誤。再看下面的提示。在date.jsp頁面中不能指定多個contentType.
原因就在這里了。是因為在翻譯階段,date.jsp文件的代碼被原封不動地加入到了test.jsp頁面從而合成一個文件。合成后的文件中就會相同的:
< %@ page language=”java” contentType=”text/html;charset=gb2312”%>
這句代碼。解決的辦法是把date.jsp文件中的這句刪掉。刷新后再請求test.jsp頁面
請求test.jsp在頁面顯示如下
2003年12月10日 13:12:40
有關jsp中include的兩種用法.敬請關注。
這時我們還不能發(fā)現(xiàn)什么。還是去查看tomcat下的臨時文件吧。到那里去看看date.jsp文件的內容是否已被加入到了test.jsp文件中。
< 注.此處的tomcat裝在E盤根目錄下>
目錄
E:\tomcat\work\Standalone\localhost\test.
在這個目錄下會看到
test_jsp.java和test_jsp.class兩個文件。
這里的java文件就是jsp容器將jsp轉化成了servlet而得到的test_jsp.java這個文件。
相對應的test_jsp.class這個文件就是編譯test_jsp.java這個servlet文件產(chǎn)生的類文件了。打開所產(chǎn)生的servlet文件(test_jsp.java)。此時我們會發(fā)現(xiàn),在test.jsp文件被轉化成servlet文件時,在輸出的< haed >之間加入了一些不是test.jsp頁面里面的代碼,新加入的內容就是date.jsp里面的代碼: 新加入了哪些內容或是否真的加入了新的內容請自己測試去看一下就會一目了然了.在這里不再詳述.
以上就是我們用< %@ include file=”date.jsp”%>這種形式得到的結果.
下面我們換用< jsp:include page=”dae.jsp” flush=”true”/>也就是將
< %@ include file=”date.jsp”%>換成< jsp:include page=”dae.jsp” flush=”true”/>,然后請求test.jsp.
2003? ê 12??10?? 13:30:13
有關jsp中include的兩種用法.敬請關注。
此時會在頁面上看見.我們所引入date.jsp輸出的日期中中文出現(xiàn)了亂碼.什么原因?是因為include行為元素是在請求處理階段執(zhí)行的(此處要對請求處理階段進行說明一下.Jsp容器除了上面提到的負責將jsp頁面轉化成servlet外,還負責調用jsp頁面實現(xiàn)類以處理每個請求并產(chǎn)生應答.這個階段我們就稱為請求處理階段.請求處理階段僅執(zhí)行類文件)。
所以在我們作include行為元素引入頁面時,實際只是引用了date.jsp這個文件被轉化并被編譯后產(chǎn)生的servlet類文件.既如此,date.jsp就是作為一個單獨的文件在執(zhí)行后才被test.jsp文件運行時調用.由于date.jsp文件中沒有指定字符編碼.所以出現(xiàn)了亂碼.解決辦法是在date.jsp文件中重新把剛才去掉的
<%@ page language=”java” contentType=”text/html;charset=gb2312”%>
這行語句加入后刷新重新運行.此時頁面顯示正確,并跟用include指令正常運行時一樣.再查看tomcat下的臨時文件會發(fā)現(xiàn).此時多出了一個date_jsp.java文件和一個date_jsp.class文件.這兩個文件得來的方式跟test_jsp.java和test_jsp.class文件得來的方式一樣.再查看一下此時test_jsp.java文件的代碼會發(fā)現(xiàn).此時只新增加了一句代碼:
JspRuntimeLibrary.include(request, response, "date.jsp", out, true);
它并沒有把date.jsp文件的代碼加入到test.jsp.
只是在運行時引入了date.jsp頁面執(zhí)行后所產(chǎn)生的應答.這意味著我們可以指定任何能夠產(chǎn)生應答的Web資源,(例如一個servlet或一個jsp頁面),只要這些資源所產(chǎn)生的類型和jsp頁面產(chǎn)生的內容類型相同.JSP容器將通過一個內部的函數(shù)調用來執(zhí)行指定的資源.因此,這些被引入的資源可以幫助處理原來的請求,所以這些資源可以訪問請求作用域內的所有對象.以及所有原來的請求參數(shù).
由于在主頁面被請求時,這些頁面還沒有被引入到主頁面中,所以你可以對page屬性使用一個請求時屬性值,以便根據(jù)運行時的情況來決定要引入哪一個頁面.還可以添加一些將被引入的頁面讀取的請求參數(shù).
<jsp:include page=”<%=pageSelectedAtRuntime%>” flush=”true” >
<jsp:param name=”fitstParamer” value=”firstValue”>
<jsp:param name=”lastParamer” value=”lastValue”>
</jsp:include>
如果修改了被引入的jsp頁面,那么可以立刻使用該頁面的最新版本,這是因為對待被引入的頁面的方式與對待由瀏覽器直接調用的jsp頁面的方式完全相同.即容器檢測頁面的變化,并自動進入翻譯階段,以得到頁面的最新版本.
(注意,include行為元素同jsp其它元素一樣,沒有行為體時要以”/”結束.就像下面這樣.
< jsp:include page=”<%=pageSelectedAtRuntime%>” flush=”true” />
以下是對include 兩種用法的區(qū)別
主要有兩個方面的不同;
1.執(zhí)行時間上:
< %@ include file=”relativeURI”%> 是在翻譯階段執(zhí)行
< jsp:include page=”relativeURI” flush=”true” /> 在請求處理階段執(zhí)行.
2.引入內容的不同:
< %@ include file=”relativeURI”%>
引入靜態(tài)文本(html,jsp),在JSP頁面被轉化成servlet之前和它融和到一起.
< jsp:include page=”relativeURI” flush=”true” />引入執(zhí)行頁面或servlet所生成的應答文本.
另外在兩種用法中file和page屬性都被解釋為一個相對的URI.如果它以斜杠開頭,那么它就是一個環(huán)境相關的路徑.將根據(jù)賦給應用程序的URI的前綴進行解釋,如果它不是以斜杠開頭,那么就是頁面相關的路徑,就根據(jù)引入這個文件的頁面所在的路徑進行解釋.更多有關URL是如何解釋的請參考相關資料或書籍。
解決JSP中文問題
方法一:最簡單也是用的最多的方法
<%@ page language="java" pageEncoding="GBK" %>
或者<%@ page contenttype="text/html;charset=gbk";>這里可以用gb2312或者gbk,只是gbk比gb2312支持跟多的字符。
這個方法用于jsp頁面中的中文顯示。
方法二:使用過濾器
過濾器使用主要針對表單提交,插入數(shù)據(jù)庫的數(shù)據(jù)都是?號。這也是應為tomcat不按request所指定的編碼進行編碼,還是自作主張的采用默認編碼方式iso-8859-1編碼。
編寫一個SetCharacterEncodingFilter類。
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class SetCharacterEncodingFilter implements Filter {
protected String encoding = null;
protected FilterConfig filterConfig = null;
protected boolean ignore = true;
public void init(FilterConfig filterConfig) throws ServletException {
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
this.ignore=false;
}
public void doFilter(
ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO 自動生成方法存根
if (ignore || (request.getCharacterEncoding() == null)) {
String encoding = selectEncoding(request);
if (encoding != null)
request.setCharacterEncoding(encoding);
}
chain.doFilter(request, response);
}
public void destroy() {
// TODO 自動生成方法存根
this.encoding = null;
this.filterConfig = null;
}
protected String selectEncoding(ServletRequest request) {
return (this.encoding);
}
}
然后再web.xml加上
<!-- Set Character Encoding-->
<filter>
<filter-name>Set Character Encoding</filter-name>
<filter-class>com.struts.common.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Set Character Encoding-->
使用過濾器的好處很多,特別是項目之中。
而且在使用國際化時就更有用了,只要在頁面指定 <%@ page language="java" pageEncoding="UTF-8" %>,服務器就會根據(jù)本地Locale來顯示正確的字符集。
所以我特別推薦使用過濾器。
方法三:修改tomcat的server.xml文件中URIEncoding
<Connector debug="0" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true"
port="80" redirectPort="8443" enableLookups="false" minSpareThreads="25" maxSpareThreads="75"
maxThreads="150" maxPostSize="0" URIEncoding="GBK" >
</Connector>
這個方法主要針對從url中獲取字符串的問題。
在tomcat5.0及以上版本,post和get方法在處理編碼時有所不同。如果你在url中獲取中文就會出現(xiàn)?號。但在tomcat4.1版本沒有問題,因為tomcat4.1的post和get方法在處理編碼時是一樣的。
本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
JSP頁面編碼問題研究 [簡便]
struts,ajax亂碼解決方案
JSP中的pagaEncoding和contentType中charset的區(qū)別
JSP將頁面輸出進行壓縮
《Java Web 應用程序設計立體化教程》第1章Java Web 應用概述
JAVAEE企業(yè)級應用開發(fā)淺談之MVC 中的V-VIEW視圖
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服