一诡右、實驗內(nèi)容
1、Filter的理解和應(yīng)用
實現(xiàn)一個禁止緩存的過濾器轻猖。
要求和提示:
(1)禁止瀏覽器緩存所有動態(tài)頁面帆吻;
(2)有3個http響應(yīng)頭字段可以禁止瀏覽器緩存當前頁面,它們在Servlet中的示例代碼如下咙边。
response.setDateHeader("Expires",-1);
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");
(3)并不是所有的瀏覽器都能完全支持上面的3個響應(yīng)頭猜煮,因此最好是同時使用上面的3個響應(yīng)頭次员。
代碼如下:
ExampleFilter.java
package com.qst.chapter02;
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;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebFilter("/ExampleFilter")
public class ExampleFilter implements Filter {
public ExampleFilter() {
// TODO Auto-generated constructor stub
}
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//HttpServletRequest req=(HttpServletRequest) request;
HttpServletResponse res=(HttpServletResponse) response;
res.setDateHeader("Expires",-1);
res.setHeader("Cache-Control","no-cache");
res.setHeader("Pragma","no-cache");
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>chapter02</display-name>
<filter>
<filter-name>ExampleFilter</filter-name>
<filter-class>com.qst.chapter02.ExampleFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ExampleFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
驗證方法:打開一個瀏覽器(不能在編譯器自帶的瀏覽器中打開),在網(wǎng)頁中右鍵點審查元素王带,network中找到頁面淑蔚,如下圖
效果:
有過濾器
無過濾器
2、Filter的理解和應(yīng)用
設(shè)計一個簡單的IP地址過濾器愕撰,根據(jù)用戶的IP地址進行網(wǎng)站的訪問控制刹衫。例如:禁止IP地址處在192.168.2網(wǎng)段的用戶對網(wǎng)站的訪問。
思路:
用字符串模擬一個IP地址搞挣,通過過濾器带迟,觀察是否能打開網(wǎng)頁,網(wǎng)頁代碼隨便一個皆可。
代碼:
ExampleFilter.java
package com.qst.chapter02;
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;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.ws.Response;
@WebFilter("/ExampleFilter")
public class ExampleFilter implements Filter {
private String ip;
private String[] ips;
public ExampleFilter() {
// TODO Auto-generated constructor stub
}
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req=(HttpServletRequest) request;
HttpServletResponse res=(HttpServletResponse) response;
//模擬IP地址
String localip="192.168.2.50";
//拆分字符,提取部分IP地址
String localipnum=localip.substring(0,localip.lastIndexOf("."));
if(localipnum.equals("192.168.2"))
{
response.getWriter().print("IP:"+localip);
response.getWriter().print("error!");
}
else
{
chain.doFilter(request, response);
}
}
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
效果:
模擬地址192.168.2.50
模擬地址192.168.1.50(不是禁止的網(wǎng)段即可正常顯示)
3囱桨、Listener的理解和應(yīng)用
通過監(jiān)聽器記錄在線用戶的姓名仓犬,在頁面進行用戶姓名的顯示,同時實現(xiàn)對某個用戶的強制下線功能舍肠。
思路:
用監(jiān)聽器監(jiān)聽每一次會話的發(fā)起和結(jié)束搀继,然后將信息保存下來并顯示,注意翠语,因為每一次的session會話都是要由不同的客戶端發(fā)起的叽躯,所以你在運行的時候是無法在同一個瀏覽器測試的,請在多個瀏覽器打開網(wǎng)頁地址同時測試啡专,或者將瀏覽器關(guān)閉再重新打開一個新的會話(但這樣的話你就無法關(guān)閉上一次會話創(chuàng)建的用戶)险毁,退出也是只能退出你此次session會話創(chuàng)建的用戶。強制下線功能需要在退出代碼中查找想要退出用戶的sessionID们童,然后將其移除map即可畔况,下面的代碼沒有該功能,可以在此代碼基礎(chǔ)上更改慧库。
代碼:
監(jiān)聽器OnlineLoginUserViewListener.java代碼
package com.qst.chapter02;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
/**
* Application Lifecycle Listener implementation class OnlineLoginUserViewListener
*
*/
@WebListener
public class OnlineLoginUserViewListener implements HttpSessionAttributeListener {
/**
* Default constructor.
*/
public OnlineLoginUserViewListener() {
// TODO Auto-generated constructor stub
}
/**
* @see HttpSessionAttributeListener#attributeAdded(HttpSessionBindingEvent)
*/
@SuppressWarnings("unchecked")
public void attributeAdded(HttpSessionBindingEvent arg0) {
HttpSession session = arg0.getSession();
//獲取表示用戶成功登陸后的會話域?qū)傩評sername
String username = (String) session.getAttribute("username");
if (username != null) {
//將登陸的用戶信息封裝到j(luò)avabean中
UserSessionInfo userSessionBean = new UserSessionInfo(username,session.getId(), new Date(session.getCreationTime()));
//map表
Map<String, UserSessionInfo> onlineRegister = (Map<String, UserSessionInfo>) session.getServletContext().getAttribute("onlineRegister");
if (onlineRegister == null) {
onlineRegister = new HashMap<String, UserSessionInfo>();
}
//將登錄信息保存到map中跷跪,key為sessionId
onlineRegister.put(session.getId(), userSessionBean);
//保存更新后的登陸用戶信息
session.getServletContext().setAttribute("onlineRegister",onlineRegister);
}
}
/**
* 刪除session時
*/
public void attributeRemoved(HttpSessionBindingEvent arg0) {
// TODO Auto-generated method stub
if ("username".equals(arg0.getName())) {
HttpSession session = arg0.getSession();
Map<String, UserSessionInfo> onlineRegister = (Map<String, UserSessionInfo>) session
.getServletContext().getAttribute("onlineRegister");
onlineRegister.remove(session.getId());
session.getServletContext().setAttribute("onlineRegister",
onlineRegister);
}
}
/**
* @see HttpSessionAttributeListener#attributeReplaced(HttpSessionBindingEvent)
*/
public void attributeReplaced(HttpSessionBindingEvent arg0) {
// TODO Auto-generated method stub
}
}
用戶信息javabean,UserSessionInfo.java
package com.qst.chapter02;
import java.io.IOException;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class UserSessionInfo {
private String username;
private String sessionID;
private Date creationDate;
public UserSessionInfo(){
}
public UserSessionInfo(String username, String sessionID, Date creationDate) {
super();
this.username = username;
this.sessionID = sessionID;
this.creationDate = creationDate;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSessionID() {
return sessionID;
}
public void setSessionID(String sessionID) {
this.sessionID = sessionID;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
}
實時在線用戶顯示頁面onlineLoginUserView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>view</title>
</head>
<body>
<c:forEach items="${applicationScope.onlineRegister}" var="mapRegister">
<p>
用戶名:${mapRegister.value.username},會話創(chuàng)建時間:
<fmt:formatDate value="${mapRegister.value.creationDate}"
pattern="yyyy-MM-dd HH:mm:ss" />
<a href="logoutPro.jsp">退出</a>
</p>
</c:forEach>
<a href="loginPro.jsp">注冊登錄</a>
</body>
</html>
登陸頁面longinPro.jsp
<%@page import="java.util.Random"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用戶登錄</title>
</head>
<body>
<%
session.setAttribute("username","用戶1"+new Random().nextInt());
//System.out.print("用戶"+new Random().nextInt());
response.sendRedirect("onlineLoginUserView.jsp");
%>
</body>
</html>
退出頁面logoutPro.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用戶退出</title>
</head>
<body>
<p>已經(jīng)退出本系統(tǒng)齐板!</p>
<%
//String username = request.getParameter("username");
//System.out.print(username);
session.removeAttribute("username");
response.sendRedirect("onlineLoginUserView.jsp");
%>
</body>
</html>
運行效果:
未有用戶注冊時
有用戶注冊時(需要打開多個瀏覽器測試吵瞻,或者重啟瀏覽器測試)
退出登陸時(一次會話只能退出當前會話的用戶,所以你只能退出一個用戶)
總結(jié)
下面是廢話甘磨,可不看橡羞。。济舆。卿泽。
過濾器和監(jiān)聽器是java web中非常重要的兩個功能,可以幫助我們處理很多邏輯上的問題滋觉,通過監(jiān)聽器監(jiān)聽網(wǎng)頁發(fā)出的請求签夭,就可以及時的對請求進行處理齐邦,通過過濾器過濾掉我們不需要的信息,可以大大提高網(wǎng)頁運行的效率第租,也方便程序員對頁面操作進行編程措拇。