zoukankan      html  css  js  c++  java
  • 记账本开发记录——第十四天(2020.2.1)

    今天主要学习了response对象,也就是http响应。学习了几个该对象下的方法和操作。关于其运行流程,如图:

     简单解释的话,就是:客户端发送http请求,tomcat(服务器)将请求封装成request对象和response对象,发送给web应用,web应用里对response进行操作,写到response的缓冲区内,之后被tomcat获取。tomcat获取好后将其组装成一个http响应,交给浏览器解析。

    从以上的解释可以看到,response下的操作大概有三类:设置响应行,设置响应头,设置响应体,

    对于响应行来说,可操作内容并不多,不再详细叙述。

    关于设置响应头,进行了一个简单的demo测试,如下:

    package header;
    
    import java.io.IOException;
    import java.sql.Date;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * Servlet implementation class HeaderServlet
     */
    @WebServlet("/HeaderServlet")
    public class HeaderServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public HeaderServlet() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            Date date = new Date(0);
            //设置响应头
            response.addHeader("name", "zhangsan");
            response.addIntHeader("age", 28);
            response.addDateHeader("birthday", date.getTime());
            response.setHeader("age", "50");
        }
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }

    在doGet中写了几种方法的演示,其中setHeader会替代旧的内容,而addHeader则会添加到后面。

    设置响应体,也就是设置文本。主要用来在界面上写入文字或者其他内容。对于文字:

    package content;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * Servlet implementation class TextServlet
     */
    @WebServlet("/TextServlet")
    public class TextServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public TextServlet() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            
            //response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-Type", "text/html;charset=UTF-8");
            PrintWriter writer = response.getWriter();
            //writer.write("hello response!");
            writer.write("你好世界!");
        }
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }

    可以看到,response.setHeader("Content-Type", "text/html;charset=UTF-8");  这一行是用来防止中文乱码的,因为tomcat默认的解码表是ISO8895-1,其中并不含有汉字,我们要将其设置为UTF-8才可以读取到中文内容。

    那么对于非文字内容,就需要使用文件流来进行读取了,如下:

    package content;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * Servlet implementation class ByteServlet
     */
    @WebServlet("/ByteServlet")
    public class ByteServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public ByteServlet() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            
            
            //使用response获得字节输出流
            ServletOutputStream out = response.getOutputStream();
            
            //获得服务器上的图片
            String realPath = this.getServletContext().getRealPath("a.jpg");
            InputStream in = new FileInputStream(realPath);
            int len=0;
            byte[] buffer = new byte[1024];
            while((len=in.read(buffer))>0) {
                out.write(buffer,0,len);
            }
            in.close();
            out.close();
        }
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }

    可以看到,其操作和java内文件的读取代码基本一致。通过这些学习我们就可以完成一个小案例——进行文件的下载。

    html界面:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
      <h1>使用a标签直接指向服务器上的资源</h1>
      <a href="/Day14/download/a.flv">a.flv</a><br>
      <a href="/Day14/download/a.jpg">a.jpg</a><br>
      <a href="/Day14/download/a.mp3">a.mp3</a><br>
      <a href="/Day14/download/a.mp4">a.mp4</a><br>
      <a href="/Day14/download/a.txt">a.txt</a><br>
      <a href="/Day14/download/a.zip">a.zip</a><br>
      <h1>使用服务器端编码的方式实现文件下载</h1>
      <a href="/Day14/DownloadServlet?filename=a.flv">a.flv</a><br>
      <a href="/Day14/DownloadServlet?filename=a.jpg">a.jpg</a><br>
      <a href="/Day14/DownloadServlet?filename=a.mp3">a.mp3</a><br>
      <a href="/Day14/DownloadServlet?filename=a.mp4">a.mp4</a><br>
      <a href="/Day14/DownloadServlet?filename=a.txt">a.txt</a><br>
      <a href="/Day14/DownloadServlet?filename=a.zip">a.zip</a><br>
      <a href="/Day14/DownloadServlet2?filename=美女.jpg">美女.jpg</a><br>
    </body>
    </html>

    servlet层:

    package content;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * Servlet implementation class DownloadServlet
     */
    @WebServlet("/DownloadServlet")
    public class DownloadServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public DownloadServlet() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            
            //获得要下载的文件的名称
            String filename = request.getParameter("filename");
            //要下载这个文件的类型-----客户端通过文件的MIME类型去区分类型
            response.setContentType(this.getServletContext().getMimeType(filename));
            
            //告诉客户端该文件不是直接解释,而是以附件打开
            response.setHeader("Content-Disposition", "attachment;filename="+filename);
            //获取文件的绝对路径
            String path = this.getServletContext().getRealPath("download/"+filename);
            //获得该文件的输入流
            InputStream in = new FileInputStream(path);
            //获得输出流---通过response获得的输出流用于向客户端写内容
            ServletOutputStream out = response.getOutputStream();
            //文件拷贝模版代码
            int len = 0;
            byte[] buffer = new byte[1024];
            while((len=in.read(buffer))>0) {
                out.write(buffer,0,len);
            }
            in.close();
            out.close();
        }
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }

    可以看到,操作和上面的写法基本一致。

    接下来是一个拓展操作,关于验证码的显示。验证码的生成代码并不需要我们自己来写,可以直接从网上copy一份,我们直接从前端获取就好,如下:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    <script>
      function changeImg(obj){
          obj.src="/Day14/CheckImg?time="+new Date().getTime();
      }
    </script>
    </head>
    <body>
      <form action="LoginServlet" method="post">
          用户名:<input type="text" name="username"><br>
          密码:<input type="password" name="password"><br>
         验证码<input type="text" name="password"><img onclick="changeImg(this)" src="/Day14/CheckImg">
          <input type="submit" value="登录">
      </form>
    </body>
    </html>

    通过查看验证码生成的servlet,就可以很简单的做好验证操作了。

    贴一下生成验证码的servlet:

      1 package cn.itcast.estore.web.servlet;
      2 
      3 import java.awt.Color;
      4 import java.awt.Font;
      5 import java.awt.Graphics;
      6 import java.awt.Graphics2D;
      7 import java.awt.image.BufferedImage;
      8 import java.io.BufferedReader;
      9 import java.io.FileReader;
     10 import java.io.IOException;
     11 import java.util.ArrayList;
     12 import java.util.List;
     13 import java.util.Random;
     14 
     15 import javax.imageio.ImageIO;
     16 import javax.servlet.ServletException;
     17 import javax.servlet.http.HttpServlet;
     18 import javax.servlet.http.HttpServletRequest;
     19 import javax.servlet.http.HttpServletResponse;
     20 
     21 /**
     22  * 验证码生成程序
     23  * 
     24  * 
     25  * 
     26  */
     27 public class CheckImgServlet extends HttpServlet {
     28 
     29     // 集合中保存所有成语
     30     private List<String> words = new ArrayList<String>();
     31 
     32     @Override
     33     public void init() throws ServletException {
     34         // 初始化阶段,读取new_words.txt
     35         // web工程中读取 文件,必须使用绝对磁盘路径
     36         String path = getServletContext().getRealPath("/WEB-INF/new_words.txt");
     37         try {
     38             BufferedReader reader = new BufferedReader(new FileReader(path));
     39             String line;
     40             while ((line = reader.readLine()) != null) {
     41                 words.add(line);
     42             }
     43             reader.close();
     44         } catch (IOException e) {
     45             e.printStackTrace();
     46         }
     47     }
     48 
     49     public void doGet(HttpServletRequest request, HttpServletResponse response)
     50             throws ServletException, IOException {
     51         // 禁止缓存
     52         // response.setHeader("Cache-Control", "no-cache");
     53         // response.setHeader("Pragma", "no-cache");
     54         // response.setDateHeader("Expires", -1);
     55 
     56         int width = 120;
     57         int height = 30;
     58 
     59         // 步骤一 绘制一张内存中图片
     60         BufferedImage bufferedImage = new BufferedImage(width, height,
     61                 BufferedImage.TYPE_INT_RGB);
     62 
     63         // 步骤二 图片绘制背景颜色 ---通过绘图对象
     64         Graphics graphics = bufferedImage.getGraphics();// 得到画图对象 --- 画笔
     65         // 绘制任何图形之前 都必须指定一个颜色
     66         graphics.setColor(getRandColor(200, 250));
     67         graphics.fillRect(0, 0, width, height);
     68 
     69         // 步骤三 绘制边框
     70         graphics.setColor(Color.WHITE);
     71         graphics.drawRect(0, 0, width - 1, height - 1);
     72 
     73         // 步骤四 四个随机数字
     74         Graphics2D graphics2d = (Graphics2D) graphics;
     75         // 设置输出字体
     76         graphics2d.setFont(new Font("宋体", Font.BOLD, 18));
     77 
     78         Random random = new Random();// 生成随机数
     79         int index = random.nextInt(words.size());
     80         String word = words.get(index);// 获得成语
     81 
     82         // 定义x坐标
     83         int x = 10;
     84         for (int i = 0; i < word.length(); i++) {
     85             // 随机颜色
     86             graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random
     87                     .nextInt(110), 20 + random.nextInt(110)));
     88             // 旋转 -30 --- 30度
     89             int jiaodu = random.nextInt(60) - 30;
     90             // 换算弧度
     91             double theta = jiaodu * Math.PI / 180;
     92 
     93             // 获得字母数字
     94             char c = word.charAt(i);
     95 
     96             // 将c 输出到图片
     97             graphics2d.rotate(theta, x, 20);
     98             graphics2d.drawString(String.valueOf(c), x, 20);
     99             graphics2d.rotate(-theta, x, 20);
    100             x += 30;
    101         }
    102 
    103         // 将验证码内容保存session
    104         request.getSession().setAttribute("checkcode_session", word);
    105 
    106         // 步骤五 绘制干扰线
    107         graphics.setColor(getRandColor(160, 200));
    108         int x1;
    109         int x2;
    110         int y1;
    111         int y2;
    112         for (int i = 0; i < 30; i++) {
    113             x1 = random.nextInt(width);
    114             x2 = random.nextInt(12);
    115             y1 = random.nextInt(height);
    116             y2 = random.nextInt(12);
    117             graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
    118         }
    119 
    120         // 将上面图片输出到浏览器 ImageIO
    121         graphics.dispose();// 释放资源
    122         
    123         //将图片写到response.getOutputStream()中
    124         ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
    125 
    126     }
    127 
    128     public void doPost(HttpServletRequest request, HttpServletResponse response)
    129             throws ServletException, IOException {
    130         doGet(request, response);
    131     }
    132 
    133     /**
    134      * 取其某一范围的color
    135      * 
    136      * @param fc
    137      *            int 范围参数1
    138      * @param bc
    139      *            int 范围参数2
    140      * @return Color
    141      */
    142     private Color getRandColor(int fc, int bc) {
    143         // 取其随机颜色
    144         Random random = new Random();
    145         if (fc > 255) {
    146             fc = 255;
    147         }
    148         if (bc > 255) {
    149             bc = 255;
    150         }
    151         int r = fc + random.nextInt(bc - fc);
    152         int g = fc + random.nextInt(bc - fc);
    153         int b = fc + random.nextInt(bc - fc);
    154         return new Color(r, g, b);
    155     }
    156 
    157 }
    生成验证码
  • 相关阅读:
    查看Java中每个数据类型所占的位数,和表示数值的范围,并得出结论。
    同名变量的屏蔽原则
    反码,补码,原码
    机器学习概念性知识总结
    图的最短路径问题
    System Design 笔记及代码(系统设计)
    2016网易游戏实习算法题解(今年找暑期实习的时候参加的)
    Google java style
    18.1---不用加号的加法(CC150)
    Java模板模式(template)
  • 原文地址:https://www.cnblogs.com/wushenjiang/p/12249177.html
Copyright © 2011-2022 走看看