一、流程图
二、代码实现
- 用户发送请求,action=add
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="add" method="post">
名称:<input type="text" name="fname"><br/>
价格:<input type="text" name="price"><br/>
库存:<input type="text" name="fcount"><br/>
备注:<input type="text" name="remark"><br/>
<input type="submit" value="添加">
</form>
</body>
</html>
- 项目中,web.xml中配置url-pattern = /add
- 找到名字,servlet-name = AddServlet
- 找和servlet-mapping中servlet-name一致的servlet
- 找到servlet-class 中的 com.atguigu.servlets.AddServlet类
- 用户发送post请求,因此tomcat会执行AddServlet类中的doPost方法
<servlet>
<servlet-name>Addservlet</servlet-name>
<servlet-class>com.atguigu.servlets.AddServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Addservlet</servlet-name>
<url-pattern>/add</url-pattern>
</servlet-mapping>
- 执行dopost
public class AddServlet extends HttpServlet {
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fname = request.getParameter("fname");
String price = request.getParameter("price");
String fcountStr = request.getParameter("fcount");
String remark = request.getParameter("remark");
System.out.println("fname = " + fname + price + fcountStr +remark);
}
}
三、IDEA配置WEB项目
1.编辑IDEAtomcat
2.生成包,并配置在tomcat中
Archive是war包
Exploded是解压缩后的程序包
四、继承关系
1.继承关系
Servlet接口、GenericServlet抽象类、HttpServlet抽象子类
2.相关方法
- init-初始化方法
- service-服务方法
- destory-销毁方法
3.service方法
继承关系
:HttpServlet -> GenericServlet -> ServletServlet核心方法
:init(),service(),destroy()service方法
:当有请求过来时,service方法会自动响应,在HttpServlet中会根据请求方式调用不同的do方法,这些do方法默认都是405的实现风格-要子类去实现对应方法,否则会报错405重写do方法
:新建Servlet时,根据请求方法,重写相应的do方法。
GenericServlet类中,service还是抽象类,并没有做具体实现
HttpServlet中有service方法的具体实现
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取请求的方式
String method = req.getMethod();
long lastModified;
//2.根据不同的请求方式,调用不同的do方法
if (method.equals("GET")) {
lastModified = this.getLastModified(req);
if (lastModified == -1L) {
this.doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader("If-Modified-Since");
} catch (IllegalArgumentException var9) {
ifModifiedSince = -1L;
}
if (ifModifiedSince < lastModified / 1000L * 1000L) {
this.maybeSetLastModified(resp, lastModified);
this.doGet(req, resp);
} else {
resp.setStatus(304);
}
}
} else if (method.equals("HEAD")) {
lastModified = this.getLastModified(req);
this.maybeSetLastModified(resp, lastModified);
this.doHead(req, resp);
} else if (method.equals("POST")) {
this.doPost(req, resp);
} else if (method.equals("PUT")) {
this.doPut(req, resp);
} else if (method.equals("DELETE")) {
this.doDelete(req, resp);
} else if (method.equals("OPTIONS")) {
this.doOptions(req, resp);
} else if (method.equals("TRACE")) {
this.doTrace(req, resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[]{method};
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
}
}
doPost方法
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String msg = lStrings.getString("http.method_post_not_supported");
this.sendMethodNotAllowed(req, resp, msg);
}
五、生命周期
生命周期
: 从出生到死亡的过程叫生命周期,对应Servlet的三个方法 init -> service -> destroy
2.演示
- 初始化:第一次接收请求时,这个Servlet会进行实例化(调用构造方法)、初始化(调用init())
- 服务:初始化以后,就不用初始化了,只调用服务方法
- 销毁:容器关闭时,其中所有Servlet销毁
- Servlet实例tomcat只会创建一个,所有请求都是这个实例去响应,默认情况下,第一次请求时,tomcat才会去实例化,初始化。
会造成第一次访问的时候,系统响应比较慢
- 通过设置Servlet初始化时机,提高响应速度。数字越小启动越靠前,通过数字设置启动顺序。
6. Servlet在容器中:单例的:所有的请求通过同一个实例去响应。线程不安全:一个线程需要根据这个实例中某个成员变量的值去做判断,但是在中间某
个时间,另一线程改变了这个成员变量的值,导致第一个现成的执行路径发生改变,所以尽量不要再servlet中定义成员变量
六、HTTP协议
1.介绍
超文本传输协议,HTTP最大的作用就是确定了请求和响应数据的格式。浏览器发送给服务器的数据:请求报文;服务器返回给浏览器的数据:响应报文。
2.请求报文
- 请求行
\
- 请求头
包含了很多客户端需要告诉服务器的信息
3. 请求主体
- get方式,没有请求体,但是有个queryString
- post方式,有请求体,form data
- json格式,有请求体,request payload
3.响应报文
1.响应行
协议、响应状态码、响应状态
2.响应头
服务器发送给浏览器的信息(内容的媒体类型,编码)
3.响应体
响应的实际内容
七、session会话跟踪
HTTP无状态:服务器无法判断这两次请求是同一个客户端发来的,还是不同客户端发来的
通过会话跟踪技术解决无状态问题
1.演示
//演示Session
public class Demo03Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取Session,如果获取不到,则创建一个新的
HttpSession session = request.getSession();
System.out.println("session ID : " + session.getId());
}
}
2.session保存作用域
1.作用域
session保存作用域是和具体某一个session对应
2.常用API
seesion.setAttribute
seeion.getAttribute
八、服务器内部转发及客户端重定向
1.服务器内部转发
一次请求响应过程,对于客户端而言,内部经过多少次转发,客户端是不知道的–访问地址无变化
request.getRequestDispatcher("…").forward(request,response);
2.客户端重定向
二次请求响应过程,客户端感知到请求URL有变化–地址栏有变化
response.sendRedirect("…")