tomcat为你做了什么?
request
1、创建socket 监听对应端口
2、维护了一个线程池
3、当有TCP连接时分配一个线程来处理
4、从TCP中读取数据
5、按照HTTP协议进行解析
6、将解析完成的数据包装在request对象中
7、按照web.xml映射传递到我们的servlet中
response
1、将response对象组装成HTTP协议数据格式
2、打散为字节流,再用过TCP发给客户端
servlet生命周期
Tomcat启动后 --> 加载web.xml获取servlet信息
–> 实例化servlet --> init初始化 --> service方法调用
–>get
–>post
–> destroy --> Tomcat停止
记一次405报错
其余报错在网上都有资源, 这个错误不常犯, 引起重视
- 在servlet中, get()请求方式不能设置req.setCharacterEncoding(), 需要在server.xml中配置, post()请求可以设置
- 如果用post()请求, 必须在所有重定向的servlet中, 重写doPost()方法, 否则会报405, 不支持post, 即使在doPost()中调用了doGet()也要重写doPost()方法
监听器要注意的点
监听器用于监听Web对象的创建和销毁, 以及自身参数的变化, 在事件发生后自动触发某些代码的执行
- 监听器需要实现接口, 重写监听器方法, 分为六类三种
可监听的对象分为三种:
ServletContext: 针对全局的Context及属性操作的监听
HttpSession: 针对某个⽤户会话及其属性操作的监听
ServletRequest: 针对某个请求对象以及属性操作的监听
常见的六种监听器:
- ⽤于对 对象的创建和销毁进⾏监听:
ServletContextListener: 监听ServletContext对象创建、销毁等操作
HttpSessionListener: 监听HTTPSession对象创建、销毁等操作
ServletRequestListener: 监听HttpServletRequest对象创建、销毁等- 用于对对象的属性设置和修改进行监听:
ServletContextAttributeListener: 监听全局属性操作
HttpSessionAttributeListener: 监听用户会话属性操作
ServletRequestAttributeListener: 监听请求属性操作
过滤器要注意的点
- 路径通配符"/"不会过滤首页, 需加上指定地址, "/*"等
- 如果需要配置过滤器的执行顺序, 一定要在web.xml中配置, 注解配置(@WebFilter())会按照类名的降序顺序执行
<!-- web.xml中的配置方式, 必需配置两个标签 -->
<filter>
<filter-name>TestFilter</filter-name>
<filter-class>com.ttc.TestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>TestFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- 继承HttpFilter, 重写doFilter()方法, 在不需要跳转的地方, 通过filterChain.doFilter(request,response)放开过滤器
Cookie和Session
cookie和sessionid默认都存在浏览器缓存中(浏览器启动后所占用的内存空间, 只要把浏览器关了, 这片内存就被释放了), 而session存放在服务器的内存当中, 同样是为了维持客户端与服务器的状态信息
cookie的概念:
- cookie是服务器保存在客户端的一个小的(4k)文本文件, 用于维持用户的登录状态
- cookie常用于保存登录状态, 用户资料等小文本
- cookie具有时效性, cookie内容会伴随请求发送给Tomcat
cookie的常用方法:
- Cookie(key, value); --cookie 的构造方法
- setMaxAge(); 设置Cookie的最大存活时间
- getValue(key); 获取对应key的cookie值
- setValue(key, newValue); 设置对应key的cookie的值
- response.addCookie(key); 往响应中添加对应key的cookie对象
注1:服务器获取cookie的时候, 要用数组获取: Cookie[] cookie = request.getCookies();
注2:cookie默认是临时的, 存放在浏览器缓存中, 必须设置有效期, 客户端才会保存在文件中
cookie 的两个问题
- 存放在客户端不安全, 虽然是加密的, 但是不保证会被破解
- 无论是否需要cookie每次都会自动发送, 造成额外网络开销
Session的概念
- session(用户会话)用于保存与"浏览器窗口"对应的数据, 即客户端与服务器在一段时间内的所有交互, 都称之为会话, 就是服务器端的一个对象, 会对应对方的客户端浏览器
- session的数据存储在服务器的内存当中, 具有时效性, 如果过一段时间不操作, session就会被删除
- session通过浏览器cookie的sessionid值提取用户数据:
① 在需要时服务器会创建一个session对象, 把id通过cookie返回给客户端
② 客户端会自动将id再发送给服务器
③ 服务器通过id来找到之前保存的session
注1:session保持会话, 先创建一个对象, 然后把session对象放在cookie中, 带给浏览器, 浏览器在请求的时候, 会把sessionid带给服务器, 服务器根据id去查session信息
注2:session不是有请求后立即创建, 而是在获取session如果没有后创建的
关于Session销毁的误区
- 不是关闭浏览器Session就没了, 而是在服务器中一直存在, 直到Session的存活时间到了(旧的session只能等超时)
- 清空缓存, sessionid就丢失了, 下一次请求如果调用了getSession时, 创建新的session
JSP的九大内置对象
九大内置对象
因为目前开发已经基本不用jsp, 如果要看懂老的应用, 升级维护也是需要了解的
1) request //请求对象 - HttpServletRequest
2) response //响应对象 - HttpServletResponse
3) session //用户会话 - HttpSession
4) application //应用全局对象 - ServletContext
5) out //输出对象 - PrintWriter
6) page //当前页面对象(当前jsp文件) - this
7) pageContext //页面上下文对象 - PageContext
8) config //应用配置对象 - ServletConfig
9) exception //应用异常对象 - Throwable
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html; charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
错误页面优化
web.xml中的配置
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/500.jsp</location>
</error-page>
<!-- 指定了错误类型优先跳转,如果错误类型没有找到, 会跳转到上面500.jsp中 -->
<error-page>
<exception-type>java.lang.ArithmeticException</exception-type>
<location>/arithmeticException.jsp</location>
</error-page>
jsp页面中的配置
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page isErrorPage="true" %>
<!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>500</title>
</head>
<body>
您请求的资源出问题了
<%
out.print("ExceptionMessage:"+exception.getMessage());
out.print("ExceptionClass():"+exception.getClass().getSimpleName());
%>
</body>
</html>
注:一定要加<%@ page isErrorPage="true" %>才能使用exception内置对象;
jsp四个作用域
按时间长短分:
- Application(跑在tomcat中的程序): 常驻
- Session(用户会话): 时效
- Request(请求): 瞬时
注: 所以不要将大量的数据放在session和servletContext里面
+一个page作用域, 只在当前jsp页面中有效