Servlet第三篇【request和response简介、response的常见应用】(三)

简介: Tomcat收到客户端的http请求,会针对每一次请求,分别创建一个代表请求的request对象、和代表响应的response对象

实现数据压缩


网页上的信息量是很大的,如果不将数据压缩再回送给浏览器,这样就十分耗费流量

  • 现在我有一篇文章要输出给浏览器
response.setContentType("text/html;charset=UTF-8");
        String ss = "fsdfhsdfhuisdhfusdhfuids" +
                "fsdfdsfsdfsdfdsfdafdsfhsdjfhsdjkfhkjds" +
                "fdsfjdslkfjsldkfjsdlkfjsdkfsdjkff" +
                "fsjdfjdsklfjdsklfjkldsfjlksdjflksdjflkds" +
                "dsjfklsdjflsdjfkldsfkjsdkfjsldkfjsdlfk" +
                "fdsjlkfjdslkfjsdlkfjlkasjflk";
        response.getWriter().write("原来的长度是:"+ss.getBytes().length+"</br>");
        //输出给浏览器
        response.getWriter().write(ss);
  • 访问一下可以看到,原来的长度是201

60.jpg

  • 压缩的原理是什么?我们知道getOutputStream()和getWriter()都是直接把数据输出给浏览器的。现在我要做的就是让数据不直接输出给浏览器,先让我压缩了,再输出给浏览器java提供了GZIP压缩类给我们
  • 就让我们使用GZIP类来对数据压缩吧
//GZIP的构造方法需要一个OutputStream子类对象,究竟哪个对象适合,我们看下write()方法
        GZIPOutputStream gzipOutputStream = new GZIPOutputStream();
        //查看了下API,write()接收的是byte[]类型的。
        gzipOutputStream.write();
  • 于是我就在构造函数上传递个ByteArrayOutputStream给它
//既然是byte[]类型,那么我就给他一个ByteArrayOutputStream
        GZIPOutputStream gzipOutputStream = new GZIPOutputStream(new ByteArrayOutputStream());
  • 而用GZIPOutputStream写数据的时候,是把数据写到ByteArrayOutputStream上的,等会还要把数据取出来,再写给浏览器,于是就不能以匿名内部类的方式给GZIPOutputStream,必须把ByteArrayOutputStream定义出来
//创建GZIPOutputStream对象,给予它ByteArrayOutputStream
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);
        //GZIP对数据压缩,GZIP写入的数据是保存在byteArrayOutputStream上的
        gzipOutputStream.write(ss.getBytes());
        //gzipOutputStream有缓冲,把缓冲清了,并顺便关闭流
        gzipOutputStream.close();
  • 压缩后的数据取出来,写给浏览器
//将压缩的数据取出来
        byte[] bytes = byteArrayOutputStream.toByteArray();
        //将压缩的数据写给浏览器
        response.getOutputStream().write(bytes);
  • 我们来对比一下压缩前的大小和压缩后的大小

image.gif61.jpg

  • 数据的确是压缩了,然而,为什么又乱码了啊?很简单,既然你压缩了数据,你写给浏览器,浏览器是不知道你这是压缩后的数据,它是以正常的方式打开数据的。这当然造成乱码啦!,现在我要告诉浏览器我这是压缩数据
//告诉浏览器这是gzip压缩的数据
        response.setHeader("Content-Encoding","gzip");
        //再将压缩的数据写给浏览器
        response.getOutputStream().write(bytes);
  • 再次访问一下

image.gif62.jpg



生出随机图片


生成随机图片这是非常常见的。在我们登陆的时候经常要写验证码,而那些验证码是一张图片,就是通过HttpServletResponse写给浏览器的。


  • 要生成一张图片,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));
        //往图片上写数据,先写个12345,横坐标是0,纵坐标是20【高度】
        graphics.drawString("12345", 0, 20);
  • 好的,现在我们在内存中创建了一张图片,并写上了12345。接着,我们要把图片写给浏览器了把图片写给浏览器,java又提供了图片流【ImageIO】给我们使用
//要往浏览器写一张图片,那要告诉浏览器回送的类型是一张图片
        response.setHeader("ContentType", "jpeg");
        //java提供了图片流给我们使用,这是一个工具类
        //把图片传进去,类型是jpg,写给浏览器
        ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
  • 我们来访问一下,看下图片长什么样

63.jpg

  • 这样太丑了,我们把背景改成白色看看
//把白色填充整张图片
        graphics.setColor(Color.white);
        graphics.fillRect(0, 0, 80, 20);
  • 再看看效果,这明显好看多了

64.png

  • 好的,我们的图片数字不可能是人工写的,数字应该是随机产生的!这个就简单了。现在我要生成7位的随机数,生成随机数的方法如下
private String makeNum() {
        Random random = new Random();
        //这样就会生成0-7位的随机数,现在问题又来了,如果随机数不够7位呢?如果不够7位,我们加到7位就行了
        int anInt = random.nextInt(9999999);
        //将数字转成是字符串
        String num = String.valueOf(anInt);
        //判断位数有多少个,不够就加
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < 7 - num.length(); i++) {
            stringBuffer.append("0");
        }
        return stringBuffer.append(num).toString();
    }
  • 如果要生成中文,就找中文映射表即可


重定向跳转


什么是重定向跳转呢?点击一个超链接,通知浏览器跳转到另外的一个页面就叫重定向跳转。是通知浏览器去跳转,这很重要。页面之间的跳转有两种方式:重定向和转发,至于什么时候用重定向,什么用转发,我在讲完HttpServletRequest对象的时候会详细说明。

  • 我们来使用以下HttpServletResponse对象的重定向
//重定向到index.jsp页面
        response.sendRedirect("/zhongfucheng/index.jsp");
  • 浏览器的地址栏访问Servlet222

image.gif65.png

  • 跳转到index.jsp页面,地址栏发生了变化

image.gif66.jpg

  • 我们再来看看http协议发生了什么

image.gif67.jpg

  • 从图上看,我们看到了两个状态码,一个是302。一个是200。302状态码在http协议中代表的是临时重定向。举个例子:我找纪律委员说:给我一份请假表,我要回家。纪律委员告诉我:我这里没有请假表,你去找辅导员吧。再看回我访问Sevlet222时:我找Servlet222,Servlet222告诉浏览器:我没有你想要的资源,你要的资源在index.jsp页面中,你自己去找吧。
  • 很容易看出重定向是通过302状态码和跳转地址实现的。于是乎,我们设置http消息头就可以实现重定向跳转
//设置状态码是302
        response.setStatus(302);
        //HttpServletResponse把常用的状态码封装成静态常量了,所以我们可以使用SC_MOVED_TEMPORARILY代表着302
        response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
        //跳转的地址是index.jsp页面
        response.setHeader("Location", "/zhongfucheng/index.jsp");
  • 其实sendRedirect()方法就是对setStatus()和setHeader()进行封装,原理就是setStatus()和setHeader()


getWriter和getOutputStream细节


  1. getWriter()和getOutputStream()两个方法不能同时调用。如果同时调用就会出现异常
  2. Servlet程序向ServletOutputStream或PrintWriter对象中写入的数据将被Servlet引擎从response里面获取,Servlet引擎将这些数据当作响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端
  3. Servlet的serice()方法结束后【也就是doPost()或者doGet()结束后】,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象.
目录
相关文章
|
5月前
|
前端开发 Java
[Web程序设计]实验: Servlet基础应用
[Web程序设计]实验: Servlet基础应用
|
18天前
|
XML 安全 Java
Servlet 教程 之 Servlet 简介 3
Servlet是运行在Web服务器上的Java程序,用于处理HTTP请求和响应,与数据库或应用交互。相比CGI,Servlet性能更优,平台无关,并受服务器安全管理器保护。它们主要任务包括读取客户端数据、处理信息、生成结果及发送响应。Servlet利用javax.servlet和javax.servlet.http包构建,遵循Java Servlet 2.5和JSP 2.1规范,可被编译成Java类运行。
17 1
|
6月前
|
Java 应用服务中间件
线上临时文件夹报错Failed to parse multipart servlet request; nested exception is java.lang.RuntimeException: java.nio.file.NoSuchFileException
Failed to parse multipart servlet request; nested exception is java.lang.RuntimeException: java.nio.file.NoSuchFileException、tmp、配置文件指定目录
125 0
|
2月前
|
Java 应用服务中间件 API
深入解析Java Servlet技术在Web开发中的应用
深入解析Java Servlet技术在Web开发中的应用
214 1
|
7月前
|
XML 开发框架 Java
Java Web 项目入门指南(http、Servlet、Request、Response、ServletContext、会话技术[cookie、session]、Filter、Listener)
Java Web 项目入门指南(http、Servlet、Request、Response、ServletContext、会话技术[cookie、session]、Filter、Listener)
|
4月前
Request通用方式获取请求参数及Servlet模板创建
Request通用方式获取请求参数及Servlet模板创建
27 0
|
4月前
|
Java 应用服务中间件 容器
Servlet简介、执行流程及生命周期
Servlet简介、执行流程及生命周期
36 1
|
9月前
|
XML 开发框架 前端开发
JavaWeb上机实验11 Servlet的应用(二)
JavaWeb上机实验11 Servlet的应用(二)
81 0
|
4月前
|
Web App开发 前端开发 JavaScript
AJAX POST请求中参数以form data和request payload形式在servlet中的获取方式
AJAX POST请求中参数以form data和request payload形式在servlet中的获取方式
32 0
|
6月前
|
小程序 Java API
04JavaWeb基础 - Servlet简介
04JavaWeb基础 - Servlet简介
19 0