一、實(shí)驗(yàn)內(nèi)容
1、request內(nèi)置對(duì)象的熟練使用
(1)創(chuàng)建a.jsp頁(yè)面,將一個(gè)字符串存入請(qǐng)求域?qū)傩詔emp中,轉(zhuǎn)發(fā)請(qǐng)求到b.jsp;
(2)在b.jsp中獲取并顯示temp的值;
(3)將步驟1中 的請(qǐng)求轉(zhuǎn)發(fā)到b.jsp改為重定向到b.jsp,觀察是否能獲取temp的值。
2、session和application內(nèi)置對(duì)象的熟練使用
(1)充分利用session和application的特點(diǎn),實(shí)現(xiàn)一個(gè)禁止用戶使用同一用戶名同時(shí)在不同客戶端登錄的功能程序。
3、exception內(nèi)置對(duì)象的熟練使用
(1)創(chuàng)建exceptionTest.jsp頁(yè)面,模擬一個(gè)空指針異常,指定異常處理頁(yè)面為error.jsp;
(2)使用exception內(nèi)置對(duì)象在異常處理頁(yè)面error.jsp中輸出異常信息。
二、實(shí)驗(yàn)代碼:
· 做實(shí)驗(yàn)之前要記憶一張圖,厘清JSP內(nèi)置對(duì)象的類別

實(shí)驗(yàn)1:
這里直接a.jsp和b.jsp一組討論第一種情況,c.jsp和d.jsp一組討論第二種情況:
?·情況一:
? ?a.jsp用form表單來(lái)傳入一個(gè)值 這樣跳轉(zhuǎn)起來(lái)更直觀,
? ?在b.jsp中用getParameter接收之后,再setAttribute和getAttribute完成實(shí)驗(yàn)要求的內(nèi)容
//a.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 1.請(qǐng)求轉(zhuǎn)發(fā)版本,利用表單輸入更直觀 -->
<form name="regForm" action="b.jsp" method="get">
<table>
<tr>
<td>輸入一串字符串:</td>
<td><input type="text" name="string" /></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="提交" /></td>
</tr>
</table>
</form>
</body>
</html>
//b.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>request內(nèi)置對(duì)象</h1>
字符串:
<%
request.setCharacterEncoding("UTF-8");
String str = request.getParameter("string");
request.setAttribute("temp", str);//set在服務(wù)器內(nèi)
%>
<!-- getParameter()獲取的是客戶端設(shè)置的數(shù)據(jù)。
getAttribute()獲取的是服務(wù)器設(shè)置的數(shù)據(jù)。
所以這里用getAttribute -->
<!-- 將一個(gè)字符串存入請(qǐng)求域?qū)傩詔emp中,轉(zhuǎn)發(fā)請(qǐng)求到b.jsp -->
<%= request.getAttribute("temp") %>
</body>
</html>


?·情況二:
? ?主要是利用sendRedirect方法完成重定向,同時(shí)也可以利用其方法拼接字符串完成傳參任務(wù),比如:sendRedirect("d.jsp?str="+str+"&pwd="+pwd);中str和pwd就是兩個(gè)參數(shù),然后用getParameter接收即可
//c.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
/*2.重定向版本*/
String str = "Topus";
%>
<br/>
<%
String pwd = "1234567";
response.sendRedirect("d.jsp?str="+str+"&pwd="+pwd);
%>
</body>
</html>
//d.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 2.改為重定向到b.jsp,觀察是否能獲取值。 -->
<!--
getParameter()獲取的是客戶端設(shè)置的數(shù)據(jù)。
getAttribute()獲取的是服務(wù)器設(shè)置的數(shù)據(jù)。
所以這里用getParameter
-->
<%= request.getParameter("str") %>
<%= request.getParameter("pwd") %>
</body>
</html>

實(shí)驗(yàn)2:
大致思路是:建立一個(gè)map表,把userid和sessionid一一對(duì)應(yīng)起來(lái),若有新用戶登錄時(shí),利用其sessionID查找map表,若有則說(shuō)明已經(jīng)登陸過(guò),若沒有查到則代表是第一次登陸即顯示登陸成功,若在map表中查找到則說(shuō)明已經(jīng)登陸過(guò)。
~注意:
1.JAVA的字符串比較有時(shí)候必須得用.equals ,而且if判斷語(yǔ)句邏輯必須規(guī)范,不然會(huì)error500(不知道為啥)
2.userid和userSessionMap都可以通過(guò)application存儲(chǔ)起來(lái),方便刷新網(wǎng)路之后使用
3.在JSP頁(yè)面中模擬按鈕調(diào)用函數(shù)可以利用form傳參數(shù)到自己的頁(yè)面,刷新后利用if判斷語(yǔ)句接收按鈕參數(shù)然后執(zhí)行if語(yǔ)句內(nèi)的代碼
??下面直接上代碼:
//login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form name="regForm" action="solution.jsp" method="get">
<table>
<tr>
<td> 輸入您的用戶ID:</td>
<td><input type="text" name="userid" /></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="提交" /></td>
</tr>
</table>
</form>
</body>
</html>
//solution.jsp
<%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
/*需要在JSP指令中加入import="java.util.*" */
//建立一個(gè)map表,把userid和sessionid一一對(duì)應(yīng)起來(lái)
Map<String,String> userSessionMap = (Map)application.getAttribute("userSessionMap");
String nameStr = request.getParameter("button");//用request得到
String userid = request.getParameter("userid");
if( "yes".equals(nameStr)){
//out.println(userid);
String useridr = (String)application.getAttribute("userid");
out.println(useridr);
//執(zhí)行你的代碼
Map<String,String> tempMap = (Map)application.getAttribute("userSessionMap");
tempMap.remove(useridr);//把userid和sessionid鍵值對(duì)清除出map
application.setAttribute("userSessionMap",tempMap);
//application.removeAttribute("userSessionMap");
//application.setAttribute("userSessionMap",userSessionMap2);
response.sendRedirect("login.jsp");
}else{
//若表單傳入數(shù)據(jù)為空的話
if(userid.isEmpty()){
out.println("數(shù)據(jù)為空");
}else{
//若為map為空的話
if(userSessionMap==null){
out.println("map為空");
userSessionMap = new HashMap<String,String>();
userSessionMap.put("userid",session.getId());//把userid和sessionid一一對(duì)應(yīng)起來(lái)
//session.setMaxInactiveInterval(10);//session的失效時(shí)間為十秒
application.setAttribute("userSessionMap" ,userSessionMap);
}else{
//利用userid取出sessionid
String sessionid = userSessionMap.get(userid);
//如果此時(shí)這個(gè)用戶還未登錄,即表中還沒有該用戶的sessionid
if(sessionid == null)
{
out.println(userid+"登陸成功");
application.setAttribute("userid",userid);
userSessionMap.put(userid, session.getId());
}else{
if(sessionid.equals(session.getId())){
out.println(userid+"已經(jīng)登陸過(guò),不能再登,請(qǐng)退出登錄后再登");
}
}
}
}
}
%>
<form action="solution.jsp">
<button name="button" value="yes">直接退出登錄</button>
</form>
<input type = "button" value = "返回登錄頁(yè)面" onclick = "window.location.href = 'login.jsp'">
</html>




實(shí)驗(yàn)3:
利用JSP指令已經(jīng)認(rèn)為制造的異常來(lái)模擬異常頁(yè)面跳轉(zhuǎn)
//error.jsp
<%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 輸出異常信息 -->
<h1>這里是異常頁(yè)面</h1>
<%= exception.getMessage() %>
</body>
</html>
//exceptionTest.jsp
<%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 指定異常之后跳轉(zhuǎn)的頁(yè)面 -->
<%@page errorPage="/error.jsp"%>
<%
int result=1/0;//人為模擬的異常
%>
</body>
</html>

三、MARK-:
1??既然parameter和attribute都是傳遞參數(shù),為什么不直接使用parameter呢?
服務(wù)器端不能通過(guò)setParameter(key, value)來(lái)添加參數(shù),因?yàn)闆]有這個(gè)函數(shù)
所以如果需要在服務(wù)器端進(jìn)行跳轉(zhuǎn),并需要想下個(gè)頁(yè)面發(fā)送新的參數(shù)時(shí),則沒法實(shí)現(xiàn)。但是Attribute可以,可以通過(guò)setAttribute(),將值放入到request對(duì)象,然后在其他頁(yè)面使用getAttribute獲取對(duì)應(yīng)的值,這樣就達(dá)到一次請(qǐng)求可以在多個(gè)頁(yè)面共享一些對(duì)象信息
②parameter返回值是字符串,意味著不能傳遞其他的對(duì)象,如Map,List,但是attribute則可以存放任意類型的Java對(duì)象
2??重定向與轉(zhuǎn)發(fā)的比較:
轉(zhuǎn)發(fā)是在服務(wù)器端發(fā)揮作用,通過(guò)forward方法將提交信息在多個(gè)頁(yè)面間進(jìn)行傳遞。
轉(zhuǎn)發(fā)是在服務(wù)器內(nèi)部控制權(quán)的轉(zhuǎn)移,客戶端瀏覽器的地址欄不會(huì)顯示出轉(zhuǎn)向后的地址。
重定向是在客戶端發(fā)揮作用,通過(guò)請(qǐng)求新的地址實(shí)現(xiàn)頁(yè)面轉(zhuǎn)向。
重定向是通過(guò)瀏覽器重新請(qǐng)求地址,在地址欄中可以顯示轉(zhuǎn)向后的地址。