如今我们访问网站都是基于Web这种Browser/Server模式,简称BS架构,它的特点是,客户端只需要浏览器,应用程序的逻辑和数据都存储在服务器端。浏览器只需要请求服务器,获取Web页面,并把Web页面展示给用户即可。
Web页面具有极强的交互性。由于Web页面是用HTML编写的,而HTML具备超强的表现力,并且,服务器端升级后,客户端无需任何部署就可以使用到新的版本,因此,BS架构升级非常容易。
HTML是一种用来定义网页的文本,会HTML,就可以编写网页;
HTTP是在网络上传输HTML的协议,用于浏览器和服务器的通信。
HTTP协议是一个基于TCP协议之上的请求-响应协议。
对于Browser来说,请求页面的流程如下:
GET / HTTP/1.1
Host: www.sina.com.cn
User-Agent: Mozilla/5.0 xxx
Accept: */*
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8
服务器的响应如下:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 21932
Content-Encoding: gzip
Cache-Control: max-age=300
...网页数据...
服务器响应的状态码一般有如下几种
实现一个最简单的Servlet:(注解)
// WebServlet注解表示这是一个Servlet,并映射到地址/:
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("hello tomcat");//通过请求对象 获取请求参数 HttpServletRequest req form aString username = req.getParameter("username");String password = req.getParameter("password");System.out.println("password = " + password);System.out.println("username = " + username);//通过HttpServletRequest req 还有哪些信息可以获取?// 获取请求方式 get post delete putString method = req.getMethod();System.out.println("method = " + method);// 请求地址的获取String servletPath = req.getServletPath();System.out.println("servletPath = " + servletPath);//项目的虚拟名称String contextPath = req.getContextPath();System.out.println("contextPath = " + contextPath);// 请求地址的全称 URL 统一资源定位符 http://localhost:8080/javaweb/helloStringBuffer requestURL = req.getRequestURL();System.out.println("requestURL = " + requestURL);//资源地址 /javaweb/helloString requestURI = req.getRequestURI();System.out.println("requestURI = " + requestURI);// 协议 HTTP/1.1String protocol = req.getProtocol();System.out.println("protocol = " + protocol);// 设置响应格式 html jsonresp.setContentType("text/html;charset=utf-8");// 响应数据给前端浏览器 HttpServletResponse resp 通过响应对象 获取输出流 通过流将数据响应给前端浏览器PrintWriter writer = resp.getWriter();writer.write("hello tomcat
"); //table 展示用户信息 id username password address 5条数据writer.close();}
}
当然也可以使用配置文件的方法,我们只需要配置web.xml文件如下
helloServlet cn.kgc.servlet.HelloServlet helloServlet /hello.do
URL:http://localhost:8080/hello.do
step1:根据ip和端口号建立连接
step2:浏览器端通信模块打包数据
step3:发送数据到服务器
step4: 服务器通信模块解析数据
step5:容器创建request和response对象,然后将解析后的数据存放到request对象中
step6: 根据请求路径,寻找相关的servlet类创建对象,
step7:调用其service方法,将step5创建的对象作为参数传入
step8:获取service方法处理后的结果,并打包响应回浏览器
step9:浏览器的通信模块解析响应数据
step10:展示数据
代码 | 消息 | 描述 |
---|---|---|
100 | Continue | 只有请求的一部分已经被服务器接收,但只要它没有被拒绝,客户端应继续该请求。 |
101 | Switching Protocols | 服务器切换协议。 |
200 | OK | 请求成功。 |
201 | Created | 该请求是完整的,并创建一个新的资源。 |
202 | Accepted | 该请求被接受处理,但是该处理是不完整的。 |
300 | Multiple Choices | 链接列表。用户可以选择一个链接,进入到该位置。最多五个地址。 |
301 | Moved Permanently | 所请求的页面已经转移到一个新的 URL。 |
302 | Found | 所请求的页面已经临时转移到一个新的 URL。 |
303 | See Other | 所请求的页面可以在另一个不同的 URL 下被找到。 |
306 | Unused | 在以前的版本中使用该代码。现在已不再使用它,但代码仍被保留。 |
307 | Temporary Redirect | 所请求的页面已经临时转移到一个新的 URL。 |
400 | Bad Request | 服务器不理解请求。 |
401 | Unauthorized | 所请求的页面需要用户名和密码。 |
402 | Payment Required | 您还不能使用该代码。 |
403 | Forbidden | 禁止访问所请求的页面。 |
404 | Not Found | 服务器无法找到所请求的页面 。. |
405 | Method Not Allowed | 在请求中指定的方法是不允许的。 |
406 | Not Acceptable | 服务器只生成一个不被客户端接受的响应。 |
407 | Proxy Authentication Required | 在请求送达之前,您必须使用代理服务器的验证。 |
408 | Request Timeout | 请求需要的时间比服务器能够等待的时间长,超时。 |
409 | Conflict | 请求因为冲突无法完成。 |
410 | Gone | 所请求的页面不再可用。 |
411 | Length Required | "Content-Length" 未定义。服务器无法处理客户端发送的不带 Content-Length 的请求信息。 |
412 | Precondition Failed | 请求中给出的先决条件被服务器评估为 false。 |
413 | Request Entity Too Large | 服务器不接受该请求,因为请求实体过大。 |
414 | Request-url Too Long | 服务器不接受该请求,因为 URL 太长。当您转换一个 "post" 请求为一个带有长的查询信息的 "get" 请求时发生。 |
415 | Unsupported Media Type | 服务器不接受该请求,因为媒体类型不被支持。 |
500 | Internal Server Error | 未完成的请求。服务器遇到了一个意外的情况 。 |
501 | Not Implemented | 未完成的请求。服务器不支持所需的功能。 |
502 | Bad Gateway | 未完成的请求。服务器从上游服务器收到无效响应。 |
503 | Service Unavailable | 未完成的请求。服务器暂时超载或死机。 |
504 | Gateway Timeout | 网关超时。 |
505 | HTTP Version Not Supported | 服务器不支持"HTTP协议"版本。 |
Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:
(1)Servlet 初始化后调用 init () 方法。只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用
(2)Servlet 调用 service() 方法来处理客户端的请求。service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。
(3)Servlet 销毁前调用 destroy() 方法。destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收。
(4)最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的
HTTP协议
超文本传输协议(Hypertext Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。
三个基本原则
1.基于请求响应模型
2.一次请求对应一次响应
3.请求必须是客户端发出,服务端只能被动的等待请求,然后做出回应
HTTP请求格式
1.请求行(请求方式 请求资源路径 协议和版本)
2.消息头
3.请求实体内容
如果请求的方式是get请求,那么请求的实体内容为空,只有请求方式是post请求时,实体内容才有数据
1.状态行
2.响应头
3.响应实体内容
案列:模拟使用servlet实现用户的查询,并展示在前端页面,此处没有使用html页面和jsp页面。
import cn.kgc.javaweb.entity.User;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;@WebServlet("/table") // 通过注解取代配置的方式 实现servlet的声明
public class TableServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 响应一个表格给前端浏览器 html username password addressString username = req.getParameter("username");String password = req.getParameter("password");String address = req.getParameter("address");System.out.println("address = " + address);System.out.println("username = " + username);System.out.println("password = " + password);User user = new User();user.setUsername(username);user.setPassword(password);user.setAddress(address);// 将user对象封装到集合ArrayList users = new ArrayList<>();Collections.addAll(users, user,user,user,user);// 将获取的参数 响应成一个表格给前端浏览器 jsonresp.setContentType("text/html;charset=utf-8");PrintWriter writer = resp.getWriter();writer.write("");writer.write(" ");writer.write("用户名 ");writer.write("密码 ");writer.write("地址 ");writer.write(" ");// 通过 查询数据库 将查询的结果响应给浏览器 Listusers.forEach(usr->{writer.write(" ");writer.write(""+usr.getUsername()+" ");writer.write(""+usr.getPassword()+" ");writer.write(""+usr.getAddress()+" ");writer.write(" ");});writer.write("
");// 关闭流 释放资源writer.close();}
}