Session会话

什么是Session会话

  • Cookie保存在客户端;Session保存在服务器

如何创建 Session 和获取(id 号,是否为新)

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Session</title>
	<base href="http://localhost:8080/cookie/">
<style type="text/css">

	ul li {
		list-style: none;
	}
	
</style>
</head>
<body>
	<iframe name="target" width="500" height="500" style="float: left;"></iframe>
	<div style="float: left;">
		<ul>
			<li><a href="sessionServlet?action=createOrGetSession" target="target">Session的创建和获取(id号、是否为新创建)</a></li>
			<li><a href="sessionServlet?action=setAttribute" target="target">Session域数据的存储</a></li>
			<li><a href="sessionServlet?action=getAttribute" target="target">Session域数据的获取</a></li>
			<li>Session的存活</li>
			<li>
				<ul>
					<li><a href="sessionServlet?action=defaultLife" target="target">Session的默认超时及配置</a></li>
					<li><a href="sessionServlet?action=life3" target="target">Session3秒超时销毁</a></li>
					<li><a href="sessionServlet?action=deleteNow" target="target">Session马上销毁</a></li>
				</ul>
			</li>
			<li><a href="" target="target">浏览器和Session绑定的原理</a></li>
		</ul>
	</div>
</body>
</html>
package com.atguigu.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class SessionServlet extends BaseServlet{
    protected void createOrGetSession(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 创建和获取session会话对象
        HttpSession session = req.getSession();

        // 判断当前session会话,是否是新创建出来的
        boolean isNew = session.isNew();

        // 获取session会话的唯一标识id
        String id = session.getId();

        resp.getWriter().write("得到的session的id是" + id + "<br>");
        resp.getWriter().write("这个session是否是新创建出来的" + isNew + "<br>");
    }
}

Session 域数据的存取

protected void setAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	req.getSession().setAttribute("key1", "value1"); 
	resp.getWriter().write("已经往 Session 中保存了数据");
}

protected void getAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
	Object attribute = req.getSession().getAttribute("key1"); 
	resp.getWriter().write("从 Session 中获取出 key1 的数据是:" + attribute); 
}

Session 生命周期控制


protected void life3(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
	// 先获取 Session 对象 
	HttpSession session = req.getSession(); 
	// 设置当前 Session3 秒后超时 
	session.setMaxInactiveInterval(3); 
	resp.getWriter().write("当前 Session 已经设置为 3 秒后超时"); 
}
protected void deleteNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
	// 先获取 Session 对象 
	HttpSession session = req.getSession(); 
	// 让 Session 会话马上超时 
	session.invalidate(); 
	resp.getWriter().write("Session 已经设置为超时(无效)"); 
}

浏览器和 Session 之间关联的技术内幕

  • 这也解决了一个问题,为什么明明session还没有超时,而关闭了浏览器以后,它就超时了,再也找不到了;因为它创建的cookie存活时间是session,浏览器一关就不在了,那之后就会创建一个新的session

Filter 过滤器

什么是过滤器

Filter 的初体验

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>a.jsp</title>
</head>
<body>
    <%
        Object username = session.getAttribute("username");

        if (username == null) {
            request.getRequestDispatcher("/login.jsp").forward(request, response);
            return;
        }
    %>
    我是a.jsp文件
</body>
</html>

  • 但这张做法显然是有个问题的,它有局限性,只能在jsp文件(可以写java代码)中应用,那如果是html文件呢?


package com.atguigu.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class AdminFilter implements Filter {

    /**
     * doFilter方法,专门用来拦截请求,就可以做权限检查了
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;

        HttpSession session = httpServletRequest.getSession();

        Object username = session.getAttribute("username");
        if (username == null) {
            servletRequest.getRequestDispatcher("/login.jsp").forward(servletRequest, servletResponse);
        } else {
            // 让程序继续往下访问用户的目标资源
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
//        Filter.super.init(filterConfig);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp/xml/ns/javaee"
         xmlns:xsi="http://www.w3/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp/xml/ns/javaee http://xmlns.jcp/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- Filter标签用于配置一个Filter过滤器 -->
    <filter>
        <filter-name>AdminFilter</filter-name>
        <filter-class>com.atguigu.filter.AdminFilter</filter-class>
    </filter>
    <!-- filter-mapping配置filter过滤器的拦截路径-->
    <filter-mapping>
        <!-- filter-name表示当前的拦截路径给哪个filter使用 -->
        <filter-name>AdminFilter</filter-name>
        <!-- url-pattern 配置拦截路径
            / 表示请求地址为: http://ip:port/工程路径  映射到  IDEA 的 web目录
            /admin/*  表示 请求地址为: http://ip:port/工程路径/admin/*
         -->
        <url-pattern>/admin/*</url-pattern>
    </filter-mapping>
</web-app>

完整的用户登录

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    这是登陆界面。login.jsp页面
    <form action="http://localhost:8080/filter/loginServlet" method="get">
        用户名:<input type="text" name="username"> <br>
        密码:<input type="password" name="password"> <br>
        <input type="submit" value="">
    </form>
</body>
</html>

package com.com.atguigu.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html; charset=UTF-8");    // 解决响应乱码

        String username = req.getParameter("username");
        String password = req.getParameter("password");

        if ("wzg168".equals(username) && "123456".equals(password)) {
            req.getSession().setAttribute("username", username);
            resp.getWriter().write("登陆成功!");
        } else {
            req.getRequestDispatcher("/login.jsp").forward(req, resp);
        }
    }
}

  • 还没有登录的时候访问admin下面的文件就会直接跳转到登陆界面
  • 如果输入错误的账号密码会重新返回到登陆界面
  • 如果登陆成功以后就会进入loginServlet,然后再访问admin下面的a.jsp,session中取出来的数据就有值了,也就是非空,就会执行filterChain.doFilter(servletRequest, servletResponse);,让程序继续往下走,刚才我们访问的是a.jsp,因此,下一步就进入了a.jsp;如果没有这句代码,就算登陆成功以后,也无法访问用户的目标资源,进入admin/a.jsp这个页面显示的是一片空白


Filter 的生命周期

package com.atguigu.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class AdminFilter implements Filter {
    public AdminFilter() {
        System.out.println("1.Filter的构造器方法-AdminFilter()");
    }

    /**
     * doFilter方法,专门用来拦截请求,就可以做权限检查了
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("3.Filter的doFilter()过滤方法");
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;

        HttpSession session = httpServletRequest.getSession();

        Object username = session.getAttribute("username");
        if (username == null) {
            servletRequest.getRequestDispatcher("/login.jsp").forward(servletRequest, servletResponse);
        } else {
            // 让程序继续往下访问用户的目标资源
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
//        Filter.super.init(filterConfig);
        System.out.println("2.Filter的初始化init()方法");
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
        System.out.println("4.Filter的destroy()销毁方法");
    }
}

FilterConfig 类

@Override 
	public void init(FilterConfig filterConfig) throws ServletException { 
		  System.out.println("2.Filter 的 init(FilterConfig filterConfig)初始化");
		  
		  // 1、获取 Filter 的名称 filter-name 的内容
		  System.out.println("filter-name 的值是:" + filterConfig.getFilterName()); 
		  
		  // 2、获取在 web.xml 中配置的 init-param 初始化参数 
		  System.out.println("初始化参数 username 的值是:" + filterConfig.getInitParameter("username")); 
		  System.out.println("初始化参数 url 的值是:" + filterConfig.getInitParameter("url")); 
		  
		  // 3、获取 ServletContext 对象 
		  System.out.println(filterConfig.getServletContext()); 
	  }
<!--filter 标签用于配置一个 Filter 过滤器--> 
<filter> 
	<!--给 filter 起一个别名--> 
	<filter-name>AdminFilter</filter-name> 
	<!--配置 filter 的全类名-->
	<filter-class>com.atguigu.filter.AdminFilter</filter-class> 
	
	<init-param> 
		<param-name>username</param-name> 
		<param-value>root</param-value> 
	</init-param> 
	
	<init-param> 
		<param-name>url</param-name> 
		<param-value>jdbc:mysql://localhost3306/test</param-value> 
	</init-param> 
</filter>

FilterChain 过滤器链




Filter 的拦截路径

  • 后缀名匹配不能以斜杠打头

JSON

什么是 JSON

JSON 在 JavaScript 中的使用

json 的定义

var jsonObj = { 
	"key1":12, 
	"key2":"abc", 
	"key3":true, 
	"key4":[11,"arr",false], 
	"key5":{ 
		"key5_1" : 551, 
		"key5_2" : "key5_2_value" 
	},
	"key6":[{ 
		"key6_1_1":6611, 
		"key6_1_2":"key6_1_2_value"
	},{
		"key6_2_1":6621, 
		"key6_2_2":"key6_2_2_value" 
	}] 
};

json 的访问

alert(typeof(jsonObj));// object json 就是一个对象 
alert(jsonObj.key1); //12 
alert(jsonObj.key2); // abc 
alert(jsonObj.key3); // true 
alert(jsonObj.key4);// 得到数组[11,"arr",false] 
// json 中 数组值的遍历 
for(var i = 0; i < jsonObj.key4.length; i++) { 
	alert(jsonObj.key4[i]); 
}
alert(jsonObj.key5.key5_1);//551 
alert(jsonObj.key5.key5_2);//key5_2_value 
alert( jsonObj.key6 );// 得到 json 数组 
// 取出来每一个元素都是 json 对象 
var jsonItem = jsonObj.key6[0]; 
// alert( jsonItem.key6_1_1 ); //6611 
alert( jsonItem.key6_1_2 ); //key6_1_2_value

json 的两个常用方法

// 把 json 对象转换成为 json 字符串 
var jsonObjString = JSON.stringify(jsonObj); // 特别像 Java 中对象的 toString 
alert(jsonObjString) 
// 把 json 字符串。转换成为 json 对象 
var jsonObj2 = JSON.parse(jsonObjString); 
alert(jsonObj2.key1);// 12 
alert(jsonObj2.key2);// abc

JSON 在 java 中的使用

  • JSON在java中使用需要先导JSON的jar包,然后 add as library

javaBean 和 json 的互转

  • 导入这两个包后才可以 @Test
@Test 
public void test1(){ 
	Person person = new Person(1,"国哥好帅!"); 
	// 创建 Gson 对象实例 
	Gson gson = new Gson(); 
	// toJson 方法可以把 java 对象转换成为 json 字符串 
	String personJsonString = gson.toJson(person); System.out.println(personJsonString); 
	// fromJson 把 json 字符串转换回 Java 对象 
	// 第一个参数是 json 字符串 
	// 第二个参数是转换回去的 Java 对象类型 
	Person person1 = gson.fromJson(personJsonString, Person.class); 
	System.out.println(person1); 
}

  • 第一行是json字符串(花括号里面键值对之间用,分隔,键值对中键有“”包围
  • 第二行是一个Java对象类型

List 和 json 的互转

@Test 
public void test2() { 
	List<Person> personList = new ArrayList<>(); 
	personList.add(new Person(1, "国哥")); 
	personList.add(new Person(2, "康师傅")); 
	Gson gson = new Gson(); 
	// 把 List 转换为 json 字符串 
	String personListJsonString = gson.toJson(personList); 
	System.out.println(personListJsonString);
	List<Person> list = gson.fromJson(personListJsonString, new PersonListType().getType()); 
	System.out.println(list); 
	Person person = list.get(0); 
	System.out.println(person); 
}
  • 第一行,转化成了(由中括号[]包起来的是数组)一个数组,里面每一个元素都是json

map 和 json 的互转


上同,Class是给javabean用的,如果是转回集合,必须用的是Type
这个Type一定要先创建一个类去继承官方给的TypeToken

  • 但在这里,由json转回list和map时每次都要写一个类去继承TypeToken,会造成很多文件,因此,我们可以写成 匿名类 的形式,如下:
@Test 
public void test3(){ 
	Map<Integer,Person> personMap = new HashMap<>(); 
	personMap.put(1, new Person(1, "国哥好帅")); 
	personMap.put(2, new Person(2, "康师傅也好帅")); 
	Gson gson = new Gson(); 
	// 把 map 集合转换成为 json 字符串 
	String personMapJsonString = gson.toJson(personMap); 
	System.out.println(personMapJsonString); 
	// Map<Integer,Person> personMap2 = gson.fromJson(personMapJsonString, new PersonMapType().getType()); 
	Map<Integer,Person> personMap2 = gson.fromJson(personMapJsonString, new TypeToken<HashMap<Integer,Person>>(){}.getType()); 
	System.out.println(personMap2); 
	Person p = personMap2.get(1); 
	System.out.println(p); 
}

更多推荐

尚硅谷最新版JavaWeb全套教程,java web零基础入门完整版(五)