response、request对象

Tomcat收到客户端的http请求,会对每一此请求,分别创建一个代表请求的request对象和代表响应的response对象。

既然request对象代表http请求,获取浏览器提交过来的数据,找request对象即可。response对象代表http响应,向浏览器输出数据,找response对象即可。

HttpServletResponse对象

http响应由状态行、实体内容、多个消息头、一个空行组成。HttpServletResponse对象就封装了http响应的信息。

调用getOutputStream()向浏览器输出数据

print()方法

ServletOutputStream servletOutputStream = response.getOutputStream();
//print()输出英文 成功
servletOutputStream.print("abc");
//print()输出中文 出现乱码   因为Tomcat使用的IOS 8859-1编码,中文不支持该编码
servletOutputStream.print("中国");

write()方法

ServletOutputStream servletOutputStream = response.getOutputStream();
//write()输出英文 成功
servletOutputStream.write("abc".getBytes());
//write()输出中文 成功 由于getBytes()在转成byte[]数组的时候默认查的是gb2312编码,而中文支持gb2312编码 而且与浏览器的编码一致
servletOutputStream.write("中国".getBytes());
//如果浏览器默认的编码不是UTF-8,则会乱码
servletOutputStream.write("中国".getBytes("UTF-8"));

而解决write()输入中文乱码的方法

//方法一
response.setContentType("text/html;charset=UTF-8");
//方法二
servletOutputStream.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'>".getBytes());
servletOutputStream.write("中国".getBytes("UTF-8"));

调用getWriter()方法向浏览器输出数据

//设置浏览器用UTF-8编码显示数据,否则会出现中文乱码
response.setContentType("text/html;charset=UTF-8");
PrintWriter printWriter=response.getWriter();
printWriter.write("中国");

实现文件下载

java的文件上传下载都是通过io流来完成的。

找到文件,读取它

//获取资源的路径
String path=this.getServletContext().getRealPath("/download/韦德.jpg");
//读取文件
FileInputStream fileInputStream=new FileInputStream(paht);
//获取到文件名,路径在电脑上保存是\\形式的
String fileName=path.substring(path.lastIndexOf("\\")+1);

告诉浏览,下载这个文件

//设置消息头,告诉浏览器,下载这个文件
response.setHeader("Content-Disposition","attachment;filename="+fileName);
//但是文件名是中文的话,会出现乱码,采取下面的方法解决该问题
response.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(fileName,"UTF-8"));

将读取的内容回送给浏览器

//把读取到的资源写给浏览器
int len=0;
byte[] bytes=new byte[1024];
ServletOutputStream servletOutputStream=response.getOutputStream();
while((len=fileInputStream.read(bytes))>0){
     servletOutputStream.write(bytes,0,len);
servletOutputStream.close();
fileInputStream.close();

实现自动刷新

//实现3秒,页面自动刷新
response.setHeader("refresh","3");
response.getWriter().write("this is "+System.currentTimeMills());
//实现3秒后,页面自动跳转
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("3秒后自动跳转");
response.setHeader("refresh","3;url='/index.jsp'");

浏览器本身就存在着缓存机制

像股票类型的网页时不能取缓存数据的,数据都是要不断更新的。所以要禁止缓存。

//浏览器有三个消息头设置缓存,为了兼容性,将三个消息头都设置了
response.setDateHeader("Expires","-1");
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");
//这里为了看效果
response.getWriter().print("你好啊"+new Date().toString());

实现数据压缩

java提供GZIP压缩类来对数据压缩

//GZIP的构造方法需要一个OutputStream子类对象
GZIPOutputStream gzipOutputStream=new GZIPOutputStream();
//write()接收的是byte[]类型
gzipOutputStream.write();
String ss="abcdefghigk";
//创建GZIPOutputStream对象,给予它ByteArrayOutputStream
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);
//GZIP对数据压缩,GZIP写入的数据是保存在byteArrayOutputStream上的
gzipOutputStream.write(ss.getBytes());
gzipOutputStream.close();
//将压缩的数据取出来
byte[] bytes = byteArrayOutputStream.toByteArray();
//告诉浏览器这是gzip压缩的数据
response.setHeader("Content-Encoding","gzip");
//将压缩的数据写给浏览器
response.getOutputStream().write(bytes);

生成随机图片

java提供了BufferedImage类生成一张图片

        //在内存中生成一张图片,宽为80,高为20,类型是RGB
        BufferedImage bufferedImage = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
        //获取到这张图片
        Graphics graphics = bufferedImage.getGraphics();
        //往图片设置颜色和字体
        graphics.setColor(Color.BLUE);
        graphics.setFont(new Font(null, Font.BOLD, 20));
        //往图片上写数据
        graphics.drawString("12345", 0, 20);
        //往浏览器写一张图片,告诉浏览器回送的类型是一张图片
        response.setHeader("ContentType", "jpeg");
        //java提供了图片流,把图片传进去,类型是jpg,写给浏览器
        ImageIO.write(bufferedImage, "jpg", response.getOutputStream());

重定向跳转

点击一个超链接,通知浏览器跳转到另外的一个页面就叫重定向跳转。

页面之间的跳转有两种方式:重定向和转发

response.sendRedirect("/index.jsp");

重定向式通过302状态和跳转地址实现的,可以设置http消息头就可以实现重定向跳转。

//设置状态码302
response.setStatus(302);
//HttpServletResponse把常用的状态码封装成静态变量了,也可以是用SC_MOVED_TEMPORARILY代表着302
response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
response.setHeader("Location","index.jsp");

其实sendRedirect()方法就是对setStatus()和setHeader()进行封装,原理就是setStatus()和setHeader()

getWriter和getOutputStream细节

  • getWriter()和getOutputStream()两个方法不能同时调用。否则,会出现异常。
  • Servlet程序向ServletOutputStream或printWriter对象中写入的数据将被Servlet引擎从response里面获取,Servlet引擎将这些数据当作相应消息的正文,然后再与状态行和各相应头组合输出到客户端。
  • Servlet的service()方法结束后【也就是doPost()或者doGet()结束后】,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象。
  •