Servlet

1 Servlet简介

Servlet ,全称 Java Servlet 。是⽤ Java 编写的服务器端程序,其主要功能在于交互式地浏览和修改数据,⽣成动态Web内容。Servlet 是一个接口,我们一般使用的是它的实现类。Servlet 运行于支持 Java 的服务器中,理论上可以响应任何类型的请求,但绝⼤多数情况下Servlet 只⽤来扩展基于 HTTP 协议的 Web 服务器。

Servlet 工作模式:

  1. 客户端发送请求⾄服务器
  2. 服务器启动并调⽤ Servlet,Servlet 根据客户端请求⽣成响应内容并将其传给服务器
  3. 服务器将响应返回客户端

2 Servlet API

在这里插入图片描述

实现 Servlet 接口需要重写五个方法,继承 HTTPServlet 只需要重写两个方法,一般后者使用较多。

3 Servlet工作原理

  1. Servlet 接⼝定义了 Servlet 与 Servlet 容器之间的契约。这个契约是:Servlet 容器将 Servlet 类载⼊内存,并产⽣ Servlet 实例和调⽤它具体的⽅法。但是要注意的是,在⼀个应⽤程序中,每种 Servlet 类型只能有⼀个实例。
  2. ⽤户请求致使 Servlet 容器调⽤ Servlet 的 Service() ⽅法,并传⼊⼀个 ServletRequest 对象和⼀个 ServletResponse 对象。这两个对象都是由 Servlet 容器(例如 TomCat)封装好的,并不需要程序员去实现,可以直接使⽤这两个对象。
  3. ServletRequest 中封装了当前的 Http 请求,开发人员通过它获取请求数据。 ServletResponse 表示当前⽤户的 Http 响应,开发人员通过它就能把响应结果发回给⽤户。
  4. 对于每⼀个应⽤程序,Servlet 容器还会创建⼀个 ServletContext 对象。这个对象中封装了上下⽂ (应⽤程序)的环境详情。每个应⽤程序只有⼀个 ServletContext。每个 Servlet 对象也都有⼀个封装 Servlet 配置的 ServletConfig 对象。

4 Servlet生命周期

当客户端⾸次发送第⼀次请求后,由 web 服务器去解析请求,根据请求找到对应的 Servlet,判断该类的对象是否存在,不存在则创建Servlet 实例,然后调用 init() ⽅法进⾏初始化操作,初始化完成后调用 service() ⽅法,由 service() 判断客户端的请求⽅式,如果是get,则执⾏ doGet(),如果是 post 则执⾏ doPost(),处理⽅法完成后作出响应结果给客户端,单次请求处理完毕。

当⽤户发送第⼆次以后的请求时,会判断对象是否存在,但是不再执⾏ init(),⽽直接执⾏ service() ⽅法,接着调用 doGet() 或者doPost() ⽅法,最后返回响应结果给客户端。

当服务器关闭时调用 destroy() ⽅法进⾏销毁。

Servlet 执行过程:

  1. 实例化,创建 Servlet 实例
  2. 初始化,调用 init 方法
  3. 处理请求,调用 service 方法
  4. 服务终止,调用 destroy 方法

在这里插入图片描述

5 HttpServletRequest请求

HttpServletRequest 表示 Http 环境中的 Servlet 请求。它扩展于 javax.servlet.ServletRequest 接⼝。

5.1 请求常用方法

常用方法:

方法名作用
String getParameter(String name)根据表单组件的名称(name属性的值)来获取请求数据,无论提交时是什么类型,获取的数据都是 String 类型
String[] getParameterValues(String name)有多个表单组件的 name 属性为同一个值时,使用该方法一次获取多组数据
void setCharacterEncoding(String charset)指定 post 请求的编码方式,一般执行 setCharacterEncoding("utf-8")
RequestDispatcher getRequestDispatcher(String path)跳转页面,一般用于请求转发,固定格式执行 getRequestDispatcher(path).forward(request,response)
void setAttribute(String s,Object o)存值,s 和 o 一般以 key = value 的形式存储
Object getAttribute(String s)取值,根据 key 值取 value,得到是一个 Object 类型,需要向下转型
HttpSession getSession()获取会话 session,用于存值

5.2 请求方式

  1. 通过表单提交,提交方式 post 或 get 都行
  2. 通过 a 标签发送请求,只能是 get 提交,示例: <a href="/login?name=abc&pass=123">
  3. 浏览器地址栏直接输入,只能是 get 提交,格式:地址?key=value&key=value…(同上 a 标签)
  4. js 提交,如 location.href="请求地址?key=value&key=value" ,只能是 get 提交
  5. ajax 提交,提交方式 post 或 get 都行

5.3 处理请求乱码

  1. 在 Servlet 中执行 request.setCharacterEncoding("UTF-8"); 仅对 post 提交生效

  2. String s=new String(request.getParameter("key").getBytes("ISO-8859-1"),"GBK"); 仅对 get 提交生效

  3. 在 Tomcat ⽬录结构 \conf\server.xml 中设置字符集 URIEncoding=“UTF-8”

    <Connector port="8080" protocol="HTTP/1.1"
     connectionTimeout="20000"
     redirectPort="8443" URIEncoding="UTF-8" />
    

    注意:tomcat8.0 以后不需要⼿动设置这个属性了

5.4 get和post的区别

Get 提交,请求可见,它的请求数据都在请求 url 中;传输数据大小有限制,请求数据大小受限于 url 的大小;传输数据类型和编码受限,只能传递文本信息,且 url 都是用 ascll 编码,所以非 ascll 请求数据要编码后才能传递;安全性低,因为请求数据可见,当有账户密码的等信息时无法保证用户的安全,且使用 get 可能会造成 CSRF 攻击。
Post 提交。请求不可见,请求数据都在 http 请求包中,用户不可见;传输数据大小没有限制;传输数据可以是任何数据,文本,图片,视频,文件都可以,也可以是任意类型的编码;相比于 get 安全性高。

6 HttpServletResponse响应

HttpServletResponse 接⼝,它继承⾃ ServletResponse 接⼝,专⻔⽤来封装 HTTP 响应消息。 在 HttpServletResponse 接⼝中定义了向客户端发送响应状态码,响应消息头,响应消息体的⽅法。

6.1 响应常用方法

方法名作用
void addCookie(Cookie cookie)添加 cookie
sendRedirect(String s)发送⼀条响应码,将浏览器重定向到指定的位置
PrintWriter getWriter()获得字符流,通过字符流的 write(String s) ⽅法可以将字符串设置到 response 缓冲区中,随后Tomcat 会将 response 缓冲区中的内容组装成 Http 响应返回给浏览器端
setContentType(String s)告诉浏览器响应的文件的 MIME 类型,以及文件的编码方式
setCharacterEncoding(String s)设置响应内容的编码方式

6.2 转发和重定向

转发: request.getRequestDispatcher(path).forward(request,response)

浏览器向服务器发送一个请求,服务器为了处理请求将请求转发到一个新的页面。

重定向: response.sendRedirect(path)

浏览器向服务器发送一个请求,服务器响应浏览器一个新的地址去处理请求,浏览器得到响应地址并向新的地址发送请求。

转发和重定向的区别:

区别转发重定向
请求次数请求一次请求两次
地址栏地址栏不变地址栏变化
数据转发一次请求,数据共享重定向两次请求不共享数据
页面跳转只能跳转本站点的资源可以跳转到任意 URL
行为目标转发发生在服务器重定向发生在客户端

7 session会话

从打开浏览器到关闭浏览器,期间访问服务器就称为⼀次会话,一次会话期间可以有多次请求。一个请求间的数据能够共享,但是不能跨页面,重定向的两次请求间数据不共享,一个会话期间的所有数据共享,也可以跨页面。

常用方法:

方法名作用
void setAttribute(String s,Object o)以 key=value 的形式存值,值存储于服务器端
Object getAttribute(String s)通过指定的 key 从 session 中获取对应存储的 value 值,
void removeAttribute(String s)从 session 中删除指定 key 对应的 value 对象
void invalidate()使当前 session 对象失效
void setMaxInactiveInterval(int i)设置 session 的最大非活动时间(单位秒),每次该客户端访问服务器就会刷新最大活动时间,指定时间内该客户端无任何活动,则其存于服务器的 session 就会失效

8 web.xml

web.xml 文件的作用主要有两个:配置 Servlet 的映射关系,初始化参数设置。

8.1 Servlet映射

每个请求都有指定的 Servlet 去处理,如何确定它们的对应关系,这就需要在 web.xml 文件中配置映射关系。根据一个 Servlet 类在项目下的完整路径找到一个指定的 Servlet,然后为其取一个别名,然后在映射表中为该别名指定一个请求路径,如此映射关系就有了。

 <servlet>
 	<servlet-name>⾃定义名称</servlet-name>
 	<servlet-class>处理请求的类的完整路径</servlet-class>
 </servlet>
 <servlet-mapping><!-- mapping 表示映射 -->
 	<servlet-name>⾃定义名称</servlet-name>
 	<url-pattern>请求名</url-pattern>
 </servlet-mapping>

8.2 初始化参数

web.xml 中可以配置一些初始化参数,在 Servlet 初始化的时候可以获取参数进行相应的配置。

为参数指定名称和值就可以完成配置,如下方字符编码参数配置:

 <servlet>
 	<servlet-name>⾃定义名称</servlet-name>
 	<servlet-class>处理请求的类的完整路径</servlet-class>
 	<init-param>
 		<param-name>encoding</param-name>
 		<param-value>utf-8</param-value>
 	</init-param>
</servlet>

使用方式,首先重写 init 方法,然后在方法中获取,如下:

@Override
public void init(ServletConfig config) throws ServletException {
 	String encoding = config.getInitParameter("encoding");
}

这种方式获取的参数仅限在当前指定的 Servlet 中使用。

全局初始化参数配置如下:

 <context-param>
 	<param-name>bianma</param-name>
 	<param-value>utf-8</param-value>
 </context-param>

获取方式如下:

@Override 
public void init(ServletConfig config) throws ServletException {
	String bianma = config.getServletContext().getInitParameter("bianma");
}

9 Servlet3.0

从 Servlet3.0 开始,配置 Servlet ⽀持注解⽅式,但还是保留了配置 web.xml ⽅式。

注解配置的方式更加简洁,高效,使用时只需在 Servlet 类上使用 @WebServlet 注解进⾏配置就行了。

@WebServlet常用属性:

属性名类型是否必须说明
asyncSupportedboolean指定Servlet是否⽀持异步操作模式
displayNameString指定Servlet显示名称
initParamswebInitParam[]配置初始化参数
loadOnStartupint标记容器是否在应⽤启动时就加载这个 Servlet,等价于配置⽂件中的标签
nameString指定Servlet名称
urlPatterns/valueString[]这两个属性作⽤相同,指定Servlet处理的url

属性名和属性值使用等号连接,多个属性间使用逗号分隔,如下:

@WebServlet(name = "myUserServlet",
 urlPatterns = "/user/test", //斜杠必须
 loadOnStartup = 1,
 initParams = {
 @WebInitParam(name="name", value="⼩明"),
 @WebInitParam(name="pwd", value="123456")
 })
public class UserServlet extends HttpServlet {
    ...
}

loadOnStartup属性

标记容器是否在启动应⽤时就加载 Servlet,默认不配置或数值为负数时表示客户端第⼀次请求 Servlet 时再加载;0 或正数表示启动应⽤就加载,正数情况下,数值越⼩,加载该 Servlet 的优先级越⾼。

name属性

可以指定也可以不指定,通过 getServletName() 可以获取到,若不指定,则为 Servlet 的完整类名。

urlPatterns/value属性

String[] 类型,可以配置多个映射,如:urlPatterns={"/user/test", “/user/example”}

使用注解注意事项

根元素中不能配置属性 metadata-complete=“true”,否则⽆法加载注解配置。metadata-complete 属性表示通知 Web 容器是否寻找注解,默认不写或者设置 false,容器会扫描注解,为 Web 应⽤程序构建有效的元数据;metadata-complete=“true”,会在启动时不扫描注解(annotation)。如果不扫描注解的话,⽤注解进⾏的配置就⽆法⽣效。

urlPatterns的使用规则

  • 一个请求路径必须以 / 开头
  • /* 或者 / 可以拦截所有请求
  • 路径拦截:/user/test (只会拦截指定的一个请求路径,必定以 / 开头)
  • 后缀名拦截:*.do (所有以 .do 结尾的请求都会拦截)
  • 路径拦截和后缀名拦截不能一起使用,如:/user/.do 、/.do 、test*.do 都是⾮法的,启动时候会报错
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值