本文目錄一覽:
- 1、編寫一個JSP頁面,該頁面提供一個表單,用戶通過表單輸入半徑提交後,JSP頁面將計算圓的周長與面積的任務
- 2、求jsp代碼,題目如下:
- 3、JSP 頁面跳轉問題 求助
- 4、假設需要編寫一個JSP頁面input.jsp,該頁面提供一個表單。。。 來JAVA大神
- 5、jsp頁面的代碼
- 6、如何避免logout後,後退按鈕依舊顯示緩存的有關問題
編寫一個JSP頁面,該頁面提供一個表單,用戶通過表單輸入半徑提交後,JSP頁面將計算圓的周長與面積的任務
1、新建一個JSP頁面,寫一個Form,在這個Form中寫一個文本框用於接收用戶輸入的半徑,在寫一個提交按鈕
2、新建一個Servlet,用於接受上一個JSP的請求,在Servlet中獲取提交的參數——半徑,然後完成計算,將計算結果放在Request中,然後轉發到另一個JSP
3、新建一個JSP頁面,用於顯示結果。獲取request中的計算結果並顯示
求jsp代碼,題目如下:
rect.jsp
%@ page language=”java” pageEncoding=”utf-8″%
!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
html
head
/head
body
form action=”com.jsp” method=”post”
請輸入正方形的邊長: input type=”text” name=”length” width=”100px”
br/ br/
input type=”submit” value=”submit”
/form
/body
/html
com.jsp
%@ page language=”java” pageEncoding=”utf-8″%
!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
html
head
/head
body
%
String length=request.getParameter(“length”);
float s=0;
try{
s=Float.parseFloat(length);
}
catch (Exception e)
{
out.print(“請輸入有效數值brbr”);
s=0;
}
%
正方形周長為: %=4*s %br/
正方形面積為: %=s*s %br/
/body
/html
JSP 頁面跳轉問題 求助
每個表單里都設置一個隱藏域,取相同的名字不同的值,在R.jsp里String hid=request.getParameter(“param”)取得隱藏域的值,hid.equals(“”)作為條件
或者表單的action=”R.jsp?param=a/b/c”,R.jsp里同上取參數
假設需要編寫一個JSP頁面input.jsp,該頁面提供一個表單。。。 來JAVA大神
input.jsp:
form action=”show.jsp” method=”post”
用戶名:input type=”text” name=”userName” /br/
密碼:input type=”password” name=”password” /br/
電子郵箱:input type=”text” name=”email” /br/
地址:input type=”text” name=”address” /br/
input type=”submit” value=”提交” /
/form
show.jsp:
%
String userName = request.getParameter(“userName”);
String password = request.getParameter(“password”);
String email = request.getParameter(“email”);
String address = request.getParameter(“address”);
out.print(“用戶名:” + userName);
out.print(“br/”);
out.print(“密碼:” + password);
out.print(“br/”);
out.print(“郵箱:” + email);
out.print(“br/”);
out.print(“地址:” + address);
out.print(“br/”);
%
jsp頁面的代碼
Vector v=(Vector)application.getAttribute(“Mess”);//這行代碼是聲明一個Vector 變量,此變量是一個鍵值對象
其他的太 多了不想寫
如何避免logout後,後退按鈕依舊顯示緩存的有關問題
JSP示例
為了更為有效地闡述實現方案,本文將從展示一個示例應用logoutSampleJSP1中碰到的問題開始。這個示例代表了許多沒有正確解決退出過程的Web應用。logoutSampleJSP1包含了下述jsp頁面:login.jsp, home.jsp, secure1.jsp, secure2.jsp, logout.jsp, loginAction.jsp, and logoutAction.jsp。其中頁面home.jsp, secure1.jsp, secure2.jsp, 和logout.jsp是不允許未經認證的用戶訪問的,也就是說,這些頁面包含了重要信息,在用戶登陸之前或者退出之後都不應該出現在瀏覽器中。login.jsp包含了用於用戶輸入用戶名和密碼的form。logout.jsp頁包含了要求用戶確認是否退出的form。loginAction.jsp和logoutAction.jsp作為控制器分別包含了登陸和退出代碼。
第二個示例應用logoutSampleJSP2展示了如何解決示例logoutSampleJSP1中的問題。然而,第二個應用自身也是有疑問的。在特定的情況下,退出問題還是會出現。
第三個示例應用logoutSampleJSP3在第二個示例上進行了改進,比較完善地解決了退出問題。
最後一個示例logoutSampleStruts展示了Struts如何優美地解決登陸問題。
注意:本文所附示例在最新版本的Microsoft Internet Explorer (IE), Netscape Navigator, Mozilla, FireFox和Avant瀏覽器上測試通過。
Login action
Brian Pontarelli的經典文章《J2EE Security: Container Versus Custom》討論了不同的J2EE認證途徑。文章同時指出,HTTP協議和基於form的認證並未提供處理用戶退出的機制。因此,解決途徑便是引入自定義的安全實現機制。
自定義的安全認證機制普遍採用的方法是從form中獲得用戶輸入的認證信息,然後到諸如LDAP (lightweight directory access protocol)或關係數據庫的安全域中進行認證。如果用戶提供的認證信息是有效的,登陸動作往HttpSession對象中注入某個對象。HttpSession存在着注入的對象則表示用戶已經登陸。為了方便讀者理解,本文所附的示例只往HttpSession中寫入一個用戶名以表明用戶已經登陸。清單1是從loginAction.jsp頁面中節選的一段代碼以此闡述登陸動作:
Listing 1
//…
//initialize RequestDispatcher object; set forward to home page by default
RequestDispatcher rd = request.getRequestDispatcher(“home.jsp”);
//Prepare connection and statement
rs = stmt.executeQuery(“select password from USER where userName = ‘” + userName + “‘”);
if (rs.next()) {
//Query only returns 1 record in the result set; only 1
password per userName which is also the primary key
if (rs.getString(“password”).equals(password)) { //If valid password
session.setAttribute(“User”, userName); //Saves username string in the session object
}
else { //Password does not match, i.e., invalid user password
request.setAttribute(“Error”, “Invalid password.”);
rd = request.getRequestDispatcher(“login.jsp”);
}
} //No record in the result set, i.e., invalid username
else {
request.setAttribute(“Error”, “Invalid user name.”);
rd = request.getRequestDispatcher(“login.jsp”);
}
}
//As a controller, loginAction.jsp finally either forwards to “login.jsp” or “home.jsp”
rd.forward(request, response);
//…
本文所附示例均以關係型數據庫作為安全域,但本文所闡述的觀點對任何類型的安全域都是適用的。
Logout action
退出動作就包含了簡單的刪除用戶名以及對用戶的HttpSession對象調用invalidate()方法。清單2是從loginoutAction.jsp頁面中節選的一段代碼以此闡述退出動作:
Listing 2
//…
session.removeAttribute(“User”);
session.invalidate();
//…
阻止未經認證訪問受保護的JSP頁面
從form中獲取用戶提交的認證信息並經過驗證後,登陸動作簡單地往 HttpSession對象中寫入一個用戶名,退出動作則做相反的工作,它從用戶的HttpSession對象中刪除用戶名並調用invalidate()方法銷毀HttpSession。為了使登陸和退出動作真正發揮作用,所有受保護的JSP頁面都應該首先驗證HttpSession中是否包含了用戶名以確認當前用戶是否已經登陸。如果HttpSession中包含了用戶名,也就是說用戶已經登陸,Web應用則將剩餘的JSP頁發送給瀏覽器,否則,JSP頁將跳轉到登陸頁login.jsp。頁面home.jsp, secure1.jsp, secure2.jsp和logout.jsp均包含清單3中的代碼段:
Listing 3
//…
String userName = (String) session.getAttribute(“User”);
if (null == userName) {
request.setAttribute(“Error”, “Session has ended. Please login.”);
RequestDispatcher rd = request.getRequestDispatcher(“login.jsp”);
rd.forward(request, response);
}
//…
//Allow the rest of the dynamic content in this JSP to be served to the browser
//…
在這個代碼段中,程序從HttpSession中減縮username字符串。如果字符串為空,Web應用則自動中止執行當前頁面並跳轉到登陸頁,同時給出Session has ended. Please log in.的提示;如果不為空,Web應用則繼續執行,也就是把剩餘的頁面提供給用戶。
運行logoutSampleJSP1
運行logoutSampleJSP1將會出現如下幾種情形:
1) 如果用戶沒有登陸,Web應用將會正確中止受保護頁面home.jsp, secure1.jsp, secure2.jsp和logout.jsp的執行,也就是說,假如用戶在瀏覽器地址欄中直接敲入受保護JSP頁的地址試圖訪問,Web應用將自動跳轉到登陸頁並提示Session has ended.Please log in.
2) 同樣的,當一個用戶已經退出,Web應用也會正確中止受保護頁面home.jsp, secure1.jsp, secure2.jsp和logout.jsp的執行
3) 用戶退出後,如果點擊瀏覽器上的後退按鈕,Web應用將不能正確保護受保護的頁面——在Session銷毀後(用戶退出)受保護的JSP頁重新在瀏覽器中顯示出來。然而,如果用戶點擊返回頁面上的任何鏈接,Web應用將會跳轉到登陸頁面並提示Session has ended.Please log in.
阻止瀏覽器緩存
上述問題的根源在於大部分瀏覽器都有一個後退按鈕。當點擊後退按鈕時,默認情況下瀏覽器不是從Web服務器上重新獲取頁面,而是從瀏覽器緩存中載入頁面。基於Java的Web應用並未限制這一功能,在基於PHP、ASP和.NET的Web應用中也同樣存在這一問題。
在用戶點擊後退按鈕後,瀏覽器到服務器再從服務器到瀏覽器這樣通常意思上的HTTP迴路並沒有建立,僅僅只是用戶,瀏覽器和緩存進行了交互。所以,即使包含了清單3上的代碼來保護JSP頁面,當點擊後退按鈕時,這些代碼是不會執行的。
緩存的好壞,真是仁者見仁智者見智。緩存的確提供了一些便利,但通常只在使用靜態的HTML頁面或基於圖形或影響的頁面你才能感受到。而另一方面,Web應用通常是基於數據的,數據通常是頻繁更改的。與從緩存中讀取並顯示過期的數據相比,提供最新的數據才是更重要的!
幸運的是,HTTP頭信息「Expires」和「Cache-Control」為應用程序服務器提供了一個控制瀏覽器和代理服務器上緩存的機制。HTTP頭信息Expires告訴代理服務器它的緩存頁面何時將過期。HTTP1.1規範中新定義的頭信息Cache-Control可以通知瀏覽器不緩存任何頁面。當點擊後退按鈕時,瀏覽器重新訪問服務器已獲取頁面。如下是使用Cache-Control的基本方法:
1) no-cache:強制緩存從服務器上獲取新的頁面
2) no-store: 在任何環境下緩存不保存任何頁面
HTTP1.0規範中的Pragma:no-cache等同於HTTP1.1規範中的Cache-Control:no-cache,同樣可以包含在頭信息中。
通過使用HTTP頭信息的cache控制,第二個示例應用logoutSampleJSP2解決了logoutSampleJSP1的問題。logoutSampleJSP2與logoutSampleJSP1不同表現在如下代碼段中,這一代碼段加入進所有受保護的頁面中:
//…
response.setHeader(“Cache-Control”,”no-cache”); //Forces caches to obtain a new copy of the page from the origin server
response.setHeader(“Cache-Control”,”no-store”); //Directs caches not to store the page under any circumstance
response.setDateHeader(“Expires”, 0); //Causes the proxy cache to see the page as “stale”
response.setHeader(“Pragma”,”no-cache”); //HTTP 1.0 backward compatibility
String userName = (String) session.getAttribute(“User”);
if (null == userName) {
request.setAttribute(“Error”, “Session has ended. Please login.”);
RequestDispatcher rd = request.getRequestDispatcher(“login.jsp”);
rd.forward(request, response);
}
//…
通過設置頭信息和檢查HttpSession中的用戶名確保了瀏覽器不緩存頁面,同時,如果用戶未登陸,受保護的JSP頁面將不會發送到瀏覽器,取而代之的將是登陸頁面login.jsp。
運行logoutSampleJSP2
運行logoutSampleJSP2後將回看到如下結果:
1) 當用戶退出後試圖點擊後退按鈕,瀏覽器並不會顯示受保護的頁面,它只會現實登陸頁login.jsp同時給出提示信息Session has ended. Please log in.
2) 然而,當按了後退按鈕返回的頁是處理用戶提交數據的頁面時,IE和Avant瀏覽器將彈出如下信息提示:
警告:頁面已過期……(你肯定見過)
選擇刷新後前一個JSP頁面將重新顯示在瀏覽器中。很顯然,這不是我們所想看到的因為它違背了logout動作的目的。發生這一現象時,很可能是一個惡意用戶在嘗試獲取其他用戶的數據。然而,這個問題僅僅出現在後退按鈕對應的是一個處理POST請求的頁面。
記錄最後登陸時間
上述問題之所以出現是因為瀏覽器將其緩存中的數據重新提交了。這本文的例子中,數據包含了用戶名和密碼。無論是否給出安全警告信息,瀏覽器此時起到了負面作用。
為了解決logoutSampleJSP2中出現的問題,logoutSampleJSP3的login.jsp在包含username和password的基礎上還包含了一個稱作lastLogon的隱藏表單域,此表單域動態的用一個long型值初始化。這個long型值是調用System.currentTimeMillis()獲取到的自1970年1月1日以來的毫秒數。當login.jsp中的form提交時,loginAction.jsp首先將隱藏域中的值與用戶數據庫中的值進行比較。只有當lastLogon表單域中的值大於數據庫中的值時Web應用才認為這是個有效的登陸。*博主點評:當然這裡可以不用數據庫(DB),建立一個application域的logon狀態關管理類也是不錯的辦法,而且這個類可以實現更多的功能,比如限制[同一賬號在不同地點同時登錄]等.
為了驗證登陸,數據庫中lastLogon字段必須以表單中的lastLogon值進行更新。上例中,當瀏覽器重複提交數據時,表單中的lastLogon值不比數據庫中的lastLogon值大,因此,loginAction轉到login.jsp頁面,並提示Session has ended.Please log in.清單5是loginAction中節選的代碼段:
清單5
//…
RequestDispatcher rd = request.getRequestDispatcher(“home.jsp”); //Forward to homepage by default
//…
if (rs.getString(“password”).equals(password)) {
//If valid password
long lastLogonDB = rs.getLong(“lastLogon”);
if (lastLogonForm > lastLogonDB) {
session.setAttribute(“User”, userName); //Saves username string in the session object
stmt.executeUpdate(“update USER set lastLogon= ” + lastLogonForm + ” where userName = ‘” + userName + “‘”);
}
else {
request.setAttribute(“Error”, “Session has ended. Please login.”);
rd = request.getRequestDispatcher(“login.jsp”); }
}
else { //Password does not match, i.e., invalid user password
request.setAttribute(“Error”, “Invalid password.”);
rd = request.getRequestDispatcher(“login.jsp”);
}
//…
rd.forward(request, response);
//…
為了實現上述方法,你必須記錄每個用戶的最後登陸時間。對於採用關係型數據庫安全域來說,這點可以可以通過在某個表中加上lastLogin字段輕鬆實現。LDAP以及其他的安全域需要稍微動下腦筋,但很顯然是可以實現的。
表示最後登陸時間的方法有很多。示例logoutSampleJSP3利用了自1970年1月1日以來的毫秒數。這個方法在許多人在不同瀏覽器中用一個用戶賬號登陸時也是可行的。
運行logoutSampleJSP3
運行示例logoutSampleJSP3將展示如何正確處理退出問題。一旦用戶退出,點擊瀏覽器上的後退按鈕在任何情況下都不會是受保護的頁面在瀏覽器上顯示出來。這個示例展示了如何正確處理退出問題而不需要額外的培訓。
為了使代碼更簡練有效,一些冗餘的代碼可以剔除掉。一種途徑就是把清單4中的代碼寫到一個單獨的JSP頁中,通過標籤<jsp:include>其他頁面也可以引用。
Struts框架下的退出實現
與直接使用JSP或JSP/servlets相比,另一個可選的方案是使用Struts。為一個基於Struts的Web應用添加一個處理退出問題的框架可以優雅地不費氣力的實現。這部分歸功於Struts是採用MVC設計模式的因此將模型和視圖清晰的分開。另外,Java是一個面向對象的語言,其支持繼承,可以比JSP中的腳本更為容易地實現代碼重用。在Struts中,清單4中的代碼可以從JSP頁面中移植到Action類的execute()方法中。
此外,我們還可以定義一個繼承Struts Action類的基本類,其execute()方法中包含了清單4中的代碼。通過使用類繼承機制,其他類可以繼承基本類中的通用邏輯來設置HTTP頭信息以及檢索HttpSession對象中的username字符串。這個基本類是一個抽象類並定義了一個抽象方法executeAction()。所有繼承自基類的子類都應實現exectuteAction()方法而不是覆蓋它。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/248874.html