Response对象
1.1 ServletContext对象
服务器中的项目,名称叫做WEB应用程序,应用程序也是对象
ServletContext (上下文) 对象表示WEB应用程序
一个WEB应用程序只能存在一个ServletContext对象,唯一性
每个应用程序,对应一个ServletContext对象
ServletContext是接口,此接口的实现类是tomcat引擎提供
-
ServletContext对象获取
- ServletConfig对象,方法 getServletContext()
- 继承HttpServlet类,继承GenericServlet类定义方法 getServletContext()
ServletContext context = getServletContext();
对象的作用
既然 ServletContext 是 贯穿全文 的对象 ,所以项目中的资源 它都能访问到 , 主要 用它获取web项目中文件.
文件保存的位置 :
- src下 : 发布到 /WEB-INF/classes/文件名
- web目录下: 发布到 /文件名
- WEB-INF目录下:发布到 /WEB-INF/文件名
代码中获取路径 , 写法应该是发布后的路径 .
-
获取WEB应用程序的初始化参数,web.xml配置
<!-- 配置的是WEB程序的初始化参数--> <context-param> <param-name>heima</param-name> <param-value>java</param-value> </context-param>
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * 获取ServletContext对象 * 父类的方法 * org.apache.catalina.core.ApplicationContextFacade实现接口ServletContext */ ServletContext context = getServletContext(); System.out.println(context); //context对象,获取配置文件中的初始化参数 String value = context.getInitParameter("heima"); System.out.println(value); }
-
获取WEB应用程序下任意资源的绝对路径
- 方法: String getRealPath(“资源相对路径”)
protected voi d doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * 获取ServletContext对象 * 父类的方法 * org.apache.catalina.core.ApplicationContextFacade实现接口ServletContext */ ServletContext context = getServletContext(); System.out.println(context); //context对象,获取配置文件中的初始化参数 String value = context.getInitParameter("heima"); System.out.println(value); //context对象,方法getRealPath获取任意资源的绝对路径 //获取web目录下的a.txt绝对路径 String aPath = context.getRealPath("a.txt"); System.out.println(aPath); //获取web目下WEB-INF目录下的b.txt绝对路径 String bPath = context.getRealPath("WEB-INF/b.txt"); System.out.println(bPath); //获取src目录下的c.txt绝对路径 String cPath = context.getRealPath("WEB-INF/classes/c.txt"); System.out.println(cPath); //获取WEB03 module下的d.txt绝对路径,获取不到 }
-
域对象
ServletContext对象是一个容器,可以存储数据.
对象有个作用域问题,ServletContext作用域是整个WEB应用程序
- 向域对象存储数据: setAttribute(String key, Object value)
- 取出域对象数据: Object getAttribute(String key)
- 移除域对象数据: removeAttribute(String key)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * 域对象的存储和取出 */ ServletContext context = getServletContext(); //域对象存储数据,键值对 context.setAttribute("heima","java"); //取出域对象存储的键值对 Object value = context.getAttribute("heima"); System.out.println(value); }
1.2ServletContext对象的空指针异常
ServletContext对象通过父类的方法getServletContext()获取
正常情况:
- Tomcat引擎,创建Servlet对象,调用init方法,引擎创建ServletConfig对象,
- 在调用init的方法时候,把ServletConfig对象传进去
- cofig会赋值给成员变量
- 在doGet方法调用getServletContext的时候,先调用getServletConfig(),然后再调用getServletContext.
非正常情况:
- 因为重写了init方法,导致引擎创建的ServletConfig对象,传到了重写的init方法里
- init方法里面没有东西,在调用getServletContext()时候,因为成员config没赋值,在调用getServletConfig()就会抛空
1.3 统计访问的次数
练习域对象ServletContext的使用
第一次访问Servlet的时候,数据1存储到域对象
第二次访问,从域中取出数据++,存储回去
public void init() throws ServletException {
ServletContext context = getServletContext();
context.setAttribute("count",1);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = getServletContext();
Integer count = (Integer) context.getAttribute("count");
response.getWriter().print("welcome "+count);
count++;
context.setAttribute("count",count);
}
1.4 注解开发取代web.xml
@WebServlet,注解添加到自己定义的Servlet中的类声明上即可
注解的属性 urlPatterns,属性值就是浏览器的访问地址
@WebServlet(urlPatterns = "/test")
1.5 Response对象概述
负责对浏览器进行响应的对象
ServletResponse接口,HttpServletResponse接口继承自ServletResponse
使用的是子接口HttpServletResponse,此接口对象由Tomcat引擎提供
可以实现对客户端的响应, 响应行,响应头,响应体
1.6 Response设置响应行
- 设置状态码: setStatus(int 状态码)
response.setStatus(500);
1.7 Response设置响应头
HTTP协议的响应头,数据格式键值对 k:v
包含指导性信息,指导客户端
- addHeader(String key,String value)
- addIntHeader(String key,int value)
- addDateHeader(String key,long l)
- setHeader(String key,String value)
- setIntHeader(String key,int value)
- setDateHeader(String key,long l)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
* response对象设置响应头
*/
response.addHeader("heima","java");
/* response.addIntHeader("heima2",5);
response.addDateHeader("date",System.currentTimeMillis());*/
/*
* addHeader() 添加,实现一个键对应多个值
* setHeader() 设置,原来的键覆盖
*/
response.setHeader("heima","java2222");
}
1.8 Response设置响应体
HTTP的响应体,就是页面的正文部分
-
getWriter() 返回值是打印流PrintWrite
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * response对象方法getWriter() * 打印流的响应体 * write() 使用字符串数据,没有差别, 输出是整数,查询编码表 * print() 无论是什么,原样打印 */ PrintWriter pw = response.getWriter(); pw.write(100); pw.print(100); out.print("<script>alert('删除成功!');location.href='UserServlets?opr=list';</script>"); }
响应中的中文乱码问题
产生乱码原因: 编码和解码不一致
响应数据,没有直接写回客户端,写在response对象缓冲区,使用的编码是iso8859-1 拉丁文
设置对象缓冲区编码表,并告诉浏览器以utf-8码表去显示数据
response.setContentType("text/html;charset=UTF-8");
-
getOutputStream() 返回字节输出流OutputStream
返回字节流,响应非文本类型的数据
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * response对象的方法getOutputStream,响应非文本类型的数据 */ //获取图片的绝对路径 String aFile = getServletContext().getRealPath("a.jpg"); FileInputStream fis = new FileInputStream(aFile); OutputStream out = response.getOutputStream(); int len = 0; byte[] bytes = new byte[1024]; while ((len = fis.read(bytes))!=-1){ out.write(bytes,0,len); } fis.close(); }
1.9 重定向
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
* 接收浏览器的请求
* 对浏览器进行响应:
* 浏览器进行重新的定向
* 302状态码
* 重定向资源的地址: 响应头
*
* Sun: 定义个方法实现重定向
response的方法 :
sendRedirect("路径") : 由于是重新定向 , 再次发起的请求来自于服务器外部, 所有需要添加 项目名称
举例 : "/WEB03/servlet2"
*/
//response.setStatus(302);
//response.setHeader("location","/WEB03/servlet2");
response.sendRedirect("/WEB03/servlet2");
}
2.0 文件的下载
客户端浏览器从服务器下载文件
超链接,连接的地址是服务器端文件的路径
文件: 浏览器识别文件,不是下载,就是直接打开运行
浏览器不识别文件,直接下载
编写服务器端代码,告诉浏览器下载,不要打开
Servlet页面
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
* 编写程序,通知浏览器请你下载,不要打开
* 指导浏览器干什么,响应头
* 浏览器下载是HTTP协议规定
*/
/*Firefox浏览器下载中文文件的时候采用的是Base64的编码.
*IE浏览器,谷歌浏览器等,下载中文文件的时候采用的URL的编码.
*可以使用工具类“DownloadUtils.java”进行处理
*/
//根据User-Agent获取什么浏览器
String agent = request.getHeader("User-Agent");
String filename="美女.jpg";
if (agent.contains("MSIE")) {
// IE浏览器
filename = URLEncoder.encode(filename, "utf-8");
filename = filename.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐浏览器,这个对象java8以后就没有了
BASE64Encoder base64Encoder = new BASE64Encoder();
filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {
// 其它浏览器
filename = URLEncoder.encode(filename, "utf-8");
}
//设定接收程序处理数据的方式
response.setHeader("Content-Disposition","attachment;filename="+filename);
String aFile = getServletContext().getRealPath("download/a.jpg");
FileInputStream fis = new FileInputStream(aFile);
OutputStream out = response.getOutputStream();
int len = 0;
byte[] bytes = new byte[1024];
while ((len = fis.read(bytes))!=-1){
out.write(bytes,0,len);
}
fis.close();
}
html页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
a:link{color: black}
a:visited{color: black}
</style>
</head>
<body>
<!--
超链接,实现文件下载
连接的地址,写服务器端需要下载文件的路径
-->
<a href="/WEB03/download/a.flv">a.flv</a><br>
<a href="/WEB03/download/a.jpg">a.jpg</a><br>
<a href="/WEB03/download/a.mp3">a.mp3</a><br>
<a href="/WEB03/download/a.mp4">a.mp4</a><br>
<a href="/WEB03/download/a.txt">a.txt</a><br>
<a href="/WEB03/download/a.zip">a.zip</a><br>
<a href="/WEB03/download/a.pdf">a.pdf</a><br>
<hr>
<!-- 超链接,连接地址不是文件,Servlet中-->
<a href="/WEB03/downLoad">a.jpg</a> <br>
<!--<form action="#" method="get">
<input type="text" name="a"> <input type="submit">
</form>-->
</body>
</html>
2.1 response对象注意事项
-
重定向,不要在写代码,没有意义
不能多次重定向
-
getWriter()字符流和getOutputStream()字节流互斥,只能选择一个使用
response对象缓冲区,临时存储数据
缓冲区到底是字节的,还是字符的呢?
2.2 验证码案例
验证码的本质是个图片,图片里面是个随机生成字符串
String str =“abcdefABCDE1234567890”;
Random.nextInt( str.length() )产生整数随机数
str.charAt(索引)
html
<img src="/WEB03/code" onclick="fnChange()" id="code">
<script type="text/javascript">
function fnChange() {
/*
* 页面打开的时候,请求服务器资源/WEB03/code
* 点击图片js函数中,发了请求/WEB03/code
*
* 请求的资源没有变化,服务器端程序也没有变化
* 浏览器拿缓存吧
*
* 每次请求不一样就行,添加参数
*/
//点击图片,修改src的属性值
var code = document.getElementById("code");
var date = new Date().getTime();
code.src="/WEB03/code?a="+date;
}
</script>
servlet
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
@WebServlet(urlPatterns = "/code")
public class CodeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 创建画布
int width = 120;
int height = 40;
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 获得画笔
Graphics g = bufferedImage.getGraphics();
// 填充背景颜色
g.setColor(Color.white);
g.fillRect(0, 0, width, height);
// 绘制边框
g.setColor(Color.red);
g.drawRect(0, 0, width - 1, height - 1);
// 生成随机字符
// 准备数据
String data = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
// 准备随机对象
Random r = new Random();
// 声明一个变量 保存验证码
String code = "";
// 书写4个随机字符
for (int i = 0; i < 4; i++) {
// 设置字体
g.setFont(new Font("宋体", Font.BOLD, 28));
// 设置随机颜色
g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
String str = data.charAt(r.nextInt(data.length())) + "";
g.drawString(str, 10 + i * 28, 30);
// 将新的字符 保存到验证码中
code = code + str;
}
// 绘制干扰线
for (int i = 0; i < 6; i++) {
// 设置随机颜色
g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
g.drawLine(r.nextInt(width), r.nextInt(height), r.nextInt(width), r.nextInt(height));
}
// 将验证码 打印到控制台
System.out.println(code);
// 将验证码放到session中
//request.getSession().setAttribute("code_session", code);
// 将画布显示在浏览器中
ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}