JavaWeb 基础之 Servlet

192 阅读11分钟

基本概念

  • Servlet(Server applet)是 Java Servlet 的简称,称为小服务程序或服务连接器,是 Java 语言编写的服务器端程序,也就是说,Servlet 是运行在服务器上的 Java 类
  • Servlet 用来完成 B/S 架构下客户端请求的响应处理,也就是交互式地浏览和生成数据,生成动态 Web 内容

编写步骤

  • 建立一个 Java Web Application 项目并配置 Tomcat 服务器
  • 自定义类实现 Servlet 接口或继承 HttpServlet类(推荐),并重写 service 方法
  • 将自定义类的信息配置到 web.xml 文件并启动项目
<!--web.xml-->
<!--进行 Servlet 配置-->
<servlet>
    <!--对 Servlet 起别名-->
    <servlet-name>hello</servlet-name>
    <!--指定对应的 Servlet 类-->
    <servlet-class>com.yamin.servlet.HelloServlet</servlet-class>
</servlet>
<!--进行 Servlet 的映射-->
<servlet-mapping>
    <!--选择Servlet进行映射,必须要与servlet的别名相同-->
    <servlet-name>hello</servlet-name>
    <!--配置访问地址-->
    <url-pattern>/hello</url-pattern>
</servlet-mapping>

Servlet

Servlet 接口

javax.servlet.Servlet接口用于定义所有 Servlet 必须实现的方法

方法功能
void init(ServletConfig config)有servlet容器调用,以向servlet指示servlet正在被放入服务中
void service(ServletRequest req,ServletResponse res)有servlet容器调用,以允许servlet响应请求
ServletConfig getServletConfig()返回ServletConfig对象,该对象包含此servlet的初始化和启动参数
String getServletInfo()返回有关Servlet的信息,如作者、版权和版本
void destory()有servlet容器调用,以向servlet指示该servlet正在退出服务

GenericServlet 类

javax.servlet.GenericServlet 类主要用于定义一个通用的,与协议无关的 servlet,该类实现了 Servlet 接口,若编写通用 Servlet ,只需要重写 service 抽象方法即可

方法功能
abstract void service(ServletRequest req,ServletResponse res)有servlet容器调用,以允许servlet响应请求

HttpServlet 类

javax.servlet.HttpServlet 类是一个抽象类并继承了 GenericServlet 类,用于创建使用与网站的 HTTP Servlet,该类的子类必须至少重写一个方法

方法功能
void doGet(HttpServletRequest req,HttpServletResponse res)处理客户端GET请求
void doPost(HttpServletRequest req,HttpServletResponse res)处理客户端POST请求
void init()进行初始化操作
void service(HttpServletRequest req,HttpServletResponse res)根据请求决定调用doGet还是doPost方法
void destory()删除实例时释放资源

ServletRequest接口

javax.servlet.ServletRequest 接口主要用于向 servlet 提供客户端请求信息,可以从中获取到任何请求信息,Servlet 容器创建一个ServletRequest 对象,并将其作为参数传递给 Servlet 的 service 方法

方法功能
String getParameter(String name)以字符串形式返回请求参数的值,如果该参数不存在,则返回空值
String[] getParameterValues(String name)返回一个字符串对象数组,其中包含给定请求参数锁具有的所有值,如果该参数不存在,则返回空值
Enumeration getParameterNames()返回包含此请求中包含的参数名称的字符串对象的枚举,如果请求没有参数,则方法放回空枚举
Map<String,String[]> getParameterMap()返回请求参数的键值对,一个键可以对应多个值
String getRemoteAddr()返回发送请求客户端或最后一个代理的IP地址
int getRemotePort()返回发送请求客户端或最后一个代理的端口号

HttpServletRequest 接口

此接口是ServletRequest的子接口,主要用于提供HTTP请求信息的功能,不同于表单数据,在发送HTTP请求时,HTTP请求头直接由浏览器设置。

方法功能
String getRequestURI()返回此请求的资源路径信息
StringBuffer getRequestURL()返回此请求的完整路径信息
String getMethod()返回发出此请求的HTTP方法的类型,如:GET POST
String getQueryString()返回路径后面请求中附带的参数
String getServletPath()返回此请求中调用servlet的路径部分

ServletResponse 接口

用于定义一个对象来帮助Servlet 向客户端发送响应

方法功能
PrintWriter getWriter()返回可想客户端发送字符文本的PrintWriter对象
String getCharacterEncoding()获取响应内容的编码方式
void setContentType(String type)如果尚未提交响应,则设置发送到客户端响应的内容类型,
内容类型可以包括字符编码规范,例如:text/html;charset=utf-8

HttpServletResponse 接口

接口继承 ServletResponse 接口,以便在发送响应式提供特定于HTTP的功能

方法功能
void sendRedirect(String location)使用指定的重定向位置URL向客户端发送临时重定向响应

ServletConfig 接口

用于描述 Servlet 本身的相关配置信息,在初始化期间用于将信息传递给 Servlet 配置对象

方法功能
String getServletName()返回 Servlet 的别名
String getInitParameter(String name)返回包含初始化参数值的字符串,如果该参数不存在,返回null
Enumeration getInitParameterNames()将servlet的初始化参数名称作为字符串对象的枚举返回,
如果servlet没有初始化参数,则返回空枚举
ServletContext getServletContext()返回对调用方正在其中执行的ServletContext的引用

ServletContext 接口

  • 主要用于定义一组方法,Servlet 使用这些方法与他的 Servlet 容器通信
  • 服务器在启动的时候会为每个项目唯一的一个 ServletContext 对象,用于实现对个 Servlet 之间的信息共享与通信
  • 在 Servlet 中可以通过使用 this.getServletContext()获取 ServletContext 对象。
  • 配置方式
<!--在 web.xml 中配置 servletContext 的初始化参数-->
<context-param>
    <param-name>key1</param-name>
    <param-value>value1</param-value>
</context-param>
<context-param>
    <param-name>key2</param-name>
    <param-value>value2</param-value>
</context-param>
方法功能
String getInitParameter(String name)返回包含初始化参数值的字符串,如果该参数不存在,返回null
Enumeration getInitParameterNames()将servlet的初始化参数名称作为字符串对象的枚举返回,如果servlet没有初始化参数,则返回空枚举
String getRealPath(String path)返回包含给定虚拟路径的实际路径的字符串
String getContextPath()返回与此上下文关联的主路径
InputStream getResourceAsStream(String path)将位于指定路径的资源作为InputStream对象返回
void setAttrbute(String name,Object value)将指定的属性名和属性值绑定到当前对象(能够跨Servlet通信)
Object getAttrbute(String name)根据执行的属性名获取属性值(能够跨Servlet通信)
void removeAttrbute(String name)删除指定的属性名信息(能够跨Servlet通信)

Servlet的生命周期

实例化(容器创建 Servlet 实例,即调用了 Servlet 的构造方法)
	↓
初始化(该 Servlet 调用 init() 方法)
	↓
服务(有请求进入到 Servlet,该 Servlet 调用了 service() 方法)
	↓
销毁(该 Servlet 调用了 destory() 方法)
	↓
不可用(销毁该 Servlet,并标记为垃圾回收)
  • 构造方法只会调用一次,第一次请求 Servlet 是会调用构造方法来创建实例
  • init 方法只会调用一次,当实例创建完成后立即调用 init 方法进行初始化
  • service 方法能被多次调用,每当有请求进入 Servlet,都会调用 Service 方法
  • destory 方法只会被调用一次,当实例所在的 web 应用被卸载前会调用该方法来释放当前占用的资源

线程安全问题

  • 当接收到请求时,就会启动一个线程来进行相应的请求。
  • 默认情况下,服务器只会为每个 Servlet 创建一个实例,当多个请求访问同一个 Servlet 时,就会有多个线程访问同一个 Servlet 对象,此时就会可能发生线程安全问题

状态管理

  • Web 程序基于 HTTP 协议通信,而 HTTP 协议是"无状态"的协议,一旦服务器响应完客户端的请求之后,就断开连接,而同一个客户端的下一次请求优惠重新建立网络连接
  • 服务器程序有时候是需要判断是否为同一个客户发出的请求,比如客户的多次选购商品,所以有必要追踪同一个客户发出的一系列请求
  • 把浏览器与服务器之间的多次监护作为一个整体,将多次交互锁涉及的数据保存下来,即状态管理
  • 多次交互的数据状态可以在客户端保存,也可以在服务器端保存,状态管理主要分为以下两类:
    • 客户端管理:将状态保存在客户端,基于 Cookie 技术实现
    • 服务端管理:将状态保存在服务端,基于 Session 技术实现

Cookie 技术

基本概念

  • Cookie在这里表示客户端以(key-value)形式将数据保存的一种技术
  • 浏览器在先服务器发送请求时,服务器将数据以 Set-Cookie 消息头的方式响应给浏览器,然后浏览器会将这些数据以文本文件的方式保存起来
  • 当浏览器再次访问服务器时,会将这些数据以 Cookie 消息头的方式发送给服务器

相关方法

  • 使用 javax.servlet.http.Cookie 类的构造方法实现 Cookie 的创建
方法功能
Cookie(String name,String value)根据参数指定数值构造对象
  • 使用 javax.servlet.http.HttpServletResponse 接口的成员方法实现 Cookie 的添加
方法功能
void addCookie(Cookie cookie)添加指定的Cookie到响应
  • 使用 javax.servlet.http.HttpServletRequest 接口的成员方法实现 Cookie 对象的获取
方法功能
Cookie[] getCookie()返回此请求中包含的所有Cookie对象
  • 使用 javax.servlet.http.Cookie 类的的成员方法实现 Cookie 对象中属性的获取与修改
方法功能
String getName()返回此Cookie对象的名字
String getValue()返回此Cookie对象的数值
void setValue(String newValue)设置此Cookie对象的数值

Cookie 生命周期

  • 默认情况下,浏览器会将Cookie信息保存在内存中,只要浏览器关闭,Cookie 信息就会消失
  • 如果希望关闭浏览器后 Cookie 信息任然有效,可以通过Cookie 类的成员方法设置
方法功能
int getMaxAge()获取Cookie 的最长使用期限(秒为单位)
void setMaxAge(int expiry)设置Cookie的最长使用期限(秒)

路径问题

  • 浏览器在访问服务器时,会比较Cookie的路径与请求路径是否匹配,只有匹配的Cookie才会发送给服务器
  • Cookie的默认路径等于添加这个Cookie信息是的组件路径,例如:/项目名/目录/cookie 请求添加了一个 Cookie 信息,则该 Cookie 的路径是 :/项目名/目录
  • 访问的请求地址必须符合 Cookie 的路径或者其子路径是,浏览器才会发送 Cookie 信息
  • 可以通过 Cookie 的成员方法设置路径信息
方法功能
void setPath(String url)设置Cookie 的路径信息

特点

Cookie技术不适合存储所有数据,只用于存储少量、非敏感信息,原因:

  • 将状态数据保存在浏览器端,不安全
  • 保存数据量有限制,大约4KB
  • 只能保存字符串信息
  • 可以通过浏览器设置禁止使用Cookie

Session 技术

基本概念

  • session 本意是 "会话" ,用来维护每一个客户端和服务器相关联的一种技术
  • 当浏览器访问服务器的时候,服务器会在内存空间中为每一个浏览器分配一个空间,用于创建一个 session 对象,该对象有一个 id 属性 且该值唯一,称之为 sessionId,并且服务器会将这个 sessionId 以 Cookie 方式发送给浏览器存储
  • 浏览器再次访问服务器时,会将 sessionId 发送到服务器,服务器依据 sessionId 查找对应的 session 对象

相关方法

  • 使用 javax.servlet.http.HttpServletRequest 接口的成员方法实现 session 的获取
方法功能
HttpSession getSession()返回此请求相关联的session,如果没有则创建一个
  • 使用 javax.servlet.http.HttpSession 接口的成员方法实现判断和获取
方法功能
boolean isNew()判断是否为新创建的 session
String getId()获取 session 的编号
  • 使用 javax.servlet.http.HttpSession 接口的成员方法实现属性的管理
方法功能
Object getAttribute(String name)获取此会话中指定名称的对象,如果没有则返回空值
void setAttribute(String name,Object value)设置此会话中指定名称的属性值
void removeAttribute(String name)删除此会话中指定名称的对象

生命周期

  • 为了节省服务器内存空间资源,服务器会将空闲时间过长的 session 对象自动清除,服务器默认的超时限制一般是 30 分钟
  • 可以使用 javax.servlet.http.HttpSession 接口的成员方法来设置失效的时间
方法功能
int getMaxInactiveInterval()获取失效的时间(秒)
void setMaxInactiveInterval(int interval)设置失效时间(秒)
  • 也可以通过 web.xml 设置失效时间(单位为分钟)
<session-config>
	<session-timeout>30</session-timeout>
</session-config>

特点

  • 数据比较安全
  • 保存的数据类型丰富
  • 能保存比较多的数据
  • 数据保存在服务器端会占用服务器的内存空间,如果存储信息过多、用户量过大会严重影响服务器的性能