Servlet基础知识点回顾(二)
本文最后更新于:2021年10月4日 下午
本篇文章用于简易回顾Servlet基础知识,并阅读自己之前项目里写过的一些Servlet代码。
Servlet基础知识点回顾(二)
知识点补充:
Servlet中的Cookie和Session
一个Web应用,通过Cookie和Session验证用户身份(简要概述):
客户端首次访问服务端,服务端登记客户端信息后,给客户端发送Cookies,其中包含Session相关信息,以及一些其它的信息。
客户端下次访问时,将Cookies发送给客户端,客户端通过解析Cookies来获取客户端信息并进行Session匹配。
Cookie
服务端:Servlet通过获取请求中的Cookies、编辑响应中要发送的Cookies,来CRUD Cookies。
客户端:保存管理服务端发送过来的Cookies。
Servlet中Cookie的常见操作
// Servlet的Cookie类中的常见字段
// 键值对
private String name;
private String value;
// 保存时间
private int maxAge = -1;
// Servlet对Request中Cookies的基本操作
public class CookieDemoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
// 从请求中获取cookies
Cookie[] cookies = req.getCookies();
// 判断cookies是否存在
if (cookies != null) {
// 显示req中cookies的信息
for (Cookie cookie : cookies) {
out.write(cookie.getName() + " " + cookie.getValue() + "\n");
}
// 查看上次登录时间
for (Cookie cookie : cookies) {
if(cookie.getName().equals("latestLoginTime")) {
long latestLoginTime = Long.parseLong(cookie.getValue());
Date date = new Date(latestLoginTime);
out.write(date.toString());
}
}
} else {
// 在该项目中,永远不会进入这个分支,因为最开始访问网站时已经进行了一次Cookie的传输了
out.write("第一次进入本服务器");
}
// 更新上次登录时间:新建一个cookie,里面存储访问时间,并放入响应对象
Cookie timeCookie = new Cookie("latestLoginTime", String.valueOf(System.currentTimeMillis()));
timeCookie.setMaxAge(24 * 60 * 60); // 设置这个cookie的存活时间
resp.addCookie(timeCookie);
}
}
Cookie的限制
一个Cookie只能保存一个信息
一些浏览器会给Cookies数量设置上限
Cookie大小一般会限制为4kb
服务端无法实时地编辑已发送至客户端的Cookies,只能设置Cookies的生命周期来进行删除
Session
服务端:保存客户端的会话信息,并通过Session来CRUD。
客户端:通过秘钥,与服务端进行会话的匹配。
每个Web应用会给每个浏览器创建一个Session对象,只要浏览器没有关闭,Session会一直存在 (多数情况下,服务端也能主动注销Session)
补充:
Session的使用场景
保存用户登录信息
保存购物车信息
在整个web应用中经常使用的数据,一般都会保留在session中
Servlet中Session的常见操作
public class SessionDemoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
HttpSession session = req.getSession();
session.setAttribute("sessionName", "SessionDemoServlet"); // get不做演示
String sessionId = session.getId();
if (session.isNew()) {
resp.getWriter().write("Session元素创建成功,ID: " + sessionId);
} else {
resp.getWriter().write("Session已存在,ID: " + sessionId);
}
}
}
XML配置Session
<!-- 设置Session的默认失效时间 -->
<session-config>
<!--
10个时间单位后服务端内的Session失效,时间单位为分钟。
在常见Web应用中,Session注销前会被保存至数据库。
下次获取SessionId时,重新激活这个Session,达到减少服务器负载的效果。
-->
<session-timeout>10</session-timeout>
<cookie-config>
<!-- 设置sessionId的Cookie在浏览器的保存时间,单位为秒 -->
<max-age>6000</max-age>
</cookie-config>
</session-config>
关于JSP和Servlet
JSP的本质就是Servlet-api的一种实现类。
在Tomcat中,JSP被转换称为一个Servlet实现类,并且进行了编译之后才转换为Web容器能处理的Servlet对象。
由此可见,Servlet是Java Web编程中实现动态网页的一种重要手段,是Java各种Web的框架的底层核心。
关于MVC架构和Servlet
一般来说,Servlet处于控制层(Controller),专注于接收用户请求、发送响应给用户、重定向或转发视图层中的视图等一系列控制操作,很少涉及业务逻辑代码,虽然在原则上说,Servlet可以完成Web应用的几乎所有功能,但为了代码解耦,让架构中的每个层级分工明确,Servlet一般仅作用于Controller层。
Servlet过滤器
用来过滤从Web容器(客户端到Web容器再到Servlet)中获得的数据(例如HttpServletRequest、HttpServletRequest),比如过滤无用信息、统一字符编码、过滤用户等级、登录验证等操作。
过滤器实例:统一字符编码
// 注解配置过滤器的方式
@WebFilter(filterName = "EncodingFilter", urlPatterns = "/filterTest/*")
public class EncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 在web服务器开始运行时,过滤器就会生成
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html;charset=UTF-8");
System.out.println("过滤器生效前");
// 放行数据,并继续执行可能存在的下一个过滤器
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("过滤器已生效");
}
@Override
public void destroy() {
//web服务器关闭后销毁过滤器
}
}
<!-- 使用xml配置的方式 -->
<filter>
<filter-name>CodeFilter</filter-name>
<filter-class>com.rootzwy.controller.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CodeFilter</filter-name>
<url-pattern>/filterTest/*</url-pattern>
</filter-mapping>
Servlet监听器
顾名思义,监听Servlet中的一系列操作,如Session、ServletContext等,与过滤器不同,监听器一开始就定义了一系列元素的监听器接口,继承自EventListener
接口
监听器实例:监听Session创建
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
// 使用注解配置监听器的方式
@WebListener()
public class FilterTestListener implements ServletContextListener, HttpSessionListener, HttpSessionAttributeListener {
public FilterTestListener() {
}
@Override
public void contextInitialized(ServletContextEvent sce) {
/* This method is called when the servlet context is initialized(when the Web application is deployed). */
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
/* This method is called when the servlet Context is undeployed or Application Server shuts down. */
}
@Override
public void sessionCreated(HttpSessionEvent se) {
/* Session is created. */
HttpSession session = se.getSession();
System.out.println(session.getAttribute(""));
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
/* Session is destroyed. */
}
@Override
public void attributeAdded(HttpSessionBindingEvent sbe) {
/* This method is called when an attribute is added to a session. */
}
@Override
public void attributeRemoved(HttpSessionBindingEvent sbe) {
/* This method is called when an attribute is removed from a session. */
}
@Override
public void attributeReplaced(HttpSessionBindingEvent sbe) {
/* This method is called when an attribute is replaced in a session. */
}
}
<!-- 在xml中配置监听器的方式 -->
<listener>
<listener-class>com.rootzwy.controller.FilterTestListener</listener-class>
</listener>