Servlet与HTTP请求协议
Posted 超霸霸
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Servlet与HTTP请求协议相关的知识,希望对你有一定的参考价值。
Servlet与HTTP请求协议
一、相关概念
-
Servlet
的体系结构:-
Servlet(接口)–>
GenericServlet
(抽象类)–>HttpServlet
(抽象类) -
GenericServlet:将
Servlet
接口其他的方法做了默认空实现,只将service()
方法作为抽象,将来定义Servlet
类时,可以继承GenericServlet
,实现service()
方法即可 -
HttpServlet
:对http协议的一种封装,简化操作- 定义类继承
HttpServlet
- 复写
doGet/doPost
方法
- 定义类继承
-
-
Servlet
相关配置:-
urlpattern
:Servlet
访问路径 -
一个
Servlet
可以定义多个访问路径:@webServlet({"/d4","/dd4","/ddd4"})
-
路径定义规则:
/xxx
:路径匹配/xxx/xxx
:多层路径,目录结构*.do
:扩展名匹配
-
-
HTTP
:- 概念:
Hyper Text Transfer Protocol
超文本传输协议 - 传输协议:定义客户端和服务器端通信时发送数据的格式
- 特点:
- 基于TCP/IP的高级协议
- 默认端口号:80
- 基于请求/响应模型:一次请求对应一次响应
- 无状态:每次请求之间互相独立,不能交互数据
- 历史版本:
- 1.0:每次请求响应都会建立新的连接
- 1.1:复用连接,一次连接可进行多次请求响应
- 概念:
-
请求消息数据格式:
-
请求行
GET /login.html HTTP/1.1 请求方式 请求url 请求协议/版本
- 请求方式:HTTP中有7种请求方式,常用的有2种
GET
- 请求参数在请求行中,url后
- 请求的url长度有限制
- 不太安全
POST
- 请求参数在请求体中
- 请求的url长度没有限制
- 相对安全
- 请求方式:HTTP中有7种请求方式,常用的有2种
-
请求头
- 客户端浏览器告诉服务器一些信息
- 请求头名称:请求头值
- 常见的请求头:
User-Agent
:浏览器告诉服务器,我访问你使用的浏览器版本信息,可以在服务器端获取该头的信息,解决浏览器的兼容性问题Referer
:告诉服务器当前请求从哪里来,作用:防盗链和统计
HOST: localhost User-Agent: Mozilla/5.0 (Windows NT 6.1;Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0 Accept: text/html,appliaction/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: keep-alive Upgrade-Insecure-Requests: 1
-
请求空行
- 空行,用于分割
POST
请求的请求头和请求体
- 空行,用于分割
-
请求体(正文)
- 存放参数,封装
POST
请求消息的请求参数,GET
方式没有请求体
username="zhangsan" password=123456
- 存放参数,封装
-
二、Request
-
request
对象和response
对象的原理:request
和response
对象是由服务器创建的,我们来使用它们request
对象是用来获取请求消息,response
对象是用来设置相应消息
-
request
对象继承体系结构:ServletRequest
(接口)–>HttpServletRequest
(接口)–>Tomcat
(实现)
-
request
功能:-
获取请求消息数据
-
获取请求行数据
- 获取请求方式:
GET
String getMethod()
- 获取虚拟目录:/day14
String getContextPath()
- 获取
Servlet
路径:/demo01
String getServletPath()
- 获取
GET
方式请求参数:name=zhangsan
String getQueryString()
- 获取请求方式:
- 获取请求URI:/day14/demo01
String getRequestURI()
:/day14/demo01
(URI,统一资源定位符)
StringBuffer getRequestURL()
:http://localhost/day14/demo01(URL,统一资源标识符) - 获取协议及版本:HTTP/1.1
String getProtocol()
- 获取客户机的IP地址:10.159.00.8
String getRemoteAddr()
-
package cn.chao.web.servlet; 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; @WebServlet("/demo5") public class ServletDemo5 extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.获取请求方法 String method = request.getMethod(); System.out.println(method); //2.获取虚拟目录 String contextPath = request.getContextPath(); System.out.println(contextPath); //3.获取Servlet路径 String servletPath = request.getServletPath(); System.out.println(servletPath); //4.获取请求参数 String queryString = request.getQueryString(); System.out.println(queryString); //5.获取URI和URL String requestURI = request.getRequestURI(); StringBuffer requestURL = request.getRequestURL(); System.out.println(requestURI); System.out.println(requestURL); //6.获取协议及版本 String protocol = request.getProtocol(); System.out.println(protocol); //7.获取客户端IP地址 String remoteAddr = request.getRemoteAddr(); System.out.println(remoteAddr); } }
在网址中输入:
http://localhost:8080/demo5?username=zhangsan
输出:
GET /demo5 username=zhangsan /demo5 http://localhost:8080/demo5 HTTP/1.1 0:0:0:0:0:0:0:1
- 获取请求头数据
String getHeader(String name)
:通过请求头的名称获取请求头的值Enumeration<String> getHeaderNames
:获取所有的请求头名称
package cn.chao.web.servlet; 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.util.Enumeration; @WebServlet("/demo5") public class ServletDemo5 extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String agent = request.getHeader("user-agent"); if (agent.contains("Chrome")) { System.out.println("谷歌来了"); } else if (agent.contains("Firefox")) { System.out.println("火狐来了"); } else if (agent.contains("Edge")) { System.out.println("Edge来了"); } else { System.out.println("其他浏览器来了"); } } }
使用谷歌浏览器,在网址中输入:
http://localhost:8080/demo5
输出:
谷歌来了
package cn.chao.web.servlet; 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.util.Enumeration; @WebServlet("/demo5") public class ServletDemo5 extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //演示获取请求头数据 //1.获取所有请求头名称 Enumeration<String> headerNames = request.getHeaderNames(); //2.遍历 while (headerNames.hasMoreElements()) String name = headerNames.nextElement(); //根据名称获取请求头的值 String value = request.getHeader(name); System.out.println(name + "---" + value); } } }
在网址中输入:
http://localhost:8080/TomcatStudy02_war_exploded/demo5
输出:
host---localhost:8080 connection---keep-alive upgrade-insecure-requests---1 user-agent---Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 SLBrowser/7.0.0.8031 SLBChan/25 accept---text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 sec-fetch-site---none sec-fetch-mode---navigate sec-fetch-user---?1 sec-fetch-dest---document accept-encoding---gzip, deflate, br accept-language---zh-CN,zh;q=0.9 cookie---JSESSIONID=4124D21F1230D29F5A04EA5E86994D93
package cn.chao.web.servlet; 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.util.Enumeration; @WebServlet("/demo5") public class ServletDemo5 extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //演示获取请求头数据:referer String referer = request.getHeader("referer"); System.out.println(referer); //防盗链 if (referer != null) { if (referer.contains("TomcatStudy02_war_exploded")) { //正常访问 System.out.println("播放电影"); } else { //盗链 System.out.println("想看电影吗,来b站!"); } } } }
在
login.html
中写一个超链接:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <a href="/TomcatStudy02_war_exploded/demo5">demo5</a> </body> </html>
在网址中输入:
http://localhost:8080/TomcatStudy02_war_exploded/login.html
点击网页的超链接,输出:
http://localhost:8080/TomcatStudy02_war_exploded/login.html
-
获取请求体数据(只有
POST
请求方法才有请求体)- 步骤:
- 获取流对象
BufferedReader getReader()
:获取字符输入流,只能操作字符数据ServletInputStream getInputStream()
:获取字节输入流,可以操作所有类型数据
- 从流对象中拿数据
- 获取流对象
- 步骤:
package cn.chao.web.servlet; 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.BufferedReader; import java.io.IOException; import java.util.Enumeration; @WebServlet("/demo5") public class ServletDemo5 extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { BufferedReader br = request.getReader(); String line = null; while ((line = br.readLine()) != null) { System.out.println(line); } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
写一个登录界面(
regist.html
) :<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/demo5" method="post"> <input type="text" placeholder="请输入用户名" name="username"><br> <input type="text" placeholder="请输入密码" name="password"><br> <input type="submit" value="注册"> </form> </body> </html>
在网址中输入:
http://localhost:8080/regist.html
填入信息,输出:
username=zhangsan&password=123
-
其他功能:
-
获取请求参数通用方式:不论是
get
还是post
请求方法都可以使用下列方法来获取请求参数String getParameter(String name)
:根据参数名名称获取参数值String[] getParameterValues(String name)
:根据参数名称 获取参数值的数组Enumeration<String> getParameterNames()
:获取所有请求的参数名称Map<String,String[]> getParameterMap()
:获取所有参数的map集合
package cn.chao.web.servlet; 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.util.Enumeration; import java.util.Map; import java.util.Set; @WebServlet("/demo5") public class ServletDemo5 extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //post获取请求参数 //根据参数名称获取参数值 String username = request.getParameter("username"); System.out.println("post"); System.out.println(username); System.out.println(); //根据参数名称获取参数值的数组 String[] hobbies = request.getParameterValues("hobby"); for (String hobby : hobbies) { System.out.println(hobby); } Servlet与HTTP请求协议
-
-