首先建立一个登录界面login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录界面</title>
</head>
<body>
<form action="login" method="post">
<table border="2">
<tr>
<td>用户名:</td><td><input type="text" name="username"></td>
</tr>
<tr>
<td>密 码:</td><td><input type="password" name="password"></td>
</tr>
<tr>
<td><input type="submit" value="提交"></td><td><input type="reset" value="取消"></td>
</tr>
</table>
</form>
</body>
</html>
建立表单要提交的servlet对象loginServlet
在下面的servlet对象当中所实现的主要功能为:
1:对发送过来的请求进行编码操作
2:获取表单当中的用户名和密码并提交到session对象当中
3:进行session对象的ID的输出操作
package com.servlet;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class loginServlet extends HttpServlet{
//建立一个servlet类对象用于对表单对象所传递过来的数据信息进行处理操作
private String username;
private String password;
private String charset=null;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
super.doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding(charset);//获取xml当中的参数变量将之作为编码参数
username=req.getParameter("username");
password=req.getParameter("password");
//将从request对象当中所获取到的用户名和密码都保存到session会话对象当中去
HttpSession session = req.getSession();
session.setAttribute("username",username);
session.setAttribute("password",password);
System.out.println("Servlet:sessionID="+session.getId());
/*
* 直接接收到的表单对象当中的数据信息当中如果有汉字的化会产生乱码的现象,所以要先对所接收到的request对象当中的内容进行编码的
* 设置操作
*/
System.out.println("charset="+charset);
System.out.println("Servlet:username="+username);
System.out.println("Servlet:password="+password);
/*当用户名和密码相匹配时,进行登录操作 */
if(username.equals("清之羽") && password.equals("password"))
/*
* req.getRequestDispatcher("success.jsp").forward(req, resp);此处如果使用服务器端的转发的话在URL地址栏当中所显示的地址将不
* 是success.jsp页面资源的地址值,这样将不会触发successFilter过滤器对象,因为当前过滤器对象只会对来自客户端的请求数据信息进行
* 过滤操作,对来自服务器的请求对象不会进行过滤操作的,所以要采用客户端的跳转方式来对success界面进行访问以此来对successFilter进
* 行触发。
*/
resp.sendRedirect("success.jsp");
else
/*resp.sendError(404);直接给客户端返回一个404响应*/
resp.sendRedirect("fail.jsp");
}
@Override
public void init(ServletConfig config) throws ServletException {
this.charset=config.getInitParameter("charset");//获取初始化的配置信息
}
}
建立一个过滤器对象用于实现对登录成功界面当中的数据进行过滤操作
过滤器对象主要实现的功能:
1:对访问success.jsp页面的资源信息进行拦截操作
2:通过reqeust对象获取来获取session对象,并将session对象当中所存放的用户名和密码进行获取并输出
3:进行sessionID的输出操作
package com.filter;
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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.websocket.Session;
public class successFilter implements Filter{
//建立一个过滤器对象用于实现对success.jsp页面当中的请求信息进行过滤操作
@Override
public void destroy() {
System.out.println("进行过滤器对象的销毁操作");
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
System.out.println("执行过滤操作");
HttpServletRequest request=(HttpServletRequest)req;//进行request对象的强制转化
HttpSession session=request.getSession();//通过Httprequest对象来进行session对象的获取操作
System.out.println("Filter:session="+session.getId());
System.out.println("过滤器对象当中:username="+session.getAttribute("username"));
/* if(session.getAttribute("username")==null || !session.getAttribute("username").equals("青之羽"))
当当前的用户名为空或用户名错误时,将不再进行请求对象控制权的转交操作。服务器将直接将请求对象进行转发到登录界面当中让用户重新
* 进行登录操作
*
{
System.out.println("对不起您所输入的用户名错误或为空,请重新进行输入操作");
req.getRequestDispatcher("login.jsp").forward(req, res);
}*/
System.out.println("过滤权限转交之前");
chain.doFilter(req, res);//进行控制权限的转交操作
System.out.println("过滤权限转交之后");
}
@Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("进行过滤器对象的初始化操作:");
}
}
web.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_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>通过过滤器来实现登录验证-servlet</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>com.servlet.loginServlet</servlet-class>
<init-param>
<param-name>charset</param-name>
<param-value>UTF-8</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<filter>
<filter-name>successFilter</filter-name>
<filter-class>com.filter.successFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>successFilter</filter-name>
<url-pattern>/success.jsp</url-pattern>
</filter-mapping>
</web-app>
问题:将用户名在servlet对象当通过session来进行保存,然后在filter对象当中进行session对象的获取操作,对用户名进行读取操作。在程序运行之后将会发现在filter对象当中获取到的用户名为空。
运行结果如下:
如上图:发现在servlet对象当中可以进行用户名的输出操作,但是在filter对象当中用户名的输出为空。分析servlet对象当中的sessionID和Filter对象当中的sessionID发现两个对象当中的sessionID是不相同的表明在经过请求重定向之后在Filter对象当中所获取到的session是一个新的session对象,所以该对象当中不含有servlet session对象对象当中所存放的数据。所以进行用户名的输出之后就为空。即在请求重定向的过程当中发生了session的丢失。
接下来说说session与cookie之间的区别与联系
cookie和session对象都是用来跟踪整个回话的。Cookie是通过在客户端记录信息来确定用户的身份。Session是通过在服务器端的记录来确定用户的身份的。
一个用户的全部请求为一个会话,而另一个用户的全部请求则属于另一个会话,二者不能够混在一起。在web应用程序当中是通过Http来进行数据的传输的,而HTTP协议是一种无状态的传输协议,一旦数据交换完毕之后,客户端与服务器端之间的连接就会关闭,当再次进行数据交换时,需要再次进行新的连接对象的 建立,但是由于无状态协议的特性使得服务器对象无法从连接上跟踪会话,使得服务器将无法对同一个会话发送过来的请求数据进行识别操作。为了解决服务器无法是识别是否为同一用户所发送过来的请求这以问题,引入了cookie对象机制。
Cookie译为"甜饼",是由W3C所提出的。由于HTTP的无状态传输特性,使得服务器无法直接从网路上来识别客户的身份。怎么办?
给客户端没个用户发送一个通行证,每一个人在对服务器端进行访问之时都必须要携带上自己的通行证给服务器端看,这样服务器端就可以通过通行证来识别每一个用户对象,这就是Cookie对象的工作原理。
cookie实际上就是一小段的文本信息,客户端在将请求信息发送给服务器对象之后,如果服务器需要记录该用户的信息以便于对下次该客户所发送过来的信息进行自动识别的话,服务器端就会使用response对象来向客户端浏览器对象发送一个cookie。客户端在接收到cookie信息之后,就会将当前的session会话的sessionID值保存到cookies对象当中。在该用户再次对服务器端进行访问操作时,将会将所保存的cookie对象一同发送到服务器端。服务器通过对cookie对象当中的数据信息进行核对来在