一、servlet运行机制
- 当浏览器发送给服务器一个servlet请求时,如果该servlet是第一次被调用,那么服务器将会创建一个servlet实例,并且运行它。而如果这个servlet已被实例化,那么服务器会启动一个新的线程运行它。也就是说servlet会一直驻留在内存中,而不是每次都重新创建新的实例。
二、servlet的生命周期
package cn.wxz1997.seckill;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @Description: ${todo}
* @Author: wxz1997
* @Date 18-6-27下午7:39
*/
public class MyServlet extends HttpServlet {
@Override
public void init() throws ServletException {
//只调用一次,在第一次调用servlet,即创建实例时调用
super.init();
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//当有一个servlet请求时,产生一个新线程,并调用service()方法,然后根据请求类型决定调用doGet()还是doPost()
super.service(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//处理get请求
super.doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//处理post请求
super.doPost(req, resp);
}
@Override
public void destroy() {
//删除servlet实例时调用
super.destroy();
}
}
三、cookie和session
- http是无状态的,可以使用cookie将信息保存在客户端。
- session:给每个客户端分配一个不重复的ID来区别不同的客户端,而将对应各个客户需要保存的数据保存在服务器的内存中。
保留sessionID的两种方法:
a. 保存在cookie中
b. url重写,即将本来用于标识用户的sessionID放在url后面。如:localhost:8080/test?jsessionid=0123456789
一般情况下,服务器会根据情况在在cookie和url重写之间进行切换,不需要我们干预。但在某些情况下需要我们自己实现url重写功能:
a. sendRedirect()进行跳转。 response.encodeRedirectURL(" ")
b. 超链接url。 response.encodeURL(" ")
区别:
a.存储的位置不同:cookie:存放在客户端;session:存放在服务端
b.存储的数据类型不同:两者都是key-value的结构,但针对value的类型是有差异的。
cookie:value只能是字符串类型;session:value是Object类型
c.存储的数据大小限制不同
cookie:按照不同的浏览器来说,有些细小的差异,但整体来说就是4K的大小
session:理论上受当前内存的限制,没有4K的限制
d.生命周期的控制
cookie的存活期分两种情况,一种是没有设置有效期,那么这种叫会话cookie,随着浏览器的关闭而消失;另外一种是有设置有效期,setMaxAge,单位是秒,并不会随着浏览器的关闭而消息,而是到了过期时间才消失。
session,默认情况下有效期是30分钟,是根据web.xml的默认配置而来,可以通过程序的手段设置失效,也可以通过web.xml配置自己设置的有效期时间
四、filter
WEB服务器每次在调用web资源的service方法之前,都会先调用一下filter的doFilter方法,因此我们可以:
在HttpServletRequest到达 Servlet 之前,拦截客户的HttpServletRequest 。根据需要检查HttpServletRequest,也可以修改HttpServletRequest 头和数据。
在HttpServletResponse到达客户端之前,拦截HttpServletResponse 。根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。
常用于实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等
package cn.wxz1997.seckill;
import javax.servlet.*;
import java.io.IOException;
/**
* @Description: ${todo}
* @Author: wxz1997
* @Date 18-6-27下午8:48
*/
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//初始化
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//实现过滤逻辑
}
@Override
public void destroy() {
//销毁
}
}
五、listener
主要作用是:做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是一些固定的对象等等。
package cn.wxz1997.seckill;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* @Description: ${todo}
* @Author: wxz1997
* @Date 18-6-27下午9:01
*/
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//当ServletContext创建时将会调用这个方法
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
//ServletContext销毁时将调用这个方法
}
}
统计当前在线人数
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* @description HttpSessionListener监听器实现统计网站在线人数的功能
*/
public class SessionListener implements HttpSessionListener{
public static int TOTAL_ONLINE_USERS = 0;
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
TOTAL_ONLINE_USERS = (Integer) servletContext.getAttribute("TOTAL_ONLINE_USERS");
// 如果用户退出,TOTAL_ONLINE_USERS自减1
if(TOTAL_ONLINE_USERS == 0){
servletContext.setAttribute("TOTAL_ONLINE_USERS", 1);
}
else{
TOTAL_ONLINE_USERS--;
servletContext.setAttribute("TOTAL_ONLINE_USERS", TOTAL_ONLINE_USERS);
}
}
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
TOTAL_ONLINE_USERS = (Integer) servletContext.getAttribute("TOTAL_ONLINE_USERS");
// 如果用户登录,TOTAL_ONLINE_USERS自增1
if(TOTAL_ONLINE_USERS == 0){
servletContext.setAttribute("TOTAL_ONLINE_USERS", 1);
}
else{
TOTAL_ONLINE_USERS++;
servletContext.setAttribute("TOTAL_ONLINE_USERS", TOTAL_ONLINE_USERS);
}
}
}
六、intercepter
过滤器可以简单的理解为“取你所想取”,过滤器关注的是web请求;拦截器可以简单的理解为“拒你所想拒”,拦截器关注的是方法调用。拦截器不依赖servlet容器,过滤器依赖于servlet容器。拦截器只对Action起作用,过滤器可以对所有请求起作用。