菜鸟学JavaWeb之——HTTP、Request、Response、ServletContent

三、HTTP(超文本传输协议)

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

特点:

  • 基于TCP/IP的高级协议

  • 默认端口号:80

  • 基于请求/响应模型的:一次请求对应一次响应

  • 无状态的:每次请求之间相互独立,不能交互数据

3.1 请求消息响应

数据格式:请求行、请求头、请求空行、请求体

3.1.1 请求行

​ 请求方式 / 请求rul / 请求协议、版本

​ GET / login.html / HTTP、1.0

请求方式

HTTP协议有7种请求方式,常用的有两种

  • GET
    • 请求参数在请求行中,在url后
    • 请求的url长度有限制的
    • 不太安全
  • POST
    • 请求参数在请求体中
    • 请求的url长度没有限制的
    • 相对安全

3.1.2 请求头

格式:

​ 请求头名称:请求头值

常见的请求头:客户端浏览器告诉服务器一些信息

  • User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息

    可以在服务器端获取该头的信息,解决浏览器的兼容性问题

     @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          
          
            String agent = req.getHeader("user-agent");
            if(agent.contains("Chrome")) {
          
          
                System.out.println("我是谷歌");
            } else if(agent.contains("Firefox")) {
          
          
                System.out.println("我是火狐");
            }
        }
    
  • Refere:告诉服务器,我(当前请求)从哪里来?

    • 作用:防盗链

      @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              
              
              String referer = req.getHeader("referer");
              System.out.println(referer);  //http://localhost:8080/myweb/login.html
      
              //防盗链
              if(referer != null) {
              
              
                  if(referer.contains("/myweb")) {
              
              
                      System.out.println("正常访问,播放电影");
                  } else {
              
              //如果通过其他项目访问就是非法的
                      //盗链
                      System.out.println("非法访问,想开电影请去爱奇艺");
                  }
              }
          }
      
    • ​ 统计工作

3.1.3 请求空行

空行,就是用于分割POST请求的请求头,和请求体的。

3.1.4 请求体(正文)

作用:封装POST请求消息的请求参数的

GET方式没有请求体,POST方式才有

请求体就是form表单提交的数据

3.2 响应消息数据格式

数据格式:响应行、响应头、响应空行、响应体

3.2.1 响应行

组成:协议/版本 响应状态码 状态码描述

响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态

  • 状态码都是3位数字

    分类

    • 1XX:客户端服务器接受客户端消息,但是没有接受完成,等待一段时间后,发送1XX状态码

    • 2XX:成功。代表:200

    • 3XX:重定向。代表:302(重定向)、304(访问缓存)

      • 重定向
        在这里插入图片描述
        代码实现:

        @WebServlet("/responseDemo1")
        public class ResponseDemo1 extends HttpServlet {
                  
                  
            protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                  
                  
                System.out.println("demo1...");
                //重定向
                response.sendRedirect("/myweb/responseDemo2");
            }
        
            protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                  
                  
                this.doPost(request,response);
            }
        }
        
        ---------------------------------------------------------------------------
        
        @WebServlet("/responseDemo2")
        public class ResponseDemo2 extends HttpServlet {
                  
                  
            protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                  
                  
                System.out.println("demo2...");
            }
        
            protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                  
                  
                this.doPost(request,response);
            }
        }
        ---------------------------------------------------------------------------
        
        访问/myweb/responseDemo1,控制台输出:demo1...    demo2...
        
        • 特点

          • 地址栏发生变化

          • 重定向可以访问其他站点(服务器)的资源

          • 重定向是两次请求。不能使用request对象来共享数据

      • 访问缓存

    • 4XX:客户端错误。代表:

      • 404:请求路径没有对应的资源(URL不对)
      • 405:请求方式没有对应的doXxx方法
    • 5XX:服务器错误。代表:500(服务器内部出现异常)

3.2.2 响应头

格式:头名称:值

常见的响应头:

  • Conten-Type:服务器告诉客户端本次响应体数据格式,以及编码格式。(text/html:表示响应体是文本内容并且是html内容)

  • Content-disposition:服务器告诉客户端以什么格式打开响应体数据

    • in-line:默认值,在当前页面内打开
    • attachment:以附件形式打开响应体。比如:文件下载

3.2.3 响应空行

3.2.4 响应体

即:传输的数据

四、Request

4.1 Request和Response对象的原理:

  • Request和Response对象是由服务器创建的。我们来使用他们
  • Request对象是来获取请求消息,Response对象是来设置响应消息

在这里插入图片描述
Request对象继承体系结构

ServletRequest ------ 接口

HttpServletRequest ------ 接口(继承ServletRequest)

org.apache.catalina.connnector.RequestFacade —— 类(Tocat编写的,实现HttpServletRequest )

4.2 Request功能

4.2.1 获取请求消息数据

4.2.1.1 获取请求行数据
  • GET/myweb/demo.do?name=zhangsan HTTP/1.1

    • 获取请求方式:GET

      String getMethod()

    • 获取虚拟目录:/myweb

      String getContextPath()

    • 获取Servlet路径:/demo.do

      String getServletPath()

    • 获取get方式请求参数:name=zhangsan

      String getQueryString()

    • 获取请求URI:/myweb/demo.do

      String getRequestURI() /myweb/demo.do

      StringBuffer getRequestURL() http://localhost/myweb/demo.do

      • URL:统一资源定位符:http://localhost/myweb/demo.do 中华人民共和国
      • URI(表示的范围大):统一资源标识符:/myweb/demo.do 共和国
    • 获取客户机的IP地址

      String getRemoteAddr()

4.2.1.2 获取请求头数据

方法:

  • String getHeader(String name):通过请求头的名称获取请求头的值
  • Enumeration<String> getHeaderNames():获取所有请求头名称(返回值就类似于一个迭代器)
Enumeration<String> headerNames = req.getHeaderNames();
        while (headerNames.hasMoreElements()) {
    
    
            System.out.println(headerNames.nextElement() +":"+req.getHeader(headerNames.nextElement()));
        }
4.2.1.3 获取请求体数据

只有POST请求方式才有请求体,在请求体中封装了POST请求的请求参数

步骤:

  • 获取流对象(这个流对象是Tomcat给返回的)
    • BufferedReader getReader():获取字符输入流,只能操作字符数据
    • ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据(文件上传)

4.2.2 其他功能

4.2.2.1 获取请求参数通用方式
  • String getParameter(String name):根据参数名称获取参数值
  • String[] getParameterValues(String name):根据参数名称获取参数值的数组(用于复选框,hobby=study&hobby=game)
  • Enumeration<String> getParameterNames():获取所有请求的参数名称
  • Map<String, String[]> getParameterMap():获取所有参数的map集合

中文乱码问题:

  • get方式:Tomcat8已经将get方式乱码问题解决了
  • post方式会乱码
    • 解决:在获取参数前,设置request的编码request.setCharacterEncoding("utf-8");
4.2.2.2 请求转发:一种在服务器内部的资源跳转方式(还有一种是重定向,在3.2.1)

步骤

  • 通过request对象获取请求转发器对象:getRequestDiapatcher(String path)
  • 使用RequestDispatcher对象来进行转发:forward(ServletRequest request, ServletResponse response)

特点:

  • 虽然转发了,但是浏览器地址栏路径不发生变化
  • 只能转发到当前服务器内部资源中(比如不能转到百度去)
  • 转发是一次请求,能使用request对象来共享数据
@WebServlet("/demo2.do")
public class ServletDemo2 extends HttpServlet {
    
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        System.out.println("demo2.do被访问了");
        request.getRequestDispatcher("/demo1.do").forward(request,response);
    }

------------------------------------------------------------------------------------- 
    
@WebServlet("/demo1.do")
public class RequestDemo extends HttpServlet {
    
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        System.out.println("demo1.do被访问了");
    }

}

在这里插入图片描述

4.2.2.3 共享数据

域对象:一个有范围的对象,可以在范围内共享数据

request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据

方法:

  • void setAttribute(String name, Object obj):存储数据
  • Object getAttribute(String name):通过键获取值
  • void removeAttribute(String name):通过键移除键值对
4.2.2.4 获取ServletContext

getServletContext()

4.2.2.5

login.html中form表单的 action路径的写法:虚拟目录+Servlet的资源路径

BeanUtils工具类,简化数据封装(用于封装JavaBean)

  • JavaBean:标准的Java类
    要求:

    • 类必须被public修饰
    • 必须提供空参的构造器
    • 成员变量必须使用private
    • 提供公共的setter和getter方法

    功能:封装数据

  • 概念(之前学的成员变量和属性意思一样,但是这里的含义不一样)

    成员变量

    属性:

    • setter和getter方法截取后的产物

      getUsername() —> Username —> username

  • 方法

  • setProperty(name, zhangsan):这里的name是属性,而不是成员变量

  • getProperty()

  • pupulate(Object obj, Map map):将map集合的键值对信息,封装到对应的javaBean对象中

五、Response

5.1 Request功能:设置响应消息

设置响应行

格式:HTTP/1.1 200 ok

设置状态码:setStatus(int sc)

设置响应头

setHeader(String name, String value)

设置响应体

使用步骤:

  • 获取输出流(这个流对象是Tomcat给返回的)

    • 字符输出流:PrintWriter getWriter()(可以写html页面,页面可以自动解析)

      注意在获取字符输出流之前一定要写response.setContentType("text/html;charset=utf-8");(作用:在获取流对象之前,设置流的默认编码;且告诉浏览器,服务器发送的消息体数据的编码,建议浏览器使用该编码解码)

    • 字节输出流:ServletOutputStream getOutputStream()

  • 使用输出流,将数据输出到客户端浏览器

    字符流输出:.write(“zaq张澳琪”)

    字节流输出:.write(“张澳琪”.getBytes(String charsetName))

六、ServletContext对象

概念:代表整个web应用,可以和程序的容器(服务器)来通信

获取:(两种方式获取的都一样)

  • 通过request对象获取

    request.getServletContext()

  • 通过HttpServlet获取

    this.getServletContext()

功能:

  • 获取MIME类型:

    MIME类型:在互联网通信过程中定义的一种数据类型

    • 格式:大类型/小类型 text/html image/jpeg

    获取:String getMimeType(String file)

    public class Demo extends HttpServlet {
          
          
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          
          
            System.out.println("demo2...");
            //通过HttpServlet获取
            ServletContext context = this.getServletContext();
            //定义文件名称
            String filename = "a.jpg";
            //获取MIME类型
            String mimeType = context.getMimeType(filename);
            System.out.println(mimeType);//  image/jpeg
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          
          
            this.doPost(request,response);
        }
    }
    
  • 域对象:共享数据

    • void setAttribute(String name, Object obj):存储数据
    • Object getAttribute(String name):通过键获取值
    • void removeAttribute(String name):通过键移除键值对

    范围:所有用户所有请求的数据

  • 获取文件的真实(服务器)路径

    • String getRealPath(String path)

      public class Demo extends HttpServlet {
              
              
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              
              
              //获取文件的服务器路径
              String realPath = context.getRealPath("/b.txt"); //web目录下资源访问
      
              String c = context.getRealPath("/WEB-INF/c.txt"); //WEB-INF目录下的资源访问
      
              String a = context.getRealPath("/WEB-INF/a.txt"); //src目录下的资源访问
                                      //这是因为项目中src目录下的文件将来会被部署到web/WEB-INF/classes路径下。
      
          }
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              
              
              this.doPost(request,response);
          }
      }
      
      

文件下载代码实现:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <a href="/myweb/img/1.jpg">图片1</a>
    <hr>
    <a href="/myweb/downloadServlet?filename=1.jpg">图片1</a>
</body>
</html>
@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
    
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        //1.获取请求参数,文件名称
        String filename = request.getParameter("filename");
        //2.使用字节输入流加载文件进内存
        //2.1找到文件服务器路径
        ServletContext servletContext = this.getServletContext();
        String realPath = servletContext.getRealPath("/img/" + filename);
        //2.2用字节流关联
        FileInputStream fis = new FileInputStream(realPath);

        //3.设置response的响应头
        //3.1设置响应头类型,content-type
        String mimeType = servletContext.getMimeType(filename);//获取文件的mime类型
        response.setHeader("content-type",mimeType);
        //3.2设置响应头打开方式:content-disposition
        response.setHeader("content-disposition","attachment;filename="+filename);

        //4.将输入流的数据写出到输出流中
        ServletOutputStream sos = response.getOutputStream();
        byte[] buff = new byte[1024*8];
        int len = 0;
        while ((len = fis.read(buff)) != -1) {
    
    
            sos.write(buff,0,len);
        }

        //释放资源
        fis.close();
    }

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

内容持续更新中…

Guess you like

Origin blog.csdn.net/ysf15609260848/article/details/105419786