实例一、编码过滤
在进行WEB开发中,编码过滤是必不可少的操作,如果按照之前的做法,在每一个JSP或者是Servlet中都重复编写“request.setCharacterEncoding(“utf-8”)”的语句肯定是不可取的,会造成大量的代码重复,此时就可以通过过滤器完成这种编码过滤。即:在服务器运行servlet和JSP之前,过滤器就把请求编码统一设置为指定的编码。具体过程如下:
(说明:setCharacterEncodingFilter.java是一个过滤器,用来设置所有请求的编码。DoServlet.java和DoServlet1.java是两个servlet,用来输出其字符编码)
在eclipse中创建如下工程和文件:
在setCharacterEncodingFilter.java的Filter中,编写如下代码:
public static String encoding;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
// pass the request along the filter chain
request.setCharacterEncoding(encoding);
chain.doFilter(request, response);
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
encoding=fConfig.getInitParameter("encoding");
}
DoServlet.java和DoServlet1.java的代码是一样的,它们什么都不做,只输出请求的编码。代码如下:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
PrintWriter out=response.getWriter();
out.print(request.getCharacterEncoding());
}
配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>fiter1-1</display-name>
<filter>
<filter-name>SetCharacterEncodingFilter</filter-name>
<filter-class>swu.smxy.jsj.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SetCharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
运行结果:
运行.DoServlet.java和DoServlet1.java的结果如下图所示:
从结果我们可以看出,Filter已经把请求的编码都设置成了“utf-8”。
实例二、通过注解的方式实现编码过滤
在实例一中修改。具体步骤如下:
(1)删除web.xm中关于过滤器的配置信息。
(2)在setCharacterEncodingFilter.java中增加如下红色框里的代码。
@WebFilter(filterName="SetCharacterEncodingFilter",urlPatterns={"/*"},initParams={@WebInitParam(name="encoding",value="utf-8")})
public class SetCharacterEncodingFilter implements Filter {
/**
* Default constructor.
*/
public SetCharacterEncodingFilter() {
// TODO Auto-generated constructor stub
}
运行效果与实例一一模一样,只是不需要配置web.xml。这样是不是更简单呢?。所以,注解使用的主要目的就是避免编写配置文件,提高编程效率。
实例三、登录验证
创建工程和文件:
SessionFilter.java的Filter文件中使用了注解方式配置,其代码如下:
package swu.smxy.jsj;
import java.io.IOException;
@WebFilter(filterName="SessionFilter",urlPatterns="/admin/*")
public class SessionFilter implements Filter {
/**
* Default constructor.
*/
public SessionFilter() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
// pass the request along the filter chain
HttpServletResponse res=(HttpServletResponse) response;
HttpServletRequest req=(HttpServletRequest) request;//向下转型
HttpSession session =req.getSession();//取得session
if(session.getAttribute("username")==null){
res.sendRedirect("../login/login.jsp");
}else{
chain.doFilter(request, response);
}
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
LoginServlet的代码如下:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String name=request.getParameter("name");
String password=request.getParameter("password");
if(name.equals("张三")&password.equals("123456")){
HttpSession session=request.getSession();
session.setAttribute("username", name);
session.setAttribute("password", password);
response.sendRedirect("admin/admin.jsp");
}else{
}
}
setCharacterEncodingFilter.java代码如下:
public static String encoding;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
// pass the request along the filter chain
request.setCharacterEncoding(encoding);
chain.doFilter(request, response);
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
encoding=fConfig.getInitParameter("encoding");
}
login.jsp页面的代码如下:
<body>
<form action="${pageContext.request.contextPath }/LoginServlet" method="post">
姓名: <input type="text" name="name"><br>
密码: <input type="password" name="password"><br>
<input type="submit" value="提交">
<input type="reset" value="重置">
</form>
</body>
创建adduser.jsp、admin.jsp、search.jsp三个页,不用输入任何代码
运行效果:
a. 依次运行adduser.jsp、admin.jsp、search.jsp文件时的结果是什么?
都是如下界面
b. 先运行login.jsp,并输入正确的用户名和密码后,再依次运行adduser.jsp、admin.jsp、search.jsp文件时的结果又是什么?
提交信息后,出现空页面
实例四、禁止浏览器缓存页面
在eclipse中创建如下工程和文件:
在NoCacheFilter.java过滤器,编写如下代码:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
// pass the request along the filter chain
HttpServletRequest req=(HttpServletRequest) request;
//把ServletResponse强转成HttpServletResponse
HttpServletResponse res=(HttpServletResponse) response;
//禁止浏览器缓存所有动态页面
res.setDateHeader("Expires", -1);
res.setHeader("Cache-Control", "no-cache");
res.setHeader("Pragma", "no-cache");
chain.doFilter(request, response);
}
index.jsp页面不用写任何代码,这里只是测试。
运行结果:
运行index.jsp页面,下图是在谷歌浏览器的开发者模式下,查看Header得出的结果。
ie浏览器没法查看Header得出的结果
实例五、控制浏览器缓存页面中的静态资源
在eclipse中创建如下工程和文件:
ResourceCacheFilter.java的代码如下:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
// pass the request along the filter chain
HttpServletRequest req=(HttpServletRequest) request;
HttpServletResponse res=(HttpServletResponse) response;
res.setHeader("Cache-Control", "max-age=3600");
res.setDateHeader("expires", System.currentTimeMillis()+1000L*3600);
chain.doFilter(request, response);
}
web.xml的配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>filter1-3</display-name>
<filter>
<filter-name>ResourceCacheFilter</filter-name>
<filter-class>swu.smxy.filter.ResourceCacheFilter</filter-class>
</filter>
<!-- 配置要缓存的web资源的后缀 -->
<filter-mapping>
<filter-name>ResourceCacheFilter</filter-name>
<url-pattern>*.png</url-pattern>
<url-pattern>*.jpg</url-pattern>
<url-pattern>*.bmp</url-pattern>
<url-pattern>*.gif</url-pattern>
<url-pattern>*.css</url-pattern>
</filter-mapping>
</web-app>
jsp的页面引用一张图片
<body>
<img alt="" src="images/1.png">
</body>
运行结果:
第1次运行1.jsp页面,在谷歌浏览器中我们得到如下信息:
再次在谷歌浏览器中运行1.jsp,得到如下结果。红色框内信息表示该图片来自于缓存。由此可见,我们把资源设置缓存浏览成功。其他资源不再测试。同学们也可以自己测试一下。
实例六、监听项目的启动与停止。
在eclipse中创建如下工程和文件:
在MyServletContextListener,编写如下代码:
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub
System.out.print("contextDestroyed");
}
public void attributeReplaced(ServletContextAttributeEvent arg0) {
// TODO Auto-generated method stub
}
public void contextInitialized(ServletContextEvent arg0) {
// TODO Auto-generated method stub
String name=arg0.getServletContext().getInitParameter("name");
System.out.println("contextInitialized : name-"+name);
}
在web.xml中配置监听器。Web.xml的配置如下:
<display-name>listener1-1</display-name>
<listener>
<listener-class>swu.smxy.listener.MyServletContextListener</listener-class>
</listener>
<context-param>
<param-name>name</param-name>
<param-value>swu</param-value>
</context-param>
运行结果:
启动Tomcat服务器,控制台打印的信息如下:
![图13](https://img-blog.csdnimg.cn/20201202170822283.png)
停止Tomcat服务器,控制台打印如下信息。
# 实例七、监听session的创建和销毁
在eclipse中创建如下工程和文件:
![图14](https://img-blog.csdnimg.cn/20201202170634171.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pieXl3bA==,size_16,color_FFFFFF,t_70)
login.html的代码::
<body>
<form action="/listener1-1/loginServlet" method="post">
用户名:<input type="text" name="username"/><br/>
密码:<input type="text" name="password"/>
<input type="submit" value="提交">
</form>
</body>
index.jsp页面的代码:
</head>
<% UserInfoList user = UserInfoList.getInstance(); %>
<%
//如果未登录,转向登录页面
if (request.getSession(false).getAttribute("username") == null) {
response.sendRedirect(request.getContextPath()+"/login.html");
}
Vector vector = user.getList(); //获取存储在线用户名的vector对象
%>
<body>
<center>
<h2>欢迎您:【${sessionScope.username}】</h2>
<p>当前在线人数:<%=user.getCount() %>人</p>
在线人员:
<%
for(int i=0;i<user.getCount();i++){
out.println(vector.get(i));
}
%>
<p><a href="${pageContext.request.contextPath}/ExitServlet">退出</a><p>
</center>
</body>
LoginServlet.java的主要代码:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
String username=request.getParameter("username");
String password=request.getParameter("password");
HttpSession session=request.getSession(true);
session.setAttribute("username", username+":"+password);
response.sendRedirect(request.getContextPath()+"/index.jsp");
}
ExitServlet.java的主要代码:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
request.getSession(false).invalidate();
response.sendRedirect(request.getContextPath()+"/login.html");
}
UserInfoList.java的主要代码:
public class UserInfoList {
private static UserInfoList user = new UserInfoList();
private Vector vector = null;
private UserInfoList(){
this.vector = new Vector();
}
//使用单例模式
public static UserInfoList getInstance(){
return user;
}
/**
* 增加用户
*/
public boolean addUserInfo(String user){
if(user!=null){
this.vector.add(user);
return true;
}else{
return false;
}
}
/**
* 删除用户
*/
public void removeUserInfo(String user){
if(user!=null){
vector.removeElement(user);
}
}
/**
* 获取用户列表
*/
public Vector getList(){
return vector;
}
/**
* 统计在线人数
*/
public int getCount(){
return vector.size();
}
}
OnlineListener.java的代码如下:
@WebListener
public class OnlineListener implements ServletContextListener, ServletContextAttributeListener, HttpSessionActivationListener, HttpSessionBindingListener {
private UserInfoList user=UserInfoList.getInstance();
public void sessionCreated(HttpSessionEvent arg0){
System.out.println("session已经创建");
}
public void sessionDestroyed(HttpSessionEvent arg0){
System.out.println("session已经销毁");
}
public void attributeAdded(ServletContextAttributeEvent sadd) {
// TODO Auto-generated method stub
//将session中内容添加到vector集合
user.addUserInfo(String.valueOf(sadd.getValue()));
System.out.println(sadd.getSession().getId()+":"+sadd.getName()+":"+sadd.getValue());
}
/**
* @see ServletContextAttributeListener#attributeRemoved(ServletContextAttributeEvent)
*/
public void attributeRemoved(ServletContextAttributeEvent srem) {
// TODO Auto-generated method stub
//移除
user.removeUserInfo(String.valueOf(srem.getValue()));
System.out.println(srem.getSession().getId()+":"+srem.getName()+":"+srem.getValue());
}
public void attributeReplaced(ServletContextAttributeEvent supd) {
// TODO Auto-generated method stub
//更改;获取旧的属性
String oldValue=String.valueOf(supd.getValue());
//获取新的属性
String newValue=String.valueOf(supd.getSession().getAttribute(supd.getName()));
//移除旧属性
user.removeUserInfo(newValue);
//添加新属性
user.addUserInfo(newValue);
System.out.println("更改属性");
}
}
运行效果
先运行login.jsp页面,结果如下:
在打开浏览器,输入浏览地址,结果如下: