HTTP笔记

1、概念: Hyper Text Transfer Protocol 超文本传输协议

传输协议:定义了客户端和服务器端通信时,发送数据的格式

2、特点:

基于TCP/ IP的高级协议
默认端口号: 80
基于请求/响应模型: 一次请求对应一次响应
无状态的:每次请求之间相互独立,不能交互数据

3、历史版本:

1.0:每一次请求响应都会建立新的连接
1.1:复用连接

3、请求消息数据格式:请求行,请求头,请求空行,请求体

(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请求消息的请求参数

4、request功能:

(1)获取请求消息数据:
	①获取请求行数据:例:GET /NO2_Servlet/demo1?name=zhangsan HTTP/1.1
		1)获取请求方式:GET
				String getMethod()
		2)获取虚拟目录:/NO2_Servlet
				String getContextPath()
		3)获取Servlet路径:/demo1
				String getServletPath()
		4)获取get方式请求参数:name=zhangsan
				String getQueryString()
		5)获取请求URI: /NO2_Servlet/demo1
			String getRequestURI():/NO2_Servlet/demo1
			StringBuffer getRequestURL():http://localhost/NO2_Servlet/demo1
		6)获取协议及版本:HTTP/1.1
			String getProtocol()
		7)获取客户端的IP地址:
			String getRemoteAddr()
	②获取请求头数据
		1)String getHeader(string name) :通过请求头的名称获取请求头的值
		2)Enumeration<string> getHeaderNames(): 获取所有的请求头名称

	③获取请求体数据
		先获取流对象:
			BufferedReader getReader() :获取字符输入流,只能操作字符
			数据	
			ServletInputstream getInputStream() :获取字节输入流,可以
			操作所有类型数据,再从流对象中拿数据

5、其他功能:

	(1)获取请求参数通用方式
		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集合
			中文乱码问题:
				get方式: tomcat8已经将get方式乱码问题解决了
				post方式:会乱码
			解决:在实现HttpServlet接口的类的doPost()方法中,获取参数前,
			设置request的编码request.setCharacterEncoding("utf-8");
			
	(2)请求转发:一种在服务器內部的资源跳转方式
		1.通过request对象获取请求转发器对象: RequestDispatcher getRequestDispatcher(String path)
		2.使用RequestDispatcher对象来进行转发: forward(ServletRequest request, ServletResponse response)
			例:
			request.getRequestDispatcher(“/requestDemo6”).forward(request,response);
			特点:
				1.浏览器地址栏路径不发生变化
				2.只能转发到当前服务器内部资源中。
				3.转发是一次请求
		
	(3)共享数据
		1)域对象:一个有作用范围的对象,可以在范围内共享数据
		2)request域:代表一次请求的范围,一般用于请求转发的多个资源中共享			
		数据(多个Servlet共享数据)
		3)方法:
			1. void setAttribute(String name ,Object obj): 存储数据(键值对形式)
			2. object getAttitude(String name) :通过键获取值
			3. void removeAttribute(String name) :通过键移除键值对
		
	(4)获取ServletContext
		ServletContext getServletContext()

6、BeanUtils.工具类,简化数据封装,用于封装JavaBean的

(1)JavaBean :标准的Java类
		1.类必须被public修饰
		2.必须提供空参的构造器
		3.成员变量必须使用private修饰
		4.提供公共setter和getter方法
(2)功能:封装数据
(3)方法:
		setProperty()
		getProperty()
		populate(Object obj,Map map):将map信息封装到obj对象中

7、成员变量和属性的区别:

成员变量:一个类里面的成员变量
属性: setter和getter方法截取后的产物

例如: getUsername() --> Username–> username
注意:一般情况下,成员变量和属性是一样的,但是也有特殊情况,如下:

public class test(){
	private String name;//这里name为成员变量
		/*从下面的getter和setter方法可以看出,属性为hehe,尽管它的指向
		是成员变量name,但是属性就是hehe*/
	public void setHehe(String name){	
		this.name = name;
	}
	public String getHehe(){
		return name;
	}
}

8、form表单的action属性为:虚拟路径(在Tomcat里面设置)+资源路径(如具体某个servlet)

9、响应消息:服务器端发送给客户端的数据

响应行,响应头,响应空行,响应体
(1)响应行:组成:协议/版本  响应状态码  状态码描述
		响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态。
		状态码都是3位数字
	——状态码分类:
		1xx :服务器就收客户端消息,但没有接受完成,等待一段时间后,发送1xx多状态码
		2xx:成功。代表:200
		3xx:重定向。代表: 302(重定向),304(访问缓存)
		4xx:客户端错误。
			* 404 (请求路径没有对应的资源)
			* 405 (请求方式没有对应的doxxx方法)
		5xx :服务器端错误。代表: 500(服务器内部出现异常)
(2)响应头: 组成:头名称:值
	常见的响应头:
		1. Content-Type :服务器告诉客户端本次响应体数据格式以及编码格式
		2. Content-disposition :服务器告诉客户端以什么格式打开响应体数据
			in-line:默认值,在当前页面内打开
			attachment;filename=xxx :以附件形式打开响应体。文件下载
(3)响应空行
(4)响应体:传输的数据

10、Response对象:设置响应消息

(1)设置响应行
			格式: HTTP/1.1 200 ok
			设置状态码: setStatus(int sc)
(2)设置响应头: setHeader(String name, string value)
(3)设置响应体:
		1.获取输出流
			*字符输出流: PrintWriter getWriter()
			*字节输出流: ServletOutputstream getOutputStream( )
		2.使用输出流,将数据输出到客户端浏览器
(4)重定向:资源跳转方式
		第一种:
			//1. 设置状态码为302
			response. setStatus(302);
			//2.设置响应头location
			response . setHeader("location" ,"/Response/ResponseServlet2");
		第二种:(推荐)
			//简单的重定向方法
			response.sendRedirect("/Response/ResponseServlet2");
(5)重定向和转发的区别:
		重定向的特点: redirect
			1.地址栏发生变化
			2.重定向可以访问其他站点(服务器)的资源
			3.重定向是两次请求。不能使用request对象来共享数据
		转发的特点: forward
			1.转发地址栏路径不变
			2.转发只能访问当前服务器下的资源
			3.转发是一次请求,可以使用request对象来共享数据

例子:

package 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("/ResponseServlet1")
public class ResponseServlet1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("ResponseServlet1........");
        //第一种重定向方法:
           /* //设置状态码
            response.setStatus(302);
            //设置响应头
            response.setHeader("location","/Response/ResponseServlet2");*/
        //第二种重定向方法:
            response.sendRedirect("/Response/ResponseServlet2");

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}


package 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("/ResponseServlet2")
public class ResponseServlet2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("ResponseServlet2.........");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}
(6)路径分类
1.相对路径:通过相对路径不可以确定唯一资源
	不以/开头,以.开头的路径
		如: ./index. html	
			规则:找到当前资源和目标资源之间的相对位置关系
			./:当前目录
			../:后退一级目录
2.绝对路径:通过绝对路径可以确定唯一资源
	以/开头的路径			
	如: http://localhost/Response/ResponseServlet2			
3.如何判断定义的路径是给谁用的?
	判断请求将来从哪儿发出
	给客户端浏览器使用:需要加虚拟目录(项目的访问路径)
		虚拟目录要动态获取: request . getContextpath()
		例:<a>链接点击,<form> 提交等的重定向...
	给服务器使用:不需要加虚拟目录
		例:转发(request.getRequestDispatcher(.......).forward(....))

例:

package 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("/ResponseServlet3")
public class ResponseServlet3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取虚拟目录
        String path = request.getContextPath();
        //重定向验证是否获取成功
        response.sendRedirect(path+"/ResponseServlet2");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}
(7)服务器输出字符数据到浏览器
		1.获取字符输出流
		2.输出数据

乱码问题:

//简单的形式,设置编码,是在获取流之前设置
response. setContentType("text/html ;charset=utf-8");

例:

package 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.io.PrintWriter;

/**
 * 服务器输出字符数据到浏览器
 */
@WebServlet("/ResponseServlet4")
public class ResponseServlet4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置编码方式,解决乱码问题
        response.setContentType("text/html;charset=utf-8");
        //获取字符输出流
        PrintWriter pw = response.getWriter();
        //输出(两个方法:write和print,前者没有自动刷新,后者有自动刷新)
        pw.print("你好啊哈哈哈,hey");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}
(8)服务器输出字节数据到浏览器
		1.获取字符输出流
		2.输出数据

例:

package servlet;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
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;

/**
 * 服务器输出字节数据到浏览器
 */
@WebServlet("/ResponseServlet5")
public class ResponseServlet5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置编码方式,解决乱码问题
        response.setContentType("text/html;charset=utf-8");
        //获取字节输出流
        ServletOutputStream outputStream = response.getOutputStream();
        //输出
        outputStream.write("很高兴能够遇见你~like".getBytes("utf-8"));
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}
(9)验证码案例

11、ServletContext对象:

1.概念:代表整个web应用,可以和程序的容器(服务器)来通信
2.获取:
	1.通过request对象获取:request. getServletContext();
	2.通过HttpServlet获取:this. getServletContext();
3.功能:
	1.获取MIME类型:
		MIME类型:在互联网通信过程中定义的一种文件数据类型
			格式:大类型/小类型 如:text/ html,image/ jpeg等等
		获取: String getMimeType(String file)
	2.域对象:共享数据(所有用户所有请求都可以获取到该域中的数据)
		 setAttribute(string name ,object value)
	 	 getAttribute(String name )
	     removeAttribute(String name)	
	3.获取文件的真实(服务器中的)路径
		getRealPath(路径)

例:

package servlet;

import javax.servlet.ServletContext;
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;

/**
 *ServletContext功能实现
 */
@WebServlet("/ServletContext2")
public class ServletContext2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1、获取MIME类型
            //获取ServletContext对象
            ServletContext servletContext = this.getServletContext();
            //自定义一个文件名
            String filename = "a.jpg";
            //获取MIME类型
            String mimeType = servletContext.getMimeType(filename);
            System.out.println(mimeType);
        //2、域对象:共享数据(所有用户所有请求都可以获取到该域中的数据)
            servletContext.setAttribute("ohh","123");
        //3、获取文件的真实路径(服务器中的文件路径)
            String a = servletContext.getRealPath("/WEB-INF/classes/a.txt");//src下的文件
            String b = servletContext.getRealPath("/b.txt");//web目录下的文件
            String c = servletContext.getRealPath("/WEB-INF/c.txt");//web目录下的WEB-INF下的文件
            System.out.println(a);
            System.out.println(b);
            System.out.println(c);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}
4.文件下载案例:

html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <a href="/Response/DownloadServlet?filename=OIP-C.jpg">下载图片</a>
    <a href="/Response/DownloadServlet?filename=下载.mp4">下载视频</a>
</body>
</html>

工具类(对各个浏览器的兼容,解决中文文件乱码问题)

package Download;

import sun.misc.BASE64Encoder;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
public class DownLoadUtils {
    public static String getFileName(String agent, String filename) throws UnsupportedEncodingException {
        if (agent.contains("MSIE")) {
            // IE浏览器
            filename = URLEncoder.encode(filename, "utf-8");
            filename = filename.replace("+", " ");
        } else if (agent.contains("Firefox")) {
            //火狐浏览器
            BASE64Encoder base64Encoder = new BASE64Encoder();
            filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
        } else {
            //其它浏览器
            filename = URLEncoder.encode(filename,"utf-8");
        }
        return filename;
    }
}

Servlet类

package Download;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;

@WebServlet("/DownloadServlet")
public class DownloadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1、获取请求参数名
        String filename = request.getParameter("filename");
        ServletContext servletContext = this.getServletContext();
        //2、找到文件服务器路径
        String realPath = servletContext.getRealPath("/img/" + filename);
        //3、字节流关联
        FileInputStream fileInputStream = new FileInputStream(realPath);
        //4、解决中文文件名乱码问题(使用工具类)
        String header = request.getHeader("user-agent");
        filename = DownLoadUtils.getFileName(header,filename);
        //5、设置响应头
        String mimeType = servletContext.getMimeType(filename);
        response.setHeader("content-type",mimeType);
        response.setHeader("content-disposition","attachment;filename="+filename);
        //6、输入流的数据,写到输出流中
        ServletOutputStream outputStream = response.getOutputStream();
        byte[] bytes = new byte[1024 * 8];
        int len = 0;
        while((len = fileInputStream.read(bytes)) != -1){
            outputStream.write(bytes,0,len);
        }
        fileInputStream.close();
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值