赞
踩
好记性不如烂笔头,记录学习的过程和内容,望与君共勉!
1、概述:Hyper Text Transfer Protocol 超文本传输协议,定义了客户端和服务器端通信时发送数据的格式。
2、特点:
① 基于 TCP/IP 的高级协议
② 默认端口号为 80
③ 基于请求/响应模型的:一次请求对应一次响应
④ 无状态的:每次请求之间相互独立,不能交互数据
3、请求消息的数据格式:
① 请求行:
格式→请求方式 请求url 请求协议/版本
请求方式:HTTP 协议有 7 种请求方式,常用的有 2 种,GET 和 POST。
GET:请求参数在请求行中,在 url 后,请求的 url 长度是有限制的。
POST:请求参数在请求体中,请求的 url 长度是没有限制的。
② 请求头:
客户端浏览器告诉服务器的一些信息
格式→请求头名称 : 请求头值
常见请求头:
1、User-Agent:浏览器告诉服务器,浏览器的版本信息。可以在服务器端获取该头的信息,解决浏览器的兼容性问题。
2、Accept:告诉服务器浏览器可以解析的响应的格式。
3、Referer:告诉服务器,当前请求从哪里来。
③ 请求空行:
一个空行,分割 POST请求 的请求头和请求体
④ 请求体(正文):
如果是 GET 方式的请求,没有请求体;如果是 POST 方式请求,实际上就是封装 POST 请求的一些请求参数。如 username=zhangsan
ServletRequest 是一个接口,HttpServletRequest 是 ServletRequest 的子接口,RequestFacade类实现了 HttpServletRequest 接口,由 tomcat 创建该类的对象。
1、获取请求消息
① 获取请求行数据
获取请求方式:String getMethod()
获取虚拟目录:String getContextPath()
获取 Servlet 路径:String getServletPath()
获取 get 方式请求参数:String getQueryPath()
获取请求 URL:getRequestURI()
和 StringBuffer getRequestURL()
获取协议及版本:String getProtocol()
获取客户机的 IP 地址:String getRemoteAddr()
@WebServlet("/ServletDemo5") public class ServletDemo5 extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1 获取请求方式 String method = req.getMethod(); System.out.println(method); // 2 获取虚拟目录 String contextPath = req.getContextPath(); System.out.println(contextPath); // 3 获取 Servlet 路径 String path = req.getServletPath(); System.out.println(path); // 4 获取 get 方式请求参数 String queryString = req.getQueryString(); System.out.println(queryString); // 5 获取请求 URL String URI = req.getRequestURI(); System.out.println(URI); StringBuffer URL = req.getRequestURL(); System.out.println(URL); // 6 获取协议及版本 String protocol = req.getProtocol(); System.out.println(protocol); // 7 获取客户机的 IP 地址 String addr = req.getRemoteAddr(); System.out.println(addr); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } }
注:
URL:统一资源定位符 http://localhost:8080/xnlj/ServletDemo5
URI:统一资源标识符 /day15/ServletDemo5
② 获取请求头数据
String getHeader(String name)
:通过请求头的名称获取请求头的值
Enumeration<String> getHeaderNames()
:获取所有的请求头名称
@WebServlet("/RequestDemo1") public class RequestDemo1 extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取请求头 String agent = req.getHeader("User-Agent"); if (agent.contains("Chrome")) { System.out.println("google Chrome"); } else if (agent.contains("Firefox")) { System.out.println("Firefox"); } else { System.out.println("others"); } // 获取所有的头信息 Enumeration<String> headerNames = req.getHeaderNames(); while (headerNames.hasMoreElements()) { String name = headerNames.nextElement(); // 根据名称获取请求头的值 String value = req.getHeader(name); System.out.println(name + ":" + value); } // 获取referer信息 String referer = req.getHeader("referer"); System.out.println(referer); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } }
③ 获取请求体数据
只有 POST 请求方式才有请求体,在请求体中封装了 POST 请求的请求参数。
步骤:
a:获取流对象
BufferedReader getReader()
:获取字符输入流,只能操作字符数据
ServletInputStream getInputStream()
:获取字节输入流,可以
b:再从流对象中拿数据
写一个登录页面,以 post 方式提交表单:
<body>
<form action="/day15/RequestDemo2" method="post">
<input type="text" placeholder="请输入用户名" name="username">
<input type="text" placeholder="请输入密码" name="pwd">
<button type="submit">登录</button>
</form>
</body>
Java 代码:
@WebServlet("/RequestDemo2") public class RequestDemo2 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取请求消息体 // 1 获取流对象 BufferedReader br = request.getReader(); // 2 从流对象中拿数据 String line = null; while ((line = br.readLine()) != null) { System.out.println(line); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
访问上面的登录页面,输入用户名和密码之后提交表单,可以看到在控制台打印出 username=zhangsan&pwd=123 的信息
2、其他功能
① 获取请求参数通用方式(GET 和 POST 请求方式都可用)
String getParameter(String name)
:根据参数名称获取参数值
String[] getParameterValues(String name)
:根据参数名称获取参数值的数组(通常用来获取复选框的参数值)
Enumeration<String> getParameterNames()
:获取所有请求的参数名称
Map<String, String[]> getParameterMap()
:获取所有参数的 map 集合
页面代码:
<body>
<form action="/day15/RequestDemo3" method="post">
<input type="text" placeholder="请输入用户名" name="username"><br>
<input type="text" placeholder="请输入密码" name="pwd"><br>
<input type="checkbox" name="hobby" value="study">学习
<input type="checkbox" name="hobby" value="play">游戏
<br>
<button type="submit">提交</button>
</form>
</body>
Java 代码:
@WebServlet("/RequestDemo3") public class RequestDemo3 extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取请求参数 String username = req.getParameter("username"); System.out.println(username); System.out.println("---------------------------------"); // 根据参数名称获取参数值的数组 String[] hobbies = req.getParameterValues("hobby"); for (String hobby : hobbies) { System.out.println(hobby); } System.out.println("---------------------------------"); // 获取所有请求的参数名称 Enumeration<String> enumeration = req.getParameterNames(); while (enumeration.hasMoreElements()) { String name = enumeration.nextElement(); System.out.println(name); String value = req.getParameter(name); System.out.println(value); } System.out.println("---------------------------------"); // 获取所有参数的 map 集合 Map<String, String[]> map = req.getParameterMap(); Set<String> set = map.keySet(); for (String name : set) { System.out.println(name); // 根据键获取值 String[] values = map.get(name); for (String value : values) { System.out.println(value); } } } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } }
中文乱码问题:
tomcat 8 已经将 get 方式的乱码问题解决了
而 post 方式如果输入中文或非法问题就会出现乱码问题,为了解决该问题,我们需要在获取参数之前,设置 request 的编码:
request.setCharacterEncoding("utf-8");
② 请求转发
一种在 服务器内部 的资源跳转方式。
步骤:
a:通过 request 对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
b:使用 RequestDispatcher 对象进行转发:forward(ServletRequest request, ServletResponse response)
特点:
a:浏览器地址栏路径不发生变化
b:只能转发到当前服务器内部资源中
c:转发是一次请求
@WebServlet("/RequestDemo4") public class RequestDemo4 extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("RequestDemo4 被访问了~~~"); // 转发资源到 RequestDemo5 req.getRequestDispatcher("/RequestDemo5").forward(req, resp); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } } @WebServlet("/RequestDemo5") public class RequestDemo5 extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("RequestDemo5 被访问了~~~"); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } }
创建两个 Servlet 对象,当通过浏览器访问 RequestDemo4 这个资源时,会在控制台打印出
RequestDemo4 被访问了~~~
和RequestDemo5 被访问了~~~
这两句话,也就是浏览器通过一次请求间接的访问了两个资源。
③ 共享数据
域对象:一个有作用范围的对象,可以在范围内共享数据
request 域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
方法:
a:void setAttribute(String name, Object obj)
:存储数据
b:Object getAttitude(String name)
:通过键获取值
c:void removeAttribute(String name)
:通过键移除键值对
@WebServlet("/RequestDemo4") public class RequestDemo4 extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("RequestDemo4 被访问了~~~"); // 存储数据到 request 域中 req.setAttribute("name", "zhangsan"); // 转发资源到 RequestDemo5 req.getRequestDispatcher("/RequestDemo5").forward(req, resp); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } } @WebServlet("/RequestDemo5") public class RequestDemo5 extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Object obj = req.getAttribute("name"); System.out.println(obj); System.out.println("RequestDemo5 被访问了~~~"); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } }
④ 获取 ServletContext
ServletContext getServletContext()
@WebServlet("/RequestDemo6")
public class RequestDemo6 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = req.getServletContext();
System.out.println(context); // org.apache.catalina.core.ApplicationContextFacade@51f99c81
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
}
我是快斗,请多多指教!下篇不见不散!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。