• 07http基础


    1.http协议

    1.1 概念

    是对浏览器和服务器端数据传输格式的规范!

    1.2 http协议内容

    请求

    GET /bbs/hello HTTP/1.1 # 请求行
    Host: localhost:8080 # 请求头
    Connection: keep-alive
    Pragma: no-cache
    Cache-Control: no-cache
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9
    Cookie: Pycharm-bdfc5fce=39c67252-c198-4d9b-bafc-ce7c50022791

    响应

    Content-Length: 46
    Content-Type: text/html;charset=utf-8
    Date: Mon, 08 Jul 2019 08:01:07 GMT

    2.1 请求行

    GET /day08/first HTTP/1.1

    http协议版本:

    http1.0: 当浏览器和服务器连接之后,在一次连接中只能发出一个请求

    http1.1:当浏览器和服务器连接之后,在一次连接中可以发出多次请求。(效率比1.0更高)

    常见问题:

    在一个html页面,在页面上有三张图片,访问这个html页面,问一共发出几次请求?

    答案:4次

    请求资源:请求服务器的哪个资源文件

    /day08/first : URI: 统一资源描述符。可以描述任何文件,本地,互联网                                           

    http://localhsot:8080/day08/first:URL : 统一资源定位符,互联网(基于http协议) ,是URI的子集。                                                        

    请求方式(提交方式):

    http协议中的请求方式:GET、POST、HEAD、PUT、CONNECT。。。。   

    最常用的的请求方式: GET  和 POST

    <form action="提交的地址" method="get/post">

                                                              

    </form>

     GET:

    1)提交的参数显示到地址栏

     原理: get方式提交的参数会跟在请求行内容的URI后面。以?开始,每个参数使用=号分开,name=jacky,第二个参数之后使用&符合连接

    GET /day08/testMethod.html?name=jacky&password=123456 HTTP/1.1
    Host: localhost:8080
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-GB,en-US;q=0.8,zh-CN;q=0.6,zh;q=0.4,en;q=0.2
    Accept-Encoding: gzip, deflate
    Referer: http://localhost:8080/day08/testMethod.html
    Connection: keep-alive

    2)不适合存放敏感数据

    3)不超过1kb

                               

    POST:

    1)提交的参数不会显示到地址栏      

    原理:post提交的参数跟在请求的实体内容中。第二个参数用&连接

    POST /day08/testMethod.html HTTP/1.1
    Host: localhost:8080
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-GB,en-US;q=0.8,zh-CN;q=0.6,zh;q=0.4,en;q=0.2
    Accept-Encoding: gzip, deflate
    Referer: http://localhost:8080/day08/testMethod.html
    Connection: keep-alive
    
    name=jacky&password=123456    -实体内容

    2)适合敏感数据

    3)提交的大小没有限制

    2.2 请求头

    Accept: text/html,image/*     --浏览器接受的数据类型
    Accept-Charset: ISO-8859-1     --浏览器接受数据编码格式
    Accept-Encoding: gzip,compress    --浏览器接受的数据压缩格式
    Accept-Language: en-us,zh-       ---浏览器接受的语言  
    Host: www.it315.org:80           --请求发出的主机和端口(必须)
    If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT   --浏览器缓存的最后修改时间
    Referer: http://www.it315.org/index.jsp   -- 当前请求来自于哪里 (防止非法链接)
    User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)   --浏览器的类型
    Cookie:name=eric                 ---浏览器保存的cookie数据
    Connection: close/Keep-Alive       ---浏览器和服务器的连接状态。close:关闭。keep-alive:保持连接
    Date: Tue, 11 Jul 2000 18:23:51 GMT  --请求发出的时间
    package cn.jxufe.b_servlet;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.PrintWriter;
    import java.util.Enumeration;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 使用HttpServletRequest获取请求的信息
     * 
     * @author Administrator
     *
     */
    /**
     * 使用HttpServletRequest获取请求信息
     * @author APPle
     *   HttpServletRequest对象:获取请求数据
     *       请求行:
     *           请求方式: request.getMethod()
     *           请求资源: request.getRequestURI() /  request.getRequestURL()
     *             http协议版本: request.getProtocol();
     *         请求头
     *             request.getHeader("name") 
     *             request.getHeaderNames()
     *         实体内容:
     *             request.getInputStream();
     */
    public class RequestDemo1 extends HttpServlet {
    
        // 1)tomcat服务器接收到浏览器发送的请求数据
        // 2)tomcat服务器把请求数据封装成HttpServletRequest对象
        // 3)tomcat服务器调用doGet方法,把request对象传入servlet
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // 4)通过request对象获取请求数据
            t1(request);
            t2(request);
        }
    
        // doPost接受post提交的请求
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {
    
            t3(request);
        }
    
        private void t3(HttpServletRequest request) throws IOException {
            System.out.println("t3--------------------");
            // 4.3 实体内容
            // 注意: post提交的参数才会出现在实体内容中
            InputStream in = request.getInputStream();
            byte[] buf = new byte[1024];
            int len = 0;
            while ((len = in.read(buf)) != -1) {
                String str = new String(buf, 0, len);
                System.out.print(str);
            }
        }
    
        private void t1(HttpServletRequest request) {
            // 4.1 请求行
            // 请求方式
            System.out.println("t1----------------");
            System.out.println("请求方式:" + request.getMethod());
            // 请求资源
            System.out.println("URI:" + request.getRequestURI());
            System.out.println("URL:" + request.getRequestURL());
            // http协议版本
            System.out.println("Http协议:" + request.getProtocol());
        }
    
        private void t2(HttpServletRequest request) {
            System.out.println("t2--------------------");
            // 4.2 请求头
            String value = request.getHeader("host");// 根据头名称获取头值
            System.out.println("host:" + value);
            System.out.println("========================================");
            // 遍历所有头
            Enumeration<String> enums = request.getHeaderNames();// 获取所有头名称
            while (enums.hasMoreElements()) {
                String headerName = enums.nextElement();
                String headerValue = request.getHeader(headerName);
                System.out.println(headerName + ":" + headerValue);
            }
        }
    }

    2.3 案例- user-agent头 -- 获取浏览器类型

    package cn.jxufe.b_servlet;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /*
     *  案例【user-agent】 浏览器类型
     */
    public class RequestDemo3 extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("text/html;charset=utf-8");
    
            String userAgent = request.getHeader("user-agent");
            // System.out.println(userAgent);
    
            if (userAgent.contains("Firefox")) {
                response.getWriter().write("你正在使用火狐浏览器");
            } else if (userAgent.contains("Chrome")) {
                response.getWriter().write("你正在使用谷歌浏览器");
            } else if (userAgent.contains("Trident")) {
                response.getWriter().write("你正在是IE浏览器");
            } else {
                response.getWriter().write("识别不了的浏览器");
            }
    
        }
    
    }

    2.4 案例- referer头  --- 防止非法链接

    第一次:下载资源 - > 下载页面 -> 打开广告页面(下载链接) -> 开始下载

     第二次:直接点击下载链接 -> 跳转广告页面(下载链接)  ->   开始下载

    非法请求:

    1)直接访问下载资源

    2)不是从广告页面过来的请求

     referer请求头只有从超链接过来的请求才有这个头

    package cn.jxufe.b_servlet;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class RequestDemo4 extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("text/html;charset=utf-8");
            /**
             * 代表下载资源文件
             * referer: 表示当前请求来自于哪里
             */
            String referer = request.getHeader("referer");
            System.out.println("referer=" + referer);
    
            /**
             * 判断非法请求(链接)
             *         1)直接访问  (referer==null)
             *      2)当前请求不是来自于广告页面  (  !referer.contains("adv.html")  )
             */
            if (referer == null || !referer.contains("/adv.html")) {
                response.getWriter().write("你当前请求是非法请求,请转到首页。<a href='/bbs/adv.html'>首页</a>");
            } else {
                response.getWriter().write("资源正在下载.....");
            }
        }
    
    }

    2.5 获取参数数据

    get:  放在请求行的URI后面

    post: 放在请求的实体内容

                               

    reuqest.getParameter("name")  获取一个值的参数

    request.getParameterValue("name")  获取多个值的参数

    request.getParameterNames() 获取所有参数名称

    request.getParameterMap()   获取所有参数对象

    package cn.jxufe.b_servlet;
    
    import java.io.IOException;
    import java.util.Collection;
    import java.util.Enumeration;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletInputStream;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /*
     * 案例【获取请求的参数数据】
     */
    public class RequestDemo5 extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            request.setCharacterEncoding("utf-8");
            /*
             * 获取get提交的参数.(URI后面的参数数据)
             */
            String params = request.getQueryString();
            System.out.println(params);
    
            /**
             * 问题:
             *     1)获取到的参数数据,还需要进一步处理,获取参数值
             *  2)两种提交方式的获取代码完全不一样的,不通用。
             */
    
            /**
             * 通用的获取参数的方法:(无论get和post可用)
             *         reuqest.getParameter("name")  获取一个值的参数
             *         request.getParameterValue("name")  获取多个值的参数
             *      request.getParameterNames() 获取所有参数名称
             *      request.getParameterMap()   获取所有参数对象
             */
    
            System.out.println("通过参数获取----------------------");
            String name = request.getParameter("name");
            System.out.println(name);
            String password = request.getParameter("password");
            System.out.println(password);
            System.out.println("遍历所有参数----------------------------");
            // 遍历所有的参数
            Enumeration<String> enums = request.getParameterNames();// 获取所有参数名称列表
            while (enums.hasMoreElements()) {
                String paramName = enums.nextElement();
                String paramValue = request.getParameter(paramName);
                System.out.println(paramName + "=" + paramValue);
            }
            System.out.println("获取参数对象列名(Map集合)------------------");
    
            Map<String, String[]> map = request.getParameterMap(); // 获取参数对象列名(Map集合)
    
            /**
             * 每个map的对象就是一个参数(包含参数名称和参数值)
             *     key: 参数名称
             *     value: 参数值(默认情况下都是多个值的参数)
             */
            /**
             * 复习Map集合
             *     问题: Map集合如何遍历?
             *     1)entrySet()
             *     2)keySet()
             *     3) values()         
             */
            // 1)entrySet()方法:获取键值对对象的Set集合
            // Entry对象中包含一个键对象,和一个值对象
            System.out.println("map方式1:");
            Set<Entry<String, String[]>> entrySet = map.entrySet();
            for (Entry<String, String[]> entry : entrySet) {
                // 获取键对象
                String key = entry.getKey();
                // 获取值对象(数组的第一个元素就是参数值)
                String[] value = entry.getValue();
                System.out.println(key + "=" + value[0]);
            }
    
            // 2)keySet(): 获取所有键对象的Set集合
            System.out.println("map方式2:");
    
            Set<String> keySet = map.keySet();
            for (String key : keySet) {
                // 通过键对象获取值对象
                String[] value = map.get(key);
                System.out.println(key + "=" + value[0]);
            }
    
            System.out.println("map方式3:");
            // 3)values(): 获取所有值对象的Collection集合(只能获取值对象,不能获取键对象)
            Collection<String[]> values = map.values();
            for (String[] value : values) {
                System.out.println(value[0]);
            }
            System.out.println("根据参数名称获取多个参数值:-----------");
            String[] hobits = request.getParameterValues("hobit"); // 根据参数名称获取多个参数值
            for (String h : hobits) {
                System.out.print(h + ",");
            }
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            /**
             * 获取post提交的参数(实体内容中) 
             */
            ServletInputStream in = request.getInputStream();
            byte[] buf = new byte[1024];
            int len = 0;
            while ((len = in.read(buf)) != -1) {
                String str = new String(buf, 0, len);
                System.out.print(str);
            }
            
            // 在doPost方法中调用doGet里面的逻辑代码
            doGet(request, response);
        }
    
    }

    3.Http响应

    3.1 响应行

    http协议版本

    状态码:当前服务器处理请求的状态(结果)

    常见的状态码:

    200     :  请求处理完成,成功返回!        

    02:       需要浏览器进一步请求,才能完成。

    404:      浏览器端的错误。没有找到资源。

    500:       服务器端的错误。

    状态描述:对状态码的文字补充        

    3.2 响应头

    Location: http://www.it315.org/index.jsp   --重定向的地址。结合302状态使用完成重定向的效果
    Server:apache tomcat    --服务器的类型
    Content-Encoding: gzip     --服务器发送给浏览器的数据压缩格式
    Content-Length: 80         --服务器发送给浏览器的数据长度
    Content-Language: zh-cn    --服务器支持语言
    Content-Type: text/html; charset=GB2312     --服务器发送给浏览器的数据类型和数据编码格式
    Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT    --服务器资源的最后修改时间
    Refresh: 1;url=http://www.it315.org        ---定时刷新或每隔n秒跳转资源
    Content-Disposition: attachment; filename=aaa.zip   -- 以下载方式打开资源
    Transfer-Encoding: chunked            
    Set-Cookie:SS=Q0=5Lb_nQ; path=/search     -- 服务器发送给浏览器的cookie数据
    Expires: -1            --通知浏览器不使用缓存
    Cache-Control: no-cache
    Pragma: no-cache   
    Connection: close/Keep-Alive    连接状态
    Date: Tue, 11 Jul 2000 18:23:51 GMT   响应发出的时间
    package cn.jxufe.c_servlet;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 使用HttpServletResponse修改响应数据
     *      response.setStatus(404) 设置状态码
     *      response.setHeader("name","value")  修改响应头
     *      response.getWriter().write()   以字符形式发送实体内容
     *      response.getOutputStream().write()  以字节形式发送实体内容
     *
     */
    public class ResponseDemo1 extends HttpServlet {
        // 1)tomcat服务器提供了一个HttpServletResponse对象,用于给开发者修改响应数据
        // 2)通过service方法把response对象传入servlet中
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // 3)通过response对象修改响应数据
            /**
             * 修改响应
             */
            // 3.1 响应行
            // 设置状态码
            System.out.println("nihao");
             response.setStatus(404);
            // response.sendError(404); // 404+404错误页面
    
            // 3.2 响应头
            response.setHeader("server", "webLogic");
    
            // 3.3 实体内容(在浏览器主题部分看到的内容)
            // response.getWriter().write("this is content!"); 字符流
            response.getOutputStream().write("this is content!!!".getBytes());  //字节流
    
        }
    
        // 4)tomcat服务器把response对象转换成响应格式的字符串,发送给浏览器
    
    }

    package cn.jxufe.c_servlet;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /*
     * 案例【location+302】请求重定向
     */
    public class ResponseDemo2 extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            /**
             * 请求重定向(  跳转到其他页面 )
             */
    //        //设置302状态码
    //        response.setStatus(302);
    //        //设置location响应头
    //        response.setHeader("location", "/bbs/adv.html");
    
            /**
             * 简化版本
             */
            response.sendRedirect("/bbs/adv.html");
        }
    
    }

    package cn.jxufe.c_servlet;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /*
     * 案例【refresh】--定时刷新或每隔n秒跳转页面
     */
    public class ResponseDemo3 extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("text/html;charset=utf-8");
    
            // 设置refresh响应头
            // 设置秒数
            // response.setHeader("refresh", "2");
    
            // 每隔n秒跳转页面
            response.getWriter().write("注册成功!3秒之后会跳转到主页");
            // 设置refresh
            response.setHeader("refresh", "3;/bbs/adv.html");
        }
    
    }

    package cn.jxufe.c_servlet;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /*
     * 案例【content-type】--服务器发送给浏览器的数据类型和数据编码格式
     */
    public class ResponseDemo4 extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // 设置content-type响应
            // response.setHeader("content-type", "text/html;charset=utf-8");
            // response.setContentType("text/html;charset=utf-8");//等价于上面的代码
            
            /**
             * 1)设置数据类型
             */
            // response.setContentType("text/html");//告诉浏览器以什么样的格式来解析实体内容
            // response.setContentType("image/jpg");//告诉浏览器以什么样的格式来解析实体内容
            /**
             * 注意: 一定要写服务器支持的数据类型,如果写了服务器不支持的类型,就会报错
             */
            
            /**
             * 2)设置数据编码格式
             */
            /**
             *    两个作用:
             *            1)设置输出数据的编码
             *          2)告诉浏览器自动适应输出数据的编码
             */
            response.setContentType("text/html;charset=gbk"); // 和下面的代码是效果是一样的。
            // response.setCharacterEncoding("utf-8"); //不会告诉浏览器自动跳转解码的码表
    
            response.getWriter().write("<html><head><title>this is tille</title></head><body>主题</body></html>");
    
        }
    
    }
    package cn.jxufe.c_servlet;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class ResponseDemo5 extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            File file = new File("e:/mm.jpg");
            /**
             * 告诉浏览器以下载的方法打开
             */
            response.setHeader("content-disposition", "attachment;filename=" + file.getName());
    
            /**
             * 文件下载
             */
            // 1)读取本地文件
            FileInputStream in = new FileInputStream(file);
    
            // 2)写出给浏览器(字节内容)
            OutputStream out = response.getOutputStream();
            byte[] buf = new byte[1024];
            int len = 0;
            // 边读边写
            while ((len = in.read(buf)) != -1) {
                out.write(buf, 0, len);
            }
    
            // 关闭
            in.close();
            out.close();
    
        }
    
    }
  • 相关阅读:
    Docker 相关资源
    ReferenceFinder 学习
    AssetBundle 复习
    Coroutine 复习
    Unreal 相关资源
    Houdini 相关资源
    MySQL多数据库合并到一个数据库
    Module is not specified
    idea导入多maven项目
    redis-cluster部署遇到为问题记录
  • 原文地址:https://www.cnblogs.com/xinmomoyan/p/11154079.html
Copyright © 2020-2023  润新知