1. HttpServletRequest与HttpServletResponse对象
-
HttpServletRequest在整个应用的生命周期中是单例的还是多例的?
多例的,每进来一个请求都需要创建一个HttpServletRequest对象
-
HttpServletResponse对象是多例的还是单例的
多例的,每次给客户端进行响应都需要创建新的响应对象
-
HttpServlet对象是多例的还是单例的?
单例的,全局只有一个我们自己创建的继承了HttpServlet的子类的对象
2. HttpServletContext对象
-
HttpServletContext对象代表的是整个应用的对象;
-
HttpServletContext是单例的,全局只有一个HttpServletContext对象
-
如何来获取HttpServletContext对象?
@Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取当前应用的上下文对象 ServletContext servletContext = this.getServletContext(); }
-
HttpServletContext携带数据
//获取当前应用的上下文对象 ServletContext servletContext = this.getServletContext(); //给当前的上下文对象设置数据 servletContext.setAttribute("mystr", "xiaohua");
-
HttpServletContext获取数据
Object mystr = servletContext.getAttribute("mystr");
-
HttpServletContext移除数据
//可以从上下文中移除数据 servletContext.removeAttribute("mystr");
3. Servlet的会话管理
http是无状态的协议,自身不能进行会话标识;所以javaee在servlet中引入了一个session的会话管理方案;
4. 浏览器的Cookie机制
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建Cookie
Cookie cookie = new Cookie("mystr", "xzycompute");
//配置有效期
cookie.setMaxAge(60 * 60 * 24 * 31);//1个月
resp.addCookie(cookie);
}
5. 上次访问时间(作业)
6. Session会话管理
- 客户端给服务器发送请求
- 服务器创建一个seesion对象,此session对象有一个session-id
- 服务器响应的时候会把Session-Id通过响应头给浏览器
- 浏览器在一个会话中再次访问服务器,就会携带Session-Id,此Session-Id是通过请求头
Cookie: Session-Id
携带的
HttpSession session = req.getSession();//判断服务器是否有此session对象,如果有返回此session对象 如果没有则创建一个新的session对象返回
那上面的判断,底层到底是如何判断服务器内存中有无此Session对象的?
底层是通过请求头: Cookie: xxxxx(sessionId);
7. Session与Cookie的关系?
Session是服务器的一种技术,这种技术的底层借助了Cookie;
Cookie是浏览器是浏览器的机制(功能)
8. Servlet的生命周期
生命周期: 从生到死
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("请求进来了");
}
/**
* init初始化方法只调用一次,在第一次请求此Servlet的时候调用
*
* @param config
* @throws ServletException
*/
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
System.out.println("init.......");
}
/**
* 当应用停止的时候回调的生命周期方法
*/
@Override
public void destroy() {
System.out.println("destory...............");
}
9. Servlet加载配置数据
/**
* init初始化方法只调用一次,在第一次请求此Servlet的时候调用
*
* @param config
* @throws ServletException
*/
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
String myName = config.getInitParameter("myname");
String myAge = config.getInitParameter("myage");
System.out.println(myName);
System.out.println(myAge);
}
10. Servlet注解开发
servlet3.x以后支持注解开发
@WebServlet(urlPatterns = "/servlet09",name = "servlet09")
public class MyServlet09 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servlet09....");
}
}
11. Servlet中的过滤器
过滤器是根据javaee提供的Filter接口来进行实现的;我们可以在应用程序中定义我们自己的Filter
,步骤如下:
先定义一个类实现Filter接口
import javax.servlet.Filter;
/**
* MyFilter01 是单例的,其"创建时机"比Servlet要早
*/
public class MyFilter01 implements Filter {
/**
* 当应用程序启动时回调的生命周期方法
*
* @param filterConfig
* @throws ServletException
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("filter01...init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("myfilter01...........");
String myname = servletRequest.getParameter("myname");
String newMyname = "hello" + myname;
servletRequest.setAttribute("myname", newMyname);
//过滤器进行放行
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
System.out.println("filter01...destroy");
}
}
在配置文件中配置filter
<filter>
<filter-name>filter02</filter-name>
<filter-class>com.xzy.filter.MyFilter02</filter-class>
</filter>
<filter-mapping>
<filter-name>filter02</filter-name>
<url-pattern>/user/*</url-pattern>
</filter-mapping>
然后我们访问 http://localhost:8080/user/servlet10
,就可以被我们定义的Filter过滤到了;
Filter也可以定义多个,多个Filter连成一条链,(FilterChain
),规则是按: 的配置顺序连起来的;
12. Servlet中的域对象有哪些?
域: 范围
ServletContext: 代表整个应用的对象
Session: 代表整个会话的对象
HttpServletRequest: 代表一次请求的对象
13. Servlet监听器
Servlet中的监听器其实就是监听域对象的改变;
- 创建 销毁
- 域对象中的数据的变化
Servlet中给我们提供了很多的监听器接口:
使用监听器的步骤:
1)创建一个类实现相应的监听器接口
2)把监听器注册到web.xml
package com.xzy;
import javax.servlet.*;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class MyListener implements ServletContextListener, ServletContextAttributeListener,HttpSessionListener , HttpSessionAttributeListener,ServletRequestListener,ServletRequestAttributeListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("servletContext的创建...");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("servletContext的销毁....");
}
@Override
public void attributeAdded(ServletContextAttributeEvent event) {
System.out.println("servletContext中添加了数据:"+event.getName()+"===>"+event.getValue());
}
@Override
public void attributeRemoved(ServletContextAttributeEvent event) {
System.out.println("servletContext中移除了数据:"+event.getName()+"===>"+event.getValue());
}
@Override
public void attributeReplaced(ServletContextAttributeEvent event) {
System.out.println("servletContext中替换了数据:"+event.getName()+"===>"+event.getValue());
}
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("session的创建...");
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("session的销毁...");
}
@Override
public void attributeAdded(HttpSessionBindingEvent event) {
System.out.println("session中添加数据:"+event.getName()+"===>"+event.getValue());
}
@Override
public void attributeRemoved(HttpSessionBindingEvent event) {
System.out.println("session中移除了数据:"+event.getName()+"===>"+event.getValue());
}
@Override
public void attributeReplaced(HttpSessionBindingEvent event) {
System.out.println("session中替换了数据:"+event.getName()+"===>"+event.getValue());
}
@Override
public void attributeAdded(ServletRequestAttributeEvent event) {
System.out.println("request中添加了数据:"+event.getName()+"===>"+event.getValue());
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent event) {
System.out.println("request中添移除数据:"+event.getName()+"===>"+event.getValue());
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent event) {
System.out.println("request中替换了数据:"+event.getName()+"===>"+event.getValue());
}
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("请求销毁了...");
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("请求创建了...");
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<listener>
<listener-class>com.xzy.MyListener</listener-class>
</listener>
</web-app>
14. Servlet中的请求转发与请求重定向
请求转发: 请求在多个Servlet中进行转发,对于客户端而言只是发送了一次请求;请求转发,浏览器的地址不会发生变化
;
请求重定向:
- 请求重定向时浏览器的功能;
- 浏览器遇到响应码为
302
并且响应头中包含Location
,那么就会跳转地址到Location对应的url中去; - 重定向之后,到达servlet中,是一次新的请求;
15. 请求转发 vs 请求重定向
- 请求转发是servlet内部做的事,和浏览器没有任何关系,对于浏览器而言只是发送了一次请求,地址栏根本不会发生任何变化;
- 请求重定向是浏览器的功能,我们服务端可以手动的触发这个功能,重定向之后是一次新的请求;