1、Servlet的基本概念
servlet是一个java小程序运行在web服务器。servlet接收并响应来自Web客户端的请求,通常通过HTTP(超文本传输协议)。
1.1 主要作用:
- 接收浏览器(客户端)的请求数据;(接收由表单用户输入的数据)
- 给客户端做响应;
- 呈现来自数据库或者其他源的记录;域中 jsp
- 动态创建网页 write
接收页面的数据------->接收数据------>-处理数据------>-给客户端做出相应的响应数据
1.2 Servlet 在web应用程序的位置
Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器请求和 HTTP 服务器上的数据库中间层。
1.3 Servlet 运行在Tomcat容器
Tomcat 的容器等级中,Context 容器是直接管理 Servlet 在容器中的包装类 Wrapper,所以 Context 容器直接影响 Servlet 的工作方式.
从上图可以看出 Tomcat 的容器分为四个等级,真正管理 Servlet 的容器是 Context 容器,一个 Context 对应一个 Web 工程。Context容器中会有多个servlet。
1.4 Servlet的生命周期
我们创建的servlet服务器(Tomcat)帮助我们完成解析工作,并且被包装成 StandardWrapper 添加在 Context 容器中,通过实例化以后就能为我们工作。如何实例化?
- 用户在浏览器中输入一个 URL。Web 服务器配置文件确定该 URL 是否指向一个由运行于服务器上的 servlet 容器所管理的 servlet。
- 如果还没有创建该 servlet 的一个实例(一个应用程序只有一个 servlet 实例),那么该容器就加载该类,并将之实例化。
- 该容器调用 servlet 上的 init()。
- 该容器调用servlet 上的service(),并在包装的 HttpServletRequest 和 HttpServletResponse 中进行传递。
- 该 servlet 通常访问请求中的元素,代表其他服务器端类来执行所请求的服务并访问诸如数据库之类的资源,然后使用该信息填充响应。
- 如果有必要,在 servlet 的有用生命结束时,该容器会调用 servlet 上的 destroy() 来清除它。
1.5 实例化
当客户端第一次进行请求的时候会实例化具体的servlet
如果 Servlet 的 load-on-startup 配置项大于 0,那么在 Context 容器启动的时候就会被实例化,在web.xml 中配置,也就是当 Tomcat 启动时这个 Servlet 就会被启动。
Servlet的加载顺序:当在web.xml中配置标签 <load-on-startup>2</load-on-startup>其中的数值大于0的整数时,当服务器启动的时候会根据配置的数值的大小顺序进行加载实例化servlet大于对象并执行初始化方法 。
1-->2-->3 -------加载顺序-----1-----2----3
(因为Tomcat内部配置了一个1,所以我们的配置一般从2开始)
1.6 Servlet的体系结构
与 Servlet 主动关联的是三个类,分别是 ServletConfig、ServletRequest 和 ServletResponse。这三个类都是通过容器传递给 Servlet 的。
创建servlet以后,服务器帮助我们将servlet加载到容器中,当客户端请求到服务器的时候,Tomcat接收请求的时候会解析用户的请求由哪个servlet来服务----->第一次实例化这个servlet。其中 ServletConfig 是在 Servlet 初始化时就传给 Servlet 了,而后两个是在请求达到时调用 Servlet 时传递过来的。
2、Servlet中的常用对象
2.1 ServletConfig
2.1.1 ServletConfig对象的获取
这个对象在 Servlet 初始化时就传给 Servlet ,所以从servlet对象中去取。
this.getServletConfig ();
2.1.2 ServletConfig对象的作用
获取当前servlet的初始化参数
什么是初始化参数
写servlet的时候给他初始化一些参数,这样我们可以在web.xml配置文件中对servlet进行配置。当servlet配置了初始化参数后,web容器在创建servlet实例对象时, 会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
2.1.3 常用方法
java.lang.String | getInitParameter(java.lang.String name) |
java.util.Enumeration | getInitParameterNames() |
ServletContext | getServletContext() |
java.lang.String | getServletName() |
2.2 ServletContext
servletContext对象是Servlet三大域对象之一,每个Web应用程序都拥有一个ServletContext对象,该对象是Web应用程序的全局对象或者上下文。Tomcat服务器在启动时,会自动创建一个ServletContext对象,域产生 。在关闭时,会自动销毁这个ServletContext对象。每个Web应用程序只拥有一个ServletContext对象,ServletContext对象可以在整个Web应用中共享数据资源。
2.2.1 获取ServletContext对象的方法
this.getServletConfig.getServletContext();
This.getServletContex() ;
2.2.2 ServletContext对象的作用
- 获取全局的初始化参数
context.getInitParameter(String name);context.getInitParameterNames() ;
- 实现整个web应用程序中多个servlet之间的数据共享(application域)
context.setAttributer(); context.getAttributer()
- 实现转发:一般使用request对象来转发
- 获取文件的真实路径和项目名路径(项目名)
getRealPath();方法来获取web项目中文件的真实路径
第一种 src目录下的文件 /WEB-INF/classes/db.properties(src目录下的东西都发布在/WEB-INF/classes/目录下面)
第二种WebContent目录下的文件/db.properties(默认在跟目录下)
第三种 WEB-INF目录下的文件/WEB-INF/db.properties
·········
getContextPath() 获得路径--->/20170723(也就是项目名)
常用方法
java.lang.Object | getAttribute(java.lang.String name) |
java.util.Enumeration | getAttributeNames() |
java.lang.String | getInitParameter(java.lang.String name) |
java.util.Enumeration | getInitParameterNames() |
java.lang.String | getRealPath(java.lang.String path) |
RequestDispatcher | getRequestDispatcher(java.lang.String path) |
java.net.URL | getResource(java.lang.String path) |
java.io.InputStream | getResourceAsStream(java.lang.String path) |
void | removeAttribute(java.lang.String name) |
void | setAttribute(java.lang.String name, java.lang.Object object) |
2.3 ServletRequest
当servlet被调用的时候会传递过来request对象,这个对象用来处理请求。
主要作用:
1 接收页面传递过来的请求参数
2 作为一个请求域对象存储数据
3 实现请求的转发
4 可以获取当前用户的session对象和cookie对象
5 获取当前请求的请求路径(URL)
6 可以获取项目路径
ServletRequest对象的常用方法
java.lang.Object | getAttribute(java.lang.String name) |
java.util.Enumeration | getAttributeNames() |
java.lang.String | getCharacterEncoding() |
java.lang.String | getParameter(java.lang.String name) |
java.util.Map | getParameterMap() |
java.util.Enumeration | getParameterNames() |
java.lang.String[] | getParameterValues(java.lang.String name) |
void | removeAttribute(java.lang.String name) |
void | setAttribute(java.lang.String name, java.lang.Object o) |
void | setCharacterEncoding(java.lang.String env) |
HttpServletRequest常用方法
String | getContextPath() |
Cookie[] | getCookies() |
java.lang.String | getHeader(java.lang.String name) |
java.util.Enumeration | getHeaderNames() |
java.util.Enumeration | getHeaders(java.lang.String name) |
java.lang.String | getMethod() |
java.lang.String | getRequestURI() |
java.lang.StringBuffer | getRequestURL() |
java.lang.String | getServletPath() |
HttpSession | getSession() |
HttpSession | getSession(boolean create) |
2.4 ServletResponse
和request对象一样在servlet创建的时候这个对象就会被放在service方法的参数中 ,
主要作用:
1对客户端(浏览器)进行响应 --->响应字符流,响应字节流
2返回客户端(浏览器)cookie对象
3实现重定向
ServletResponse常用方法
getCharacterEncoding() | |
ServletOutputStream | getOutputStream() |
java.io.PrintWriter | getWriter() |
void | setContentType(java.lang.String type) |
HttpServletResponse常用方法
void | sendRedirect(java.lang.String location) |
void | addCookie(Cookie cookie) |
2.5 Session 与 Cookie
会话技术----什么是会话
简单来说就是打开浏览器,在一个站点中点击各种超链接,直到关闭这个网站所有的页面,或者关闭浏览器,这个过程就叫做一次会话 。
会话技术保存用户会话时产生的数据信息
Session 与 Cookie 的作用都是为了保持访问用户与后端服务器的交互状态。它们有各自的优点也有各自的缺陷。然而具有讽刺意味的是它们优点和它们的使用场景又是矛盾的,例如使用 Cookie 来传递信息时,随着 Cookie 个数的增多和访问量的增加,它占用的网络带宽也很大,试想假如 Cookie 占用 200 个字节,如果一天的 PV 有几亿的时候,它要占用多少带宽。所以大访问量的时候希望用 Session,但是 Session 的致命弱点是不容易在多台服务器之间共享,所以这也限制了 Session 的使用。
2.5.1 Session和cookie本身存在的问题:
1 使用cookie传递信息的时候,大量cookie占用带宽;
2 Session在多台服务器之间的数据共享,广播数据容易形成网络风暴 ;
2.5.2 Session 如何基于 Cookie 来工作
第一种情况下,当浏览器不支持 Cookie 功能时,浏览器会将用户的 SessionCookieName 重写到用户请求的 URL 参数中,它的传递格式如 /path/Servlet;name=value;name2=value2? Name3=value3,其中“Servlet;”后面的 K-V 对就是要传递的 Path Parameters,服务器会从这个Path Parameters 中拿到用户配置的SessionCookieName。关于这个 SessionCookieName,如果你在 web.xml 中配置 session-config 配置项的话,其 cookie-config 下的 name 属性就是这个 SessionCookieName 值,如果你没有配置 session-config 配置项,默认的 SessionCookieName 就是大家熟悉的“JSESSIONID”。接着 Request 根据这个 SessionCookieName 到Parameters 拿到Session ID并设置到 request.setRequestedSessionId 中。
请注意如果客户端也支持 Cookie 的话,Tomcat 仍然会解析 Cookie 中的 Session ID,并会覆盖 URL 中的 Session ID。
有了 Session ID 服务器端就可以创建 HttpSession 对象了,第一次触发是通过 request. getSession() 方法,如果当前的 Session ID 还没有对应的 HttpSession 对象那么就创建一个新的,并将这个对象加到 org.apache.catalina. Manager 的 sessions 容器中保存,Manager 类将管理所有 Session 的生命周期,Session 过期将被回收,服务器关闭,Session 将被序列化到磁盘等。只要这个 HttpSession 对象存在,用户就可以根据 Session ID 来获取到这个对象,也就达到了状态的保持。
2.5.3 Cookie
2.5.3.1 Cookie的基概念
在servlet中创建一个Cookie,并且发送少量的信息到web浏览器,由浏览器保存这些信息,稍后再返回给服务器,cookie的值可以唯一的标识一个客户机.
cookie有一个名称、一个值和可选属性,如注释、路径和域限定符、最大年龄和版本号。一些浏览器有错误如何处理的可选属性,所以少量地使用它们来提高您的servlet的互操作性。
2.5.3.2 Cookie的创建
Cookie(java.lang.String name, java.lang.String value) 构造参数
Constructs a cookie with a specified nam and value.
2.5.3.3 Cookie的常用方法
int | getMaxAge() |
java.lang.String | getName() |
java.lang.String | getPath() |
java.lang.String | getValue() |
int | getVersion() |
void | setMaxAge(int expiry) |
void | setPath(java.lang.String uri) |
void | setValue(java.lang.String newValue) |
2.5.3.4 Cookie中的不支持中文
中文和英文字符不同,中文属于Unicod字符,在内存中站4个字符,而英文属于ASCII字符,内存中只占2个字符。Cookie中使用Unicode字符时需要对Unicode字符进行编码,否则会乱码。编码使用java.net.URLEncoder类的encode(String str,String encoding)方法,解码使用java.net.URLDecoder类的decode(String str,String encoding)方法。
当存储中文的时候要将cookie发送到浏览器时会报数据非法异常,所以要先编码,再解码
2.5.4 Session
识别唯一的一个用户,并且为这个用户存储一些会话时产生的信息,保存在服务器端 。
作为一次会话范围的作用域 ,存储数据 。
2.5.4.1 Session的基本概念
servlet容器使用此接口在HTTP客户机和HTTP服务器之间创建会话。会话在指定的时间段内持续,跨越用户的多个连接或页面请求。会话通常对应于一个可以多次访问站点的用户。服务器可以通过多种方式维护会话,比如使用cookie或重写URL
2.5.4.2 怎么获取session对象
HttpSession | getSession() HttpServletRequest对象的方法 |
2.5.4.3 常用方法
java.lang.Object | getAttribute(java.lang.String name) |
java.util.Enumeration | getAttributeNames() |
java.lang.String | getId() |
int | getMaxInactiveInterval() |
java.lang.Object | getValue(java.lang.String name) |
java.lang.String[] | getValueNames() |
void | putValue(java.lang.String name, java.lang.Object value) |
void | removeAttribute(java.lang.String name) |
void | removeValue(java.lang.String name) |
void | setAttribute(java.lang.String name, java.lang.Object value) |
void | setMaxInactiveInterval(int interval) |