Day08—Http协议概述、Request

导读:本篇文章讲解 Day08—Http协议概述、Request,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

一、今日内容

1. Http协议概述
2. Request

二、Http、Request

1. Http协议概述
* 概念:Hyper Text Transfer Protocol 超文本传输协议
	* 传输协议:定义了客户端与服务器端通信时,发送数据的格式
	* 特点:
		1. 基于TCP/IP的高级协议
		2. 默认端口号: 80
		3. 基于请求/响应模型:一次请求对应一次响应
		4. 无状态的:每次请求之间是相互独立的,不进行数据交流
	* 历史版本:
		1. 1.0:每次请求并相应完毕后都会断开,下次建立新的连接
		2. 1.1:复用连接(短时间内复用)
* 请求消息数据格式:
	1. 请求行
		* 格式:
			请求方式 请求url 请求协议/版本
			GET /login.html http/1.1
			
			* 请求方式:
				* HTTP协议有7中请求方式,常用的有2种
					* GET:
						1. 请求参数在请求行中,在url后。
						2. 请求的url长度有限制的
						3. 不太安全
					* POST:
						1. 请求参数在请求体中
						2. 请求的url长度没有限制的
						3. 相对安全
	2. 请求头:客户端浏览器告诉服务器一些信息
		* 格式:键值对形式
			请求头名称: 请求头值
		* 常见的请求头:
			1. User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息
				* 可以在服务器端获取该头的信息,解决浏览器的兼容性问题
			2. Referer:http://localhost/login.html
				* 告诉服务器,我(当前请求)从哪里来?
					* 作用:
						1. 防盗链
						2. 统计工作
	3. 请求空行
		* 空行,就是用于分割POST请求的请求头,和请求体的。
	4. 请求体
		* 封装POST请求消息的请求参数的
			* setCharacterEncoding()只是对请求体有效,所以只是对post请求有效,对get请求无效

	eg:一个字符串形式的请求信息:
		POST /login.html	HTTP/1.1
		Host: localhost
		User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
		Accept: text/html,application/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
		Referer: http://localhost/login.html
		Connection: keep-alive
		Upgrade-Insecure-Requests: 1
		
		username=zhangsan	

防盗链示意图:
在这里插入图片描述

2. Request

(1)request对象和response对象的原理

1. request和response对象是由服务器创建的。我们来使用它们
2. request对象是来获取请求消息,response对象是来设置响应消息

在这里插入图片描述
(2)request对象继承体系结构

ServletRequest		--	接口
		|	继承
HttpServletRequest	-- 接口
		|	实现
org.apache.catalina.connector.RequestFacade 类(tomcat)

继承于HttpServlet抽象类的servlet类重写的doPost/doGet方法参数有 HttpServletRequest req,其中reqorg.apache.catalina.connector.RequestFacade类的实例化对象。

(3)request功能

1. 获取请求消息数据
	1. 获取请求行数据
		* GET /day14/demo1?name=zhangsan HTTP/1.1
		* 方法:
			1. 获取请求方式 :GET
				* String getMethod()  
			2. (*)获取项目的虚拟目录:/day14
				* String getContextPath()
			3. 获取Servlet虚拟路径: /demo1
				* String getServletPath()
			4. 获取get方式请求参数:name=zhangsan
				* String getQueryString()
			5. (*)获取请求URI:/day14/demo1
				* String getRequestURI():		/day14/demo1
				* StringBuffer getRequestURL()  :http://localhost/day14/demo1

				* URL:统一资源定位符 : http://localhost/day14/demo1	中华人民共和国
				* URI:统一资源标识符 : /day14/demo1					共和国
				* 注意:URI的范围比URL的范围大
			6. 获取协议及版本:HTTP/1.1
				* String getProtocol()
			7. 获取客户机的IP地址:
				* String getRemoteAddr()
	2. 获取请求头数据
		* 方法:
			* (*)String getHeader(String name):通过请求头的名称获取请求头的值
			* Enumeration<String> getHeaderNames():获取所有的请求头名称
				* 举例:
					Enumeration<String> headerNames = request.getHeaderNames();
			        if (headerNames.hasMoreElements()) {
			            String name = headerNames.nextElement();
			            String value = request.getHeader(name);
			            System.out.println(name + "--" + value);
			        }
	3. 获取请求体数据:
		* 请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
		* 步骤:
			1. 获取流对象
				*  BufferedReader getReader():获取字符输入流,只能操作字符数据
				*  ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据
			2. 再从流对象中拿数据
			* 举例
			 	//1.获取流对象
			    BufferedReader reader = request.getReader();
			    //2.读取请求体中的数据
			    String line = null;
			    while ((line = reader.readLine()) != null) {
			        System.out.println(line);
			    }

2. 其他功能:
	1. 获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法来获取请求参数
		1. String getParameter(String name):根据参数名称获取参数值    username=zs&password=123
		2. String[] getParameterValues(String name):根据参数名称获取参数值的数组  hobby=xx&hobby=game
		3. Enumeration<String> getParameterNames():获取所有请求的参数名称
		4. Map<String,String[]> getParameterMap():获取所有参数的map集合
		* 举例:
			Map<String, String[]> parameterMap = request.getParameterMap();
	        Set<String> keys = parameterMap.keySet();
	        for (String key : keys) {
	            System.out.println(key);
	            String[] values = parameterMap.get(key);
	            for (String value : values) {
	                System.out.println(value);
	            }
	            System.out.println("-----");
	        }

		* 中文乱码问题:
			* get方式:tomcat 8 已经将get方式乱码问题解决了
			* post方式:会乱码
				* 解决:在获取参数前,设置request的编码request.setCharacterEncoding("utf-8");
	
			
	2. 请求转发:一种在服务器内部的资源跳转方式
		1. 步骤:
			1. 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
			2. 使用RequestDispatcher对象来进行转发:forward(ServletRequest request, ServletResponse response) 

		2. 特点:
			1. 浏览器地址栏路径不发生变化
			2. 只能转发到当前服务器内部资源中。
			3. 转发是一次请求


	3. 共享数据:
		* 域对象:一个有作用范围的对象,可以在范围内共享数据
		* request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
		* 方法:
			1. void setAttribute(String name,Object obj):存储数据
			2. Object getAttitude(String name):通过键获取值
			3. void removeAttribute(String name):通过键移除键值对

	4. 获取ServletContext:
		* ServletContext getServletContext()

(4)知识补充

1. form表单的action路径的写法
	* 虚拟目录+Servlet的资源路径
2. BeanUtils工具类,简化数据封装
	* 用于封装JavaBean的
		1. JavaBean:标准的Java类
			1. 要求:
				1. 类必须被public修饰
				2. 必须提供空参的构造器
				3. 成员变量必须使用private修饰
				4. 提供公共setter和getter方法 ---因为设置属性的时候调用的getter和setter方法设置的
			2. 功能:封装数据
		2. 概念:
			成员变量
			属性:setter和getter方法截取后的产物
				例如:getUsername() --> Username--> username
								|								|						|
							去掉get				首字符小写			类的属性
				* 注意:成员变量和类的属性绝大多数情况下是相同的,因为getter/setter的名字可以更改,会造成成员变量和类的属性可能不一样的情况
		3. 方法:
			1. setProperty(JavaBean对象, 属性名, 属性值)	---调用的是属性对应的setter方法
			2. getProperty(JavaBean对象, 属性名)		---调用的是属性对应的getter方法
			3. populate(Object obj , Map map):将map集合的键值对信息,封装到对应的JavaBean对象中
3. 案例

实现一个登入界面的功能:
servlet层代码如下:

@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.设置编码
        request.setCharacterEncoding("utf-8");
        //2.获取所有请求参数及参数值
        Map<String, String[]> parameterMap = request.getParameterMap();
        //3.建立用户对象
        User loginUser = new User();
        System.out.println(loginUser.toString());
        //4.将参数封装到用户对象中
        try {
            BeanUtils.populate(loginUser, parameterMap);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        //5.用户登入
        UserDao userDao = new UserDao();
        User user = userDao.select(loginUser);
        System.out.println(user.toString());
        //6.登入是否成功
        if (user == null) {
            System.out.println("登入失败!");
        } else {
            System.out.println("登入成功!");
        }
    }
}

注意:如果使用BeanUtils来封装对象,一定注意传入的参数名称一定要和对象的成员变量名一致!!!

在这里插入图片描述
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/84698.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!