13 Cookie和Session
http协议是一个无状态的协议,你每一个跳转到下一个页面的时候都是需要先登录才能使用,这样就很麻烦比如淘宝,没有cookie和session的话,用户在首页已经登录上去了,但是需要再次登录才能选择商品,需要再次登录才能放到购物车,需要再次登录才能然后购买,这样用户的体验是相当差的。
13.1 cookie
- 是什么
-
浏览器保存的内容,通常cookie是在浏览器中保存的,每一次访问服务器的时候,浏览器会自动的把cookie带到下一个页面的
-
如果想要使用cookie要保证我们的浏览器是开启cookie,所以说有一定的弊端,如果浏览器没有开启cookie,就不能再使用cookie了
-
cookie的大小是有限制的,通常是4096byte
-
cookie的保存是以键值对的形式存在的
- 常用方法
//1.cookie的构造方法,目的是实例化出来cookie对象
Cookie(String name,String value)
//2.设置cookie的方法
setValue(String value) //修改cookie的值
setMaxAge(int time) //设置cookie的有效时间
setPath(String path) //设置当前cookie的有效路径
//3.要将cookie发送到浏览器
response.addCookie(Cookie cookie);
- servlet实例一
package com.by.servlet;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class SetCookieServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request,HttpServletResponse response) throws Exception {/*** 1.创建cookie对象* 将键:java2311 值:sb ,存到cookie对象中*/Cookie cookie = new Cookie("msg", "sb");/*** 2.设置有效时间* 正数:表示当前cookie的有效时间* 负数:表示当前浏览器打开的时候存在,关闭的时候没了* 0:销毁当前的cookie*/cookie.setMaxAge(60*60*24);//设 置了有效期是个正数,//3.把cookie发送到浏览器response.addCookie(cookie);}
}
<servlet><servlet-name>setCookie</servlet-name><servlet-class>com.by.servlet.SetCookieServlet</servlet-class></servlet><servlet-mapping><servlet-name>setCookie</servlet-name><url-pattern>/setCookie</url-pattern></servlet-mapping>
- servlet实例二
package com.by.servlet;import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GetCookieServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) {//获取浏览器中cookie,返回值是一个数组Cookie[] cookies = request.getCookies();for (Cookie cookie : cookies) {System.out.println("==============");System.out.println(cookie.getName());//获取键System.out.println(cookie.getValue());//获取值}}
}
<servlet><servlet-name>getCookie</servlet-name><servlet-class>com.by.servlet.GetCookieServlet</servlet-class></servlet><servlet-mapping><servlet-name>getCookie</servlet-name><url-pattern>/getCookie</url-pattern></servlet-mapping>
- 实例三
@WebServlet("/destroyCookie")
public class DestroyCookieServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) {//退出登录Cookie[] cookies = request.getCookies();for (Cookie cookie : cookies) {if (cookie.getName().equals("msg")){cookie.setMaxAge(0);//销毁cookie//重新发送给浏览器response.addCookie(cookie);}}}
}
<servlet><servlet-name>destroyCookie</servlet-name><servlet-class>com.by.servlet.DestroyCookieServlet</servlet-class></servlet><servlet-mapping><servlet-name>destroyCookie</servlet-name><url-pattern>/destroyCookie</url-pattern></servlet-mapping>
13.2 session
- 为什么使用session?
- cookie保存数据类型是单一的,只能保存字符串类型的数据
- cookie的大小由限制
- 是什么?
-
保存服务器中,每一个session在我们当前的服务器会有一个标识号
-
使用session的时候一般要开启cookie如果浏览器没有开启cookie功能,我们可以通过html的url传参完后session的使用
-
没有大小的限制
-
信息的保存也是以键值对的形式存在的
- 实例一
package com.by.servlet;import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Date;public class SetSessionServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response){doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) {//1.获取session对象HttpSession session = request.getSession();System.out.println(session);//获取的是JSESSIONID 服务器唯一的标识System.out.println(session.getId());//给session设置一个时间,有效果的,里面放的是秒session.setMaxInactiveInterval(60*60*24);User user = new User();user.setUsername("张5丰");user.setBirthday(new Date());user.setSex("1");session.setAttribute("user",user);}
}
<servlet><servlet-name>setSession</servlet-name><servlet-class>com.by.servlet.SetSessionServlet</servlet-class></servlet><servlet-mapping><servlet-name>setSession</servlet-name><url-pattern>/setSession</url-pattern></servlet-mapping>
- 实例二
package com.by.servlet;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;public class GetSessionServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response){doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) {//1.获取Session对象//第一次创建session的时候默认为true//false的话,这个session使用的是已经创建好的session对象HttpSession session = request.getSession(false);//2.获取session,通过键取值Object user = session.getAttribute("user");System.out.println(user);}
}
<servlet><servlet-name>getSession</servlet-name><servlet-class>com.by.servlet.GetSessionServlet</servlet-class></servlet><servlet-mapping><servlet-name>getSession</servlet-name><url-pattern>/getSession</url-pattern></servlet-mapping>
- 实例三
package com.by.servlet;import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;public class DestroySessionServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) {//1.获取session对象HttpSession session = request.getSession(false);//销毁当前的sessionsession.invalidate();}
}
<servlet><servlet-name>destroySession</servlet-name><servlet-class>com.by.servlet.DestroySessionServlet</servlet-class></servlet><servlet-mapping><servlet-name>destroySession</servlet-name><url-pattern>/destroySession</url-pattern></servlet-mapping>
14 过滤器和监听器
14.1 过滤器
- 什么是过滤器
当浏览器向服务器发送请求的时候,过滤器可以将请求拦截下来,完成一些特殊的功能,比如:编码设置、权限校验、日志记录等。
- 过滤器执行流程
- Filter实例
package com.by.servlet;import javax.servlet.*;
import java.io.IOException;public class FilterDemo implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}//真正执行过滤业务的方法@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain filterChain) throws ServletException, IOException {//获取前端传送过来的数据request.setCharacterEncoding("utf-8");//设置请求的编码格式response.setContentType("text/html;charset=utf-8"); //设置相应的编码格式System.out.println("请求进来,经过过滤器...");//一个web路径,可以配置多个过滤器,这多个过滤器就被称为过滤器链filterChain.doFilter(request,response);System.out.println("相应返回,经过过滤器...");}@Overridepublic void destroy() {}
}
- 使用过滤器需要注意的事项:
1.过滤器必须实现Filter接口。
2.过滤器拦截的请求执行完毕之后,必须要放行,否则我们的请求就不会被执行。
filterChain.doFilter(request,response); //过滤器放行
3.我们可以使用@WebFilter来配置过滤器要拦截的资源,当然我们也可以通过xml的方式配置过滤器。
<filter><filter-name>filter</filter-name><filter-class>com.by.servlet.FilterDemo</filter-class></filter><filter-mapping><filter-name>filter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
- Filter的拦截路径的配置
1.拦截具体的资源路径:/index.jsp,只有访问index.jsp的时候才会被拦截
2.目录拦截:/user/*,访问/user下的所有资源,都会被拦截
3.后缀名拦截:*.jsp 访问后缀名为jsp的资源,都会被拦截
4.拦截所有:/* 访问所有的资源,都会被拦截
- 测试
1.创建servlet
package com.by.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 FilterTestServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//设置字符编码//request.setCharacterEncoding("utf-8");String username = request.getParameter("username");String password = request.getParameter("password");System.out.println("username: " + username+"===password"+password);//设置字符编码//response.setContentType("text/html;charset=utf-8");response.getWriter().write("username: " + username+"===password"+password);}
}
2.配置servlet
<servlet><servlet-name>filterTest</servlet-name><servlet-class>com.by.servlet.FilterTestServlet</servlet-class></servlet><servlet-mapping><servlet-name>filterTest</servlet-name><url-pattern>/filterTest</url-pattern></servlet-mapping>
3.创建filter_test.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<form action="filterTest" method="post"><input type="text" name="username"/><br><input type="text" name="password"/><br><input type="submit" value="提交">
</form>
</body>
</html>
14.2 监听器
- 是什么?
监听器可以监听就是在application,session,request三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件。
- Listener分类:Javaweb提供了8个监听器(接口)
- listen实例
package com.by.servlet;import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;public class MyListener implements ServletContextListener {//监听Servlet上下文对象创建的方法@Overridepublic void contextInitialized(ServletContextEvent servletContextEvent) {System.out.println("============tomcat启动(create servletContext)========");}//监听Servlet上下文对象销毁的方法@Overridepublic void contextDestroyed(ServletContextEvent servletContextEvent) {System.out.println("============tomcat关闭(destroyed servletContext)==========");}
}
<!--配置监听器--><listener><listener-class>com.by.listen.MyListener</listener-class></listener>
15 web三层架构
分层的目的是为了解耦。解耦就是为了降低代码的耦合度。方便项目后期的维护和升级。
-
web层
com.by.web/servlet/controller:servlet包
-
service 层
com.by.service:Service接口包
com.by.service.impl:Service接口实现类
-
dao 持久层
com.by.dao:Dao接口包
com.by.dao.impl: Dao接口实现类