HttpServletResponse&浏览器缓存操作总结

web应用交互用到两个对象 request 和 response

request : 封装所有请求内容 请求行 请求头 请求体
response : 封装所有响应内容 响应行 响应头 响应体

repsonse : 缓冲区默认大小8k response输出流会自动关闭
response : getOutputStream() getWriter()不能同时调用
response.Content-Type(“text/html;character=UTF-8”);

Servlet中response : 常用方法

//手动往客户端写状态码 tomcat会自动生成
response.setStatus(302);
//设置响应头
addHeader(String name,String value);
addIntHeader(String name,int value);
addDateHeader(String name,long date);

setHeader(String name,String value);
setIntHeader(String name,int value);
setDateHeader(String name,long date);
response.addHeader("name","test");
response.addHeader("name","java");
//响应头显示 name:"test,java"

response.setHeader("name","test");
response.setHeader("name","java");
//响应头显示 name:"java"

response响应体

//设置响应体 不可写 中文
response.getWriter().write("Hello Response!");
//浏览器显示 Hello Response!
//设置响应体编码 默认是 ISO-8859-1 西欧(不能用于中文)
response.setCharacterEncoding("UTF-8");
//设置后输出乱码 浏览器解码默认本地编码(GBK) 浏览器修改即可
//告知浏览器自动转码 设置响应头 Content-Type 的值 文本类型 和 编码类型
//response.setHeader("Content-Type","text/html;character=UTF-8");简写
response.setContentType("text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
	//可省略 设置Content-Type值后 tomcat自动设置响应体编码
//获得WebContent下的文件输出流 获取tomcat web资源 绝对路径
String realPath = getServletContext().getRealPath("test.jpg");

InputStream in = new FileInputStream(realPath);//生成字节输入流

ServletOutputStream out = response.getOutputStream();//获取响应字节流

int len = 0;//定义计算变量
byte[] buffer = new byte[1024];//定义缓冲字节数组
while ((len=in.read(buffer))>0) {
out.write(buffer, 0, len);
	//从buffer读取二进制流 从0开始 读取len个字节 len<=1024
}
in.close();
out.close();
//浏览器输出二进制文件

response.getWriter().write()与response.getWriter().print()区别

通过源码发现print或println会判断null值 除此之外别无差别

public void println(String x) {
    synchronized (lock) {
        print(x);
        println();
    }
}

public void print(String s) {
    if (s == null) {
        s = "null";
    }
    write(s);
}

response.getWriter().write()与out.print()区别

  1. write()和print()区别
    1. write() 仅支持输出字符类型数据 字符 字符数组 字符串等
    2. print() 支持任意类型数据输出 通过默认编码转换成bytes字节输出
  2. response.getWriter()和out区别
    1. out和response.getWriter类不一样 前者为JspWriter 后者为java.io.PrintWriter
    2. 执行原理不同 JspWriter相当于一个带缓存功能的printWriter 并不是直接将数据输出到页面 而是将数据刷新到response的缓冲区后再输出
      response.getWriter()为直接输出数据 out.print()在response.print()后输出
    3. out的print()方法和println()方法在缓冲区溢出并且没有自动刷新时候会产生IOException 而response.getWrite()方法的print()和println()会抑制IOException异常

对于一次请求 response的getOutputStream方法和getWriter方法是互斥 只能调用其一 forward后到新的servlet也受其约束

servlet方法结束后 tomcat会自己检查response获取的OutputStream或者Writer是否关闭 如未关闭 服务器会自动帮你关闭 一般情况下不要自己关闭这两个流 如已关闭后续filter将无法获取此流


重定向是 response 实现(浏览器地址栏改变)

//设置状态码 302
response.setStatus(302);
//设置响应头 Location浏览器地址栏参数
response.setHeader("Location","https://www.baidu.com");

//Java把上方两个方法 封装到一个方法中
response.sendRedirect("https://www.baidu.com");

//设置定时刷新的响应头 五秒钟后跳转到百度
response.setHeader("refresh","5,url=https://www.baidu.com");
重定向最少访问服务两次 第一次访问服务器返回其他链接 第二次访问返回的链接

转发是 request 实现(浏览器地址栏不改变)

转发访问服务一次 服务器内部自己定向资源 直接响应给客户端 客户端无法察觉

response缓存操作

Cache-Control

Cache-Control值 作用
public 内容将被缓存 客户端和代理服务器都可缓存
private 内容将被缓存 客户端可缓存 代理服务器不可缓存
no-cache 强制所有缓存该响应的用户 在使用已存储的缓存数据前 发送带验证器的请求到原始服务器 如果资源未更改 可以避免下载 (HTTP/1.0使用用Pragma的no-cache替换)
no-store 所有内容都不会被缓存或Internet临时文件
max-age 客户端可以接收指定时间内的响应 (单位为秒)
min-fresh 客户端可以接收响应时间小于当前时间加上指定时间内的响应
max-stale 客户端可接收超出指定值之内的响应消息

Expires

  • 通过指定Expires值也会影响到缓存 如 指定Expires值为一个已过去的时间 访问此网时若重复在地址栏按回车 每次都会重复访问
  • Expires 服务器设置为-1 表示立即过期

Cache-Control和Expires区别

  1. 概念
    Cache-control用于控制HTTP缓存(HTTP/1.0中需使用Pragma: no-cache)
    Expires表示存在时间 允许客户端在这个时间之前不去检查发请求 等同max-age的效果 但如果同时存在 则被Cache-Control的max-age覆盖

  2. 格式

  • Cache-control
    数据包中的格式 Cache-Control: cache-directive
    cache-directive可以为以下
    request时用到
| "no-cache"
| "no-store"
| "max-age" "=" delta-seconds
| "max-stale" [ "=" delta-seconds ]
| "min-fresh" "=" delta-seconds
| "no-transform"
| "only-if-cached"
| "cache-extension"

response时用到

| "public"
| "private" [ "=" <"> field-name <"> ]
| "no-cache" [ "=" <"> field-name <"> ]
| "no-store"
| "no-transform"
| "must-revalidate"
| "proxy-revalidate"
| "max-age" "=" delta-seconds
| "s-maxage" "=" delta-seconds
| "cache-extension"
  • Expires
    数据包中的格式 Expires = Date
    Expires: Thu, 01 Dec 1994 16:00:00 GMT(必须是GMT格式)

3.应用
通过HTTP的META设置expires和cache-control

设置浏览器缓存时间 在缓存时间到达之前不会访问此servlet

protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    // 时间是从1970开始 设置当前时间+缓存的时间 时间单位为毫秒 如下缓存时间1分钟
    response.setDateHeader("expires", System.currentTimeMillis() + 1000 * 60);
    // 设置缓存时间为1分钟 时间单位为秒
    response.addHeader("Cache-Control", "max-age=60");
}
@GetMapping("captcha.jpg")
public void captcha(HttpServletResponse response) {
    // 设置相应类型 告诉浏览器输出的内容为图片
    response.setContentType(MediaType.IMAGE_JPEG_VALUE);
    // 不缓存此内容
	response.setHeader("Cache-Control", "no-store");
	response.setHeader("Pragma", "no-cache");
	response.setDateHeader("expires", -1);

    try {
        // 将内存中的图片通过流动形式输出到客户端
        ImageIO.write(CaptchaUtil.createImage()
        		, "JPG", response.getOutputStream());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

cache-control参考 https://baike.baidu.com/item/Cache-control/1885913
Cache-Control和Expires区别参考 https://www.cnblogs.com/hnhycnlc888/p/9607679.html

你可能感兴趣的:(java)