JavaWeb-HTTP协议(服务器数据的接收、处理、响应流程)详解
HTTP协议
● 什么是HTTP协议? 超文本传输协议(Hypertext Transfer Protocol)服务器传输超文本到本地浏览器的传送协议,是互联网上应用最为流行的一种网络协议,用于定义客户端浏览器和服务器之间交换数据的过程
● HTTP是基于TCP/IP通信协议来传送数据
● HTTP是属于引用层的协议,由于棋简捷、快速的方式、适用于分布式超媒体信息系统
HTTP请求
客户端连上服务器后,向服务器请求某个web资源,称之为客户端向服务器发送一个http请求。
就是从浏览器中以超链接,表单等向服务器发送的请求都称为http请求。
请求包括:请求行,请求头,(这两部分会自动发送) 请求体。
请求行:http请求方式,请求资源名称,http版本(例如post、post、text.jsp、HTTP/1.1)
请求头:服务器端和客户端的一些信息格式为键值对。
请求体:是指表单post方式请求时,向服务器端发送的数据
请求头包含主机地址,以及客户端的一些环境信息,以键值对的形 式传递.
Host: 127.0.0.1:8088 请求的主机地址
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8 浏览器能够处理的内容类型
Accept-Encoding: gzip, deflate, br 浏览器能够处理的压缩编码
Accept-Language: zh-CN,zh;q=0.9 浏览器当前设置的语言
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36 使用的浏览器和操作平台信息
Connection: keep-alive 浏览器与服务器之间连接的类型
请求体代表着浏览器在post请求方式中传递给服务器的参数,请求体中参数以 键值形式传递, 多个用&链接,服务器接收到后再解析. username=admin&userpwd=123
两种HTTP请求方式
get(获得):从服务器端获取数据,在地址栏会显示发送的数据,但是一般有以下状况
1、不安全
2、传输的数据大小受限制 一般浏览器的大小为2-5kb
● 以超链接访问,默认是GET方式
● form提交,不指定method,默认为GET方式
post(发送):向服务器端发送数据,向服务器端发送数据,发送的数据是在请求体当中,安全(相对安全),大小不受限制
● form提交,指定method=“post”
get/post的区别
● get方式主要是从服务器获取信息;post主要是向服务器提交信息
● get方式在通过URL提交数据,数据在URL中可以看到;POST方式,数据是放置在请求体中提交。
● get方式提交的数据大小受限制一般都很小(不同浏览器也会有不同);而 post则没有此限制。
在父类的service中写了一个判断 get---->doGet、post----->doPost
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的第一个web程序</title>
</head>
<body>
<a href="demourl">列表</a>
<form action="demourl" method="post">
账号:<input type="text">
密码:<input type="password">
<input type="submit" value="保存">
</form>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>demo</servlet-name>
<servlet-class>com.student.firstweb.servlet.Demo1Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo</servlet-name>
<url-pattern>/demourl</url-pattern>
<!--前端点击的连接就是与这个做连接相对应-->
</servlet-mapping>
</web-app>
package com.student.firstweb.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class Demo1Servlet extends HttpServlet {
//service 每次请求都要调用,由于http请求分为get,post请求,在service中两者处理上有略微不同
//所以父类中定义了doGet() doPost()分别处理get,post请求
//就是在父类service的方法中写了一个判断 get就调用doGet(),post就调用doPost()
//doGet()和doPost()都是属于service中的方法。
//doGet()处理get请求
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet方法");
}
//doPost()处理post请求
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost方法");
}
}
分别点击列表和保存就调用了各自的请求方式
列表—>doGet、保存—>doPost
在服务器接收信息(HttpServletRequest)
● 请求和响应是Web交互最基本的模式,在Servlet中,用HttpServletRequest 来表示请求。
(HttpServletRequest req, HttpServletResponse resp)中的HttpServletReuuest req
● HttpServletRequest是ServletRequest的子接口。HttpServletRequest比ServletRequest多了一些针对于Http协议的方法。
数据请求先到达服务器,服务器接收请求数据,然后服务器将接收到的数据封装到RequestFacade(这里说明的这个类属于Tomcat),而他实现的是java对外提供的HttpServletRequest接口 (是RequestFacade implements HttpServletRequest) ,所以程序员只要面对HttpServletRequest req,服务器就会把接收到的数据传输过来(例如:Tomcat就将它自己RequestFacade这个类给传输过来)
所以我们在写代码的时候只需要写一个HttpServletRequest,但实际上传输过来的是RequestFacade
所以我们就只需要学习java中的统一标准接口。
这就是javaSE多态的体现
● HttpServletRequest :封装了请求的信息,可以从中获取任何请求信息。
请求行
获得请求类型数据: req.getMethod()
获得协议:req.getProtocol()
获得请求服务器的地址:req.getServerName()
获得请求服务器的端口:req.getServerPort()
请求头
获得客户端的ip:req.getRemoteAddr()
获得客户端的端口:req.getServerPort()
获得请求头中的某一数据:req.getHeader(“User-Agent”)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的第一个web程序</title>
</head>
<body>
<!--前段传输的数据一定都是键=值&键=值-->
<a href="demourl?name=张三&age=20">列表</a>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>demo</servlet-name>
<servlet-class>com.student.firstweb.servlet.Demo1Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo</servlet-name>
<url-pattern>/demourl</url-pattern>
<!--前端点击的连接就是与这个做连接相对应-->
</servlet-mapping>
</web-app>
package com.student.firstweb.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class Demo1Servlet extends HttpServlet {
//service 每次请求都要调用,由于http请求分为get,post请求,在service中两者处理上有略微不同
//所以父类中定义了doGet() doPost()分别处理get,post请求
//就是在父类service的方法中写了一个判断 get就调用doGet(),post就调用doPost()
//doGet()和doPost()都是属于service中的方法。
//doGet()处理get请求
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet方法");
//请求行数据
System.out.println(req.getMethod());//获得请求类型数据
System.out.println(req.getProtocol());//获得协议
System.out.println(req.getServerName());//获得请求服务器的地址
System.out.println(req.getServerPort());//获得请求服务器的端口
//请求头数据
System.out.println(req.getRemoteAddr());//获得客户端的ip
System.out.println(req.getServerPort());//获得客户端的端口
System.out.println(req.getHeader("User-Agent"));//获得请求头中的某一数据
}
}
请求体
接收用户的请求数据,因为前段传输过来的数据都是键值对,所以后端就可以通过键来接收前端传输过来的数据。
通过parameter来获取前段发送过来的数据
getParameter(name) — String 通过name获得值
getParameterValues — String[ ] 通过name获得多值
req.getParameter(“name”)
Tomcat8.0之后get请求数据的解码方式支持中文 ,但是post请求解码是不支持中文的,所以我们要设置post请求数据的解码格式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的第一个web程序</title>
</head>
<body>
<!--前段传输的数据一定都是键=值&键=值-->
<a href="demourl?name=张三&age=20">列表</a>
<form action="demourl" method="post">
账号:<input type="text" name="account">
密码:<input type="password" name="password">
课程:<input type="checkbox" value="java" name="course">java
<input type="checkbox" value="c" name="course">c
<input type="checkbox" value="python" name="course">python
<input type="submit" value="保存">
</form>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>demo</servlet-name>
<servlet-class>com.student.firstweb.servlet.Demo1Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo</servlet-name>
<url-pattern>/demourl</url-pattern>
<!--前端点击的连接就是与这个做连接相对应-->
</servlet-mapping>
</web-app>
package com.student.firstweb.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
public class Demo1Servlet extends HttpServlet {
//service 每次请求都要调用,由于http请求分为get,post请求,在service中两者处理上有略微不同
//所以父类中定义了doGet() doPost()分别处理get,post请求
//就是在父类service的方法中写了一个判断 get就调用doGet(),post就调用doPost()
//doGet()和doPost()都是属于service中的方法。
//doGet()处理get请求
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet方法");
//接收用户请求的数据,通过键名来获得前段的数据
// Tomcat8.0之后get请求数据的解码方式支持中文
String name = req.getParameter("name");
System.out.println(name);
System.out.println(req.getParameter("age"));
}
//doPost()处理post请求
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost方法");
//因为不支持中文,所以就要设置中文编码
req.setCharacterEncoding("utf-8");//设置post请求数据的解码格式
System.out.println(req.getParameter("account"));
System.out.println(req.getParameter("password"));
System.out.println(req.getParameter("course"));
String[] courses = req.getParameterValues("course");
System.out.println(Arrays.toString(courses));
}
}
处理
例如:使用jdbc处理
响应
一个http响应代表服务器向客户端回送的数据,它包括:响应行,响应头,响应体。
响应行里包含了http协议版本,以及用于描述服务器对请求的处理结果。
HTTP/1.1 (协议版本) 200(状态吗) OK(状态码描述)
状态码就是:服务器和浏览器用于确定状态的固定数字号码(实现固定好的)
◆ 200:请求成功
◆ 302:请求重定向
◆ 400:语义有误,当前请求无法被服务器理解或请求参数有误
◆ 404:请求资源不存在,通常是路径写错了或者服务器资源删除了
◆ 500:服务内部错误(代码异常)
响应头就是用于描述服务器的基本信息,以及数据描述
Ser ver Apache-Coyote/1.1
Content-Type text /html;charset=UTF-8
Content-Length 0
Date Wed, 13 Sep 2017 02:26:07 GMT
响应体则代表服务器向客户端浏览器回送的正文
(HttpServletRequest req, HttpServletResponse resp)中的HttpServletResponse resp
就是根据处理的结构向客户端做出响应
也是一个接口,是和接收同理。Tomcat实现出java中的一个接口==(ResponseFacade implements HttpServletResponse)==,我们利用多态的性质通过java的接口来调用我们需要的方法 。
//响应
PrintWriter writer = null;
try{
resp.setContentType("text/html;charset=utf-8");//设置响应内容的编码格式
writer = resp.getWriter();//获得打印字符流
writer.println("<h1>操作成功<h1>");
}catch (Exception e){
e.printStackTrace();
writer.println("<h1>服务器忙<h1>");
}
是写在servlet中,响应回去我们所需要的动态页面内容
早期的时候是用jsp来书写需要返回的动态页面,但是到现在它已经被淘汰了,因为18年出了ajax,几乎已经完全替换了jsp的书写
使用ajax从前端向后端进行发起请求交互