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()区别
对于一次请求 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
Cache-Control和Expires区别
概念
Cache-control用于控制HTTP缓存(HTTP/1.0中需使用Pragma: no-cache
)
Expires表示存在时间 允许客户端在这个时间之前不去检查发请求 等同max-age的效果 但如果同时存在 则被Cache-Control的max-age覆盖
格式
Cache-Control: cache-directive
| "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 = 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