Servlet
Java Servlet是运行在Web服务器或应用服务器上的程序,作为客户端(Web浏览器或其他HTTP客户端)和服务端(HTTP服务器上的数据库或应用程序)之间的中间层。
使用Servlet,可以接收来自网页表单的用户输入,呈现来自数据库或其他源的记录,还可以动态创建网页。
Java Servlet可以使用javax.servlet和javax.servlet.http包创建,它是java企业版(java EE)的标准组成部分。
Servlet架构示意图如下:
servlet的主要任务
- 读取客户端发送的显式的(GET)数据。包括网页上的HTML表单,或者客户端自定义的HTTP请求数据;
- 读取客户端发送的隐式的(POST)HTTP请求数据。包括cookies、媒体类型或者浏览器能理解的压缩格式等;
- 处理数据并生成结果。这个过程可能会访问数据库、调用WEB服务器、或者直接进行业务逻辑计算得出要响应给客户端的数据;
- 发送显示的数据(文档)到客户端。该文档的格式可以是多样的,包括文本文件(HTML、XML)、二进制文件(GIF图像)、Excel等;
- 发送隐式的HTTP响应到客户端。包括告诉客户端被返回的文档类型,设置cookies和缓存参数,以及其他类型的任务。
servlet特点
- servlet对象是单例的,每一次请求到达服务器时,服务器(tomcat)会检查有没有目标对象(servlet对象),如果没有则创建,如果有,则拿来直接使用。
由于servlet是单例的,所有的用户共享的是一个对象,所以在servlet实现类中不建议定义成员变量,在高并发情况下Servlet是线程不安全的。
web.xml配置
<!-- 配置servelt -->
<servlet>
<!-- servlet别名 -->
<servlet-name>user</servlet-name>
<!-- sevlet类完整路径 -->
<servlet-class>servlet.UserServlet</servlet-class>
</servlet>
<!-- 配置servlet映射 -->
<servlet-mapping>
<servlet-name>user</servlet-name>
<url-pattern>/u</url-pattern>
</servlet-mapping>
请求与响应
HttpServletRequest请求
//设置请求编码
req.setCharacterEncoding("utf-8");
//获取请求参数
String name = req.getParameter("name");
//获取所有请求参数名的结果集
Enumeration<String> params = req.getParameterNames();
//遍历参数名结果集,获取所有参数值
//hasMoreElements判断参数名集合中是否有元素
while (params.hasMoreElements()) {
//nextElement获取下一个元素
String key = (String) params.nextElement();
System.out.print(key+":"+req.getParameter(key));
}
//向请求对象中添加参数
req.setAttribute("user_list", list);
HttpServletResponse响应
//设置响应数据的编码
resp.setCharacterEncoding("gb2312");
//创建字符输出流,向客户端响应数据
PrintWriter out = null;
out = resp.getWriter();
out.write("success");
out.flush();
if (out == null) {
out.close();
}
页面跳转方式
请求转发
req.getRequestDispatcher("/WEB-INF/page/show.jsp").forward(req, res);
重定向
res.sendRedirect("http://baidu.com");
res.sendRedirect("user?method=queryAll");
Session会话
//创建session会话
HttpSession session = req.getSession();
session.setMaxInactiveInterval(5);//设置session失效时间,单位秒s
//向session中添加信息
session.setAttribute("user_name", "张三");
session.setAttribute("addr", "中国,山东,青岛");
请求转发与重定向的区别
- 转发使用的是getRequestDispatcher()方法;重定向使用的是sendRedirect();
- 转发:浏览器URL的地址栏不变;重定向:浏览器URL的地址栏改变;
- 转发是服务器行为,重定向是客户端行为;
- 转发是浏览器只做了一次访问请求。重定向是浏览器做了至少两次的访问请求;
- 转发两次跳转之间传输的信息不会丢失,重定向两次跳转之间传输的信息会丢失(request范围)。
servlet生命周期
- 可以被定义为servlet对象从创建到销毁的整个过程:
- 在创建servlet对象时,通过调用init()方法进行初始化
- 通过service()方法来处理客户端的请求,根据请求方式的不同转发给doGet()或doPost()方法
- 停止服务时,通过调用destory()方法销毁servlet对象
- servlet对象被JVM垃圾回收器回收
package servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
1 servlet对象是单例的
每一次请求到达服务器时,服务器(tomcat)会检查有没有目标对象(servlet对象),如果没有则创建,如果有,则拿来直接使用。
由于servlet是单例的,所有的用户共享的是一个对象,所以在servlet实现类中不建议定义成员变量,在高并发情况下Servlet是线程不安全的。
2 servlet的生命周期
可以被定义为servlet对象从创建到销毁的整个过程:
1)在创建servlet对象时,通过调用init()方法进行初始化
2)通过service()方法来处理客户端的请求,根据请求方式的不同转发给doGet()或doPost()方法
3)停止服务时,通过调用destory()方法销毁servlet对象
4)servlet对象被JVM垃圾回收器回收
*
*/
public class DemoServlet extends HttpServlet{
{
System.out.println("yes");
}
@Override
public void init() throws ServletException {
/*
* 初始化方法
* 1 只会调用一次;
* 2 在创建servlet对象时调用,在后续每次用户请求时不再调用。
*
*/
System.out.println("*****init*****(调用servlet对象时才会调用init()方法)");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
* service()方法,是执行实际业务任务的主要方法,由servlet的对象的容器调用service方法
* 作用:处理来自客户端的请求,并把格式化的响应写回给客户端
* 1 service()方法由容器调用;
* 2 service()方法会检查HTTP请求类型(GET/POST/PUT/DELETE等),然后根据请求类型的不同,调用对应的方法,
* 如GET请求调用doGet()方法,POST请求调用doPost()方法;
* 3 所以,不需要对service方法做任何修改,只需要根据客户端的请求类型来重写doGet()和doPost()方法;
*/
System.out.println("*****service*****");
super.service(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
* HttpServletRequest,接收HTTP请求,
* 提供了一系列的方法来:
* 1 接收HTTP头信息、cookies
* 2 获取HTTP请求参数
* 3 设置HTTP请求编码
* 4 获取HTTP的请求方式GET/POST
*/
System.out.println("接受HTTP的GET方式请求");
//请求转发:通过请求转跳转到JSP页面
req.getRequestDispatcher("/WEB-INF/page/demo.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
@Override
public void destroy() {
/*
* 销毁servlet对象
* 1 destroy()方法只调用一次,在servlet对象生命周期结束时(如停止tomcat服务)被调用。
* 2 destroy()方法可以关闭数据库连接、停止后台线程、把cookie或者缓存写入硬盘以及其他清理活动
* 3 在调用destroy()方法后,servlet对象会被GC(垃圾回收)线程标记为被回收的资源。
*/
System.out.println("*****destroy*****(停止服务)");
}
}
信息: [1156]毫秒后服务器启动
*****init*****(调用servlet对象时才会调用init()方法)
*****service*****
接受HTTP的GET方式请求
二月 10, 2022 9:44:13 上午 org.apache.catalina.core.StandardServer await
信息: 通过关闭端口接收到有效的关闭命令。正在停止服务器实例。
二月 10, 2022 9:44:13 上午 org.apache.coyote.AbstractProtocol pause
信息: 暂停ProtocolHandler["http-nio-8080"]
二月 10, 2022 9:44:13 上午 org.apache.catalina.core.StandardService stopInternal
信息: 正在停止服务[Catalina]
*****destroy*****(停止服务)
二月 10, 2022 9:44:13 上午 org.apache.coyote.AbstractProtocol stop
信息: 正在停止ProtocolHandler ["http-nio-8080"]
二月 10, 2022 9:44:13 上午 org.apache.coyote.AbstractProtocol destroy
信息: 正在摧毁协议处理器 ["http-nio-8080"]