概念
全称 Java Servlet
(Servlet = Service + Applet),用 Java 编写的 服务器端程序
,处理用户发起的请求,用于交互式浏览和生成数据,生成动态Web内容
- 狭义的 Servlet 是指 Java 语言实现的一个接口
- 广义的 Servlet 是指 任何实现了 Servlet 接口的类
应用
Servlet 用于扩展基于 Http协议 的 web服务器
Servlet 导入特定的属于 Java Servlet API 的包
同类技术对比
- Servlet
- 运行在服务端
- 没有图形界面
- Java applet
- 与浏览器一起在客户端运行,当作单独文件跟网页一起发送的小程序
- 具有很好的图形界面
quickstart
声明一个 web 服务器能认识的 Java 类
-
创建普通 Java 类并继承 HttpServlet 类
-
复写 service 方法 (服务器接收到请求时调用 service 方法)
配置 web.xml 使 web服务器 可以找到声明过的 Java 类
- 在 webapp 下的 WEB-INF 文件夹下的 web.xml 文件中配置 servlet
虚拟项目名是自行命名,与 tomcat 配置上写的一致就行
- URL | 服务器地址 : 端口号 / 虚拟项目名 / servlet 别名
- 举个栗子:www.stu.cn:8080/manager/login
- URI | 虚拟项目名 / servlet 别名
- 举个栗子:manager/login
生命周期
-
服务器启动
web.xml
加载进内存 -
第一次调用 xxx 加载进内存,直到终止服务器时才销毁内存
-
load-on-startup 生命周期从服务器启动到服务器关闭
init 方法在servlet 第一次加载进内存时执行
destory 方法在 服务器终止时执行
Servlet方法
- service 方法:
- 不管是get 方式还是post 方式的请求,如果Servlet类中有service方法,则优先调用Service方法。
- doGet 方法:
- 在没有service方法的情况下如果是get方式的请求所调用的处理请求的方法
- doPost 方法:
- 在没有service 方法的情况下如果是post方式的请求所调用的处理请求的方法
- 注意:
- 如果在覆写的service方法中调用了父类的service方法
super . service(req, resp)
- 则service方法处理完后,会再次根据请求方式响应的doGet和doPost方法执行。
- 所以一般情况下,我们是不在覆写的service中调用父类的service方法的,避免出现405错误。
- 如果在覆写的service方法中调用了父类的service方法
Servlet的常见错误
- 404错误:资源未找到
- 原因一:在请求地址中的servlet的别名书写错误。
- 原因二:虚拟项目名称拼写错误
- 500错误内部服务器错误
- 错误一:java . lang . ClassNotFoundException: com. hrbust . servlet .ServletMothod
- 解决:在 web.xml 中校验 servlet 类的全限定路径是否拼写错误。
- 错误二:因为 service 方法体的代码执行错误导致
- 解决:根据错误提示对 service 方法体中的代码进行错误更改。
- 错误一:java . lang . ClassNotFoundException: com. hrbust . servlet .ServletMothod
- 405错误:请求方式不支持
- 原因:请求方式和 servlet 中的方法不匹配所造成的
- 解决:尽量使用 service 方法进行请求处理,并且不要再 service 方法中调用父类的service
Respone对象学习
- 作用:用来响应数据到浏览器的一个对象
- 使用:
-
设置响应头 setHeader(String name , String value);/ /在响应头中添加响应信息,但是同键会覆盖
addHeader(String name , String value);//在响应头中添加响应信息,但是不会覆盖。 -
设置响应状态
// 自定义响应状态码 sendError(int num, String msg);
-
-
设置响应实体
//响应具体的数据给浏览器 resp. getWrite() . write(String str);
-
设置响应编码格式:
resp. setContentType( "text/ html ; charset=utf-8");
-
- 总结:
- service请求处理代码流程:
- 设置响应编码格式
- 获取请求数据
- 处理请求数据
- 数据库操作 (MVC思想)
- 响应处理结果
- service请求处理代码流程:
请求乱码问题
- 使用String进行数据:重新编码
String username = req.getParameter("form-username");
username = new String(username.getBytes("iso8859-1"),"utf-8");
- 使用公共配置
- get方式
- 步骤一:req.setCharacterEncoding(“utf-8”);
- 步骤二:再 tomcat 的目录下的conf 目录中修改 server.xml 文件 -> 在 Connector 标签中增加属性 useBodyEncodingForURI=’‘true”;
- post方式:
- req. setCharacterEncoding(“utf-8”);
- 第一步
- req. setCharacterEncoding(“utf-8”);
- get方式
//设置请求编码格式
req.setCharacterEncoding("utf-8");
-
第二步
增加一行内容
useBodyEncodingDorURI="true"
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" useBodyEncodingDorURI="true" />
Servlet流程总结
- 浏览器发起请求到服务器(请求)
- 服务器接受浏览器的请求,进行解析,创建request对象存储请求数据
- 服务器调用对应的servlet进行请求处理,并将request对象作为实参传递给servlet的方法
- servlet的方法执行进行请求处理
- 设置请求编码格式
- 设置响应编码格式
- 获取请求信息
- 处理请求信息
- 创建业务层对象
- 调用业务层对象的方法
- 响应处理结果
- Servlet的使用流程:
- 设置请求编码格式
- 设置响应编码格式
- 获取请求信息
- 处理请求信息
- 响应处理结果
- 数据流转流程:
- 浏览器—–>服务器——>数据库
- 浏览器——服务器——-数据库
请求转发
- 作用:实现多个servlet联动操作处理请求,这样避免代码冗余,让servlet的职责更加明确。
- 使用:
- req. getRequestDispatcher(“要转发的地址” ). forward(req, resp);`
- 地址:相对路径,直接书写servlet的别名即可。
- 特点:
- 一次请求, 浏览器地址栏信息不改变。
- 注意:
- 请求转发后直接 return 结束即可。
request 作用域
- 问题:
- 使用请求转发后,不同的Servlet之间怎么进行数据的共享 呢?
- 或者说数据怎么从一个servlet流转给另外一个Servlet呢?
-
解决:使用request对象的作用域
- 使用:
request.getAttribute(Object obj)
request.setAttribute(object name,Object value);
- 作用:
- 解决了一次请求内的不同Servlet的数据(请求数据+其他数据)共享问题。
-
作用域:基于请求转发,一次请求中的所有Servlet共享。
- 注意:使用Request 对象进行数据流转,数据只在一次请求内有效。
重定向
- 问题:
- 如果当前的请求,Servlet 无法进行处理怎么办?
- 如果使用请求转发,造成表单数据重复提交怎么办?
- 解诀了表单重复提交的问题,以及当前servlet无法处理的请求的问题。
- 使用: resp. sendRedirect(String uri);
- 特点:
- 两次请求,两个request对象。
- 浏览器地址栏信息改变
- 时机:
- 如果请求中有表单数据,而数据又比较重要,不能重复提交,建议使用重定向
- 如果请求被Servlet接收后,无法进行处理,建议使用重定向定位到可以处理的资源。
Cookies
-
解决问题:发送不同请求的数据共享问题
-
使用:
//Cookie的使用
//创建Cookie对象
Cookie c = new cookie(String name, String value);
//设置cookie(可选)
//设置有效期
c.setMaxAge(int seconds);
//设置有效路径
c.setPath(String uri)
//响应Cookie信息给客户端
resp.addCookie(c);
- 注意:
- 一个 Cookie 对象存储一条数据。多条数据,可以多创建几个 Cookie 对象进行存储。
- 特点:
- 浏览器端的数据存储技术。
- 存储的数据声明在服务器端。
- 临时存储:存储在浏觉器的运行内存中,浏览器关闭即失效。
- 定时存储:设置了 Cookie 的有效期,存储在客户端的硬盘中,在有效期内符合路径要求的请求都会附带该信息。
- 默认 cookie 信息存储好之后,每次请求都会附带,除非设置有效路径
session
-
问题:一个用户的不同请求处理的数据共享怎么办?
-
解诀:使用 session 技术
- 原理:
- 用户第一次访问服务器,服务器会创建一个 session 对象给此用户,
- 并将该 session 对象的 JSESSIONID使用 Cookie 技术存储到浏览器中
- 保证用户的其他请求能够获取到同一个 session 对象
- 也保证了不同请求能够获取到共享的数据。
- 特点:
- 存储在服务器端
- 服务器进行创建
- 依赖Cookie技术
- 作用域
- 一次会话
- 在 JSESSIONID 和 session 对象 不失效的情况下,作用域是整个项目内
- 默认存储时间是 30 min
- 使用:
- 创建 session 对象/获取 session 对象
HttpSession hs=req. getSession();
- 如果请求中拥有 session 标识符也就是
JSESSIONID
,则返回其对应的 session 队形 - 如果请求中没有 session 标识符也就是
JSESSIONID
,则创建新的 session 对象,并将其 JSESSIONID 作为 cookie 数据存储到浏览器中 - 如果 session 对象失效了,也会重新创建一个 session 对象, 并将其 JSESSIONID 存储在浏览器内存中。
- 如果请求中拥有 session 标识符也就是
- 设置 session 存储时间
httpSession.setMaxInactiveInterval(int seconds);
- 设置 session 强制失效
httpSession.invalidate();
- 存储和获取数据
- 存储
httpSession.setAttribute(String s,Object o);
- 获取
httpSession.getAttribute(String s);
- 注意:存储的动作和取出的动作发生在不同的请求中,但是存储在先于取出执行
- 存储
- 创建 session 对象/获取 session 对象
-
使用时机:
- 一般用户在登陆web项目时会将用户的个人信息存储到session中,供该用户的其他请求使用
- session 失效处理
- 将用户请求中的 JSESSIONID 和后台获取到的 session对象 的 JSESSIONID 进行比对
- 一致则 session 没有失效
- 不一致则证明 session 失效
- 重定向到登陆页面,让用户重新登陆
- 总结:
- session 解决了一个用户的不同请求的数据共享问题,只要在 JSESSIONID 不失效和 session对象 不失效的情况下
- 用户的任意请求在处理时都能获取到同一个 session对象
-
注意:
- JSESSIONID 存储在了 Cookie 的临时存储空间中,浏览器关闭即失效。
ServletContext
- 问题
- Request 解决了一次请求内的数据共享问题,session 解决了 用户不同请求的数据共享问题,那么不同的用户的数据共享该怎 么办 ?
- 方法 :使用 ServletContext 对象
- 作用 :解决不同用户数据共享问题
- 获取 ServletContext 对象
- 作用域
- 生命周期
- 服务器启动 –> 服务器关闭
- 使用
ServletConfig
-
问题
- 如何获取在 web.xml 中给每个 servlet 单独配置的数据
-
作用
- ServletConfig 对象是 Servlet 的专属配置对象
- 每个 Servlet 都单独拥有一个 ServletConfig 对象
- 用来获取 web.xml 中的配置信息
-
使用
ServletConfig sc = this.getServletConfig()