• Response/Request


    HttpServletResponse
    向客户端发送数据 ---->实体内容
    发送响应头 -----> 头信息
    发送响应状态码 ----> 状态行


    状态码(Status Code)
    setStatus(int)
    常用状态码:200、302、304、404、500

    302 重定向
    resp.setStatus(302);
    resp.setHeader("Location",url); // 客户端url : / ----> http://localhost:8080


    头信息 (Header Info)
    addHeader(String,String) :  // 调用addHeader 不会覆盖原来值,会拼成一个多值属性
    * 如果不是多值,只有一个值,addHeader 效果 同 setHeader
    setHeader(String,String) :  // 调用setHeader 新的值会覆盖掉旧的值


    获得向客户端进行数据输出的流对象
    字节流数据输出
    OutputStream out = response.getOutputStream();
    字符流数据输出
    PrintWriter pw = response.getWriter();

    提供了两个和编码设置相关的方法

    指定body内容的类型
    setContentType("text/html")
    指定输出数据的编码格式
    setCharacterEncoding("gb2312");
    默认情况下,编码格式是ISO-8859-1

    响应乱码问题
    1、不设置编码 采用 ISO-8859-1编码 不支持中文
    2、设置编码 setCharaterEncoding gbk  ----> 浏览器是如果不以gbk方式查看,是不是还会有乱码
    * 保证服务器端中文正确编码 --- > 不能确定浏览器打开的查看编码集
    3、指定浏览器查看编码 setContentType
    *setContentType 原意 是用来设定 输出到浏览器端 文档的MIME类型
    *setContentType 指定浏览器查看编码集
    *setContentType 设置了 charset 将会覆盖 setCharacterEncoding的效果
    setContentType("text/html;charset=utf-8");
    等价于
    setCharacterEncoding("utf-8");
    setContentType("text/html");

    IO使用缓存效率更高!!! 为什么?
    如果不使用缓存
    1、使用客户端连接(使用CPU)
    2、写出一个字节 (IO操作,释放CPU)
    3、使用客户端连接
    4、写出一个字节
    使用缓存
    1、使用客户端连接(使用CPU)
    2、一次性写出 1024B

    假如缓存8K ,什么情况下缓存会输出
    1、flushBuffer
    2、当8K缓存写满时

    reset() // 重置 HTTP 响应 状态码 头信息 实体内容
    resetBuffer() // 重置实体内容 不会重置头信息和状态码

    getBufferSize() // 获取缓存大小 默认缓存8K
    setBufferSize() // 设置缓存大小 只能往大设置 不能往小设置

    isCommitted()  // 判断响应的信息(状态码、头信息、实体内容)是否输出的浏览器端
    false 表示信息没有输出到浏览器
    true 表示信息已经输出到浏览器

    通常<meta> 具有设置Http响应头信息的效果
    meta和setHeader区别
    1、setHeader是真正意义上设置Http响应头信息,在服务器端生成http响应时生效
    2、<meta>不是真正设置http响应头信息,在浏览器解析时生效
    3、如果我同时写了
    resp.setHeader("Content-Type", "text/html; charset=UTF-8");
    resp.getWriter().println("<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>");
    第二句<meta> 将没有效果

    resp.getWriter().println("中文测试信息");
    resp.getOutputStream().write(1);
    不能一起使用

    resp.setHeader("refresh", "3"); // 3秒刷新当前页面
    resp.setHeader("refresh", "3;url=xxx"); // 3秒刷新,跳转到xxx页面
    <meta http-equiv="refresh" content="3;url=/day7/index.html">

    setHeader(String,String) // 其实用来设置字符串类型头信息
    setIntHeader(String,int) // 用来设置数字类型头信息
    setDateHeader(String,long) // 毫秒数  用来设置日期类型头信息

    expires: Fri, 02 Jan 1970 00:00:00 GMT
    当你使用毫秒时,所有时间都从1970.1.1 00:00:00计时
    如果你想使用setHeader 设置过期时间 时间的值写成:Fri, 02 Jan 1970 00:00:00 GMT
    resp.setHeader("expires","2011-10-30"); // 不行

    当过期时间设置成过去时,意味着已经过期,没有缓存

    long time = System.currentTimeMillis();
    long time2 = new Date().getTime();
    resp.setDateHeader("expires", time + 1000 * 60 * 60 * 24);

    expires: Sun, 30 Oct 2011 02:49:38 GMT

    如果想页面不缓存
     <meta http-equiv="pragma" content="no-cache">
     <meta http-equiv="cache-control" content="no-cache">
     <meta http-equiv="expires" content="0">   
    resp.setHeader("pragma","no-cache");
    resp.setHeader("cache-control","no-cache");
    resp.setDateHeader("exires",-1); // resp.setHeader("exires","-1");

    cache 304区别
    cache 根本不走服务器
    304 到了服务器 服务器让你找缓存

    下载文件:
    1、可见文件的下载
    使用链接直接实现
    什么样的文件可以下载:浏览器不识别的文件格式
    如果浏览器识别文件格式,直接打开
    2、不可见文件的下载
    如果你有一个文件,想收费--- 不可见
    如果文件格式浏览器识别 不能用链接

    *一定设置文件的MIMEType   ---- getServletContext().getMimeType()
    如果文件格式浏览器识别
    设置一个头信息 Content-Disposition : attachment;filename=xxx  ---- 以附件形式下载
    中文名称的文件 乱码
    需要对中文文件名单独编码 URLEncoder  //URLEncoder.encode(name, "utf-8")  ---- 对中文名称文件名编码


    *字节流 字符流 什么时候选用?
    网络传输、文件复制 当你不需要知道文件里面写的是什么的时候 ----> 字节流
    当你想分析文件,写中文的时候 --- > 字符流

    验证码图片
    就是在你登陆或者注册的时候,下面显示的那个看不清楚的图片
    为什么有验证码:防止机器人,恶意登陆、注册

    graphics.setColor(Color.YELLOW); // 指定当前笔颜色

    修饰字的显示
    字体:宋体、黑体、仿宋、楷体
    样式:加粗、斜体、下划线
    大小:20 、40

    画线
    宽120
    高40

    随机生成的点
    x 0-120
    y 0-40

    旋转
    Graphics2D graphics2D = (Graphics2D) graphics; // 必须使用Graphics2D,才能旋转

    theta 弧度
    360度 = 2Pi弧度
    1弧度 = 180/Pi度
    1度 = Pi/180 弧度

    *旋转角度不要大于45

    响应的重定向
    原理  
    resp.setStatus(302);  
    resp.setHeader("location", "/day7/index.html"); // 客户端路径
    等价于
    resp.sendRedirect("/day7/index.html");

    URL和URI区别
    URL完整路径
    http://www.itcast.cn/index.html
    file:///c:/info.txt
    URI资源路径
    index.html
    ./index.jsp
    ../aaa/bb/login.html
    URI包括URL

    req.getRequestURL():http://localhost:8080/day7/request1
    req.getRequestURI():/day7/request1
    req.getQueryString():null   ------- ?name=zhangsan&pwd=123
    客户机ip ----客户机主机名 === 客户机端口(随机的取1024后任意端口)
    127.0.0.1------127.0.0.1-----2385
    服务器IP ---- 服务器名称
    127.0.0.1====localhost
    method:GET

    通过request getHeader
    getHeaders // 主要用来获得多值头信息字段
     
    获取
    Accept: */*
    Accept-Language: zh-cn
    Accept-Encoding: gzip, deflate
    User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)
    Host: 127.0.0.1:8080
    Connection: Keep-Alive

    getIntHead(name)方法  --- int  用来获取头信息的值为int的属性
    getDateHead(name)方法 --- long(日期对应毫秒)  用来获取头信息的值为日期类型的属性

    request获取请求参数
      // Post乱码解决
      req.setCharacterEncoding("utf-8");
      // 获得单值数据 getParameter
      String username = req.getParameter("username");
    *当调用getParameter获取一个多值属性?------ 获得第一个值
    获得多值属性
    String[] hobby = req.getParameterValues("hobby");
    System.out.println(Arrays.toString(hobby));
    通过getParameterNames 遍历所有请求数据
    Enumeration<String> names = req.getParameterNames();
      while (names.hasMoreElements()) {
       String name = names.nextElement();
       System.out.println("变量名称:" + name);
       String[] values = req.getParameterValues(name);// 得到这个变量对应的所有值
       System.out.println("值:" + Arrays.toString(values));
      }


    getParameterMap  --- Map<String,String[]> // 获得请求数据的Map结构
    作业:通过BeanUtils populate 将Map数据存入User对象

    username != null && username.trim().length() > 0 // 这是一个验证非空的常见写法,这是一个短路程序屏蔽了空指针异常

    username != null // username 在请求中没有这个字段时,调用getParameter 返回null
    username.trim().length() > 0 用户没有输入,或者可能输入的是空格

    get方式乱码的导致原因
    1、regist.html 输入了一个中文 :无敌
    2、浏览器对无敌进行了编码:URL编码 URLEncoder  username=%E6%97%A0%E6%95%8C
                    utf-8  %E6%97%A0%E6%95%8C
    3、服务器tomcat接受了%E6%97%A0%E6%95%8C数据,分析请求,提取数据
    4、将数据提取为String 存入Request对象-------byte[] - String 默认解码方式 ISO-8859-1
    5、req.getParameter("username")

    * "".getBytes() // 不传入编码集的时候,默认编码集:系统字符集gbk

    练习:
    http://localhost:8080/myweb?name=zhangsan+lisi
    req.getParameter("name") ---> 输出什么:zhangsan lisi

    常用转义规则
    空格换成加号(+)
    +换成%2B
    正斜杠(/)分隔目录和子目录 换成%2F
    问号(?)分隔URL和查询 换成%3F
    百分号(%)制定特殊字符 换成%25
    #号指定书签  换成%23
    &号分隔参数  换成%26

    利用域传递对象:ServletContext  ----- 所有Servlet共享
    setAttribute
    getAttribute
    removeAttribute

    利用request数据域传递对象  ----- 同一个请求内数据可以共同访问
    setAttribute(String,Object)
    getAttribute(String) ---- Object  类型丢失
    removeAttribute

    什么情况下会使用request域传递对象?
    当服务器端有两个资源需要共享数据时!
    客户端页面 ----- 请求 ----- 服务器端程序 ----- 响应 ----- 客户端页面
    客户端页面 ------请求 ----- 服务器端A程序 ----- 转发 ----- 服务器端B程序 ---- 响应 ---- 客户端页面
    当你的服务器端的功能太过复杂时,你想将功能分开

    Servlet
    // 将users对象存入request域
    req.setAttribute("users", users);
    // 通过RequestDispatcher 转发
    req.getRequestDispatcher("/users.jsp").forward(req, resp);

    JSP
    java.util.List users = (java.util.List)request.getAttribute("users");
    System.out.println(users.size());

    如果在调用forward方法之前,在Servlet程序中写入的部分内容已经被真正地传送到了客户端 isCommited,forward方法将抛出IllegalStateException异常
    练习
    resp.getWriter().print("xxx");
    resp.flushBuffer(); // isCommited --- true
    req.getRequestDispatcher().forward ... // 出现异常

    当你使用request域传递对象的时候,共享同一个request才能共享request域中的数据
    转发:一个request
    重定向:两个request


    转发和重定向的区别
    转发:
    1、一次请求、一次响应
    2、只能访问本站
    3、/ 指带 当前web应用根目录
    4、URL不变
    5、共享request域中的对象

    重定向
    1、两次请求、两次响应
    2、可以访问任何站点
    3、/ 指带 当前服务器的根目录
    4、URL改变
    5、不能共享request域中的对象

    include
    开放网站的时候:很多个页面都有一部分数据重复的
    对于这些固定不动的部分,你可以include动态编程
     
    // 包含页面top.html
    req.getRequestDispatcher("top.html").include(req, resp);
    // 包含页面 content.html
    req.getRequestDispatcher("content.html").include(req, resp);
    // 包含页面 footer.html
    req.getRequestDispatcher("footer.html").include(req, resp);

    现在可以通过Servlet访问页面 有三种方式给你选择 forward sendRedirect include
    当isCommited为true 哪种 可以使用:include

  • 相关阅读:
    Leetcode: 1425
    Leetcode: 1508 Range Sum of Sorted Subarray Sums
    Leetcode: 1353. Maximum Number of Events That Can Be Attended
    Leetcode: 1424. Diagonal Traverse II
    Leetcode: 825. Friends Of Appropriate Ages
    非递归实现二叉树的前序,中序,后序遍历
    TCP协议详解
    Linux常见命令
    C++基础笔记
    指针和引用的区别
  • 原文地址:https://www.cnblogs.com/qq809306794/p/Response_Request.html
Copyright © 2020-2023  润新知