• Response


    Response对象代表响应

    响应由三部分组成:

    1. 响应行(状态码)
    2. 响应头
    3. 响应数据

    用处:

    • 向客户端浏览器输出中文
    • 下载一个图片
    • 向页面中加入动态图片(验证码)
    • 控制浏览器定时刷新(使用refresh)
    • 控制浏览器缓存(使用expires)
    • 使用重定向

    相关方法:

          getStatus

          setHeader

          getWrite和getOutputStream

    其中写数据可以分为两种方式

    • 字节流  可以写任何格式的数据 
    • 字符流  只能写字符数据

    1 如何向客户端浏览器输出中文

    输出中文就涉及到编码和乱码形成的问题

    不是把汉字写到客户端,而是先写到response里面

    计算机或者网络之间的通信是没有汉字通信的,都是数字(二进制)通信

    所以要把汉字通过一定的方式转化为数字

    首先是把汉字通过编码(比如java内部的unicode编码翻译成十六进制等,然后再通过TCP/ip协议向下封装,最后转化为二进制)

    1. 字节流

    使用字节流,必须先把字符串转化为字节

    public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            String dataString = "中国";
            OutputStream outputStream  = response.getOutputStream();
            //要以字节流输出,所以要先把汉字转化为字节
            outputStream.write(dataString.getBytes());
        }

    这种方式在浏览器上是没有问题的

    但是在实际开发中,为了全球通用,一般是使用UTF-8

    但是如果指定传输字节格式

    public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            String dataString = "中国";
            OutputStream outputStream  = response.getOutputStream();
            //指定汉字传输格式
            outputStream.write(dataString.getBytes("UTF-8"));
        }

    把汉字变成字节的过程就是把从编码表上查出汉字对应的数字,然后把数字放在一个数组里面给客户机

    这里查的是UTF-8编码表

    那么在浏览器上就会出现乱码(即是其他的字)

    原因:

    • 当把汉字定义成UTF-8时,传输的并不是汉字,而是其中对应的编码,即是数字。
    • 当把数字传给浏览器时,浏览器要进行解码,但是浏览器默认的解码方式是国标gb2312

    所以会解析成其他的字

    servlet写给浏览器的不是汉字中国,而是它所对应的编码

    解决:

    • 在浏览器设置里面改动编码方式
    • 在服务器代码里设定浏览器的解码方式
    public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            //加入响应头
            response.setHeader("Content-type", "text/html;charset=UTF-8");
    
            String dataString = "中国";
            OutputStream outputStream  = response.getOutputStream();
            
            outputStream.write(dataString.getBytes("UTF-8"));
        }

    这样的话就没有问题了。

    2. 字符流

    因为汉字本身是字符串,所以用字符流会更方便一些

     直接向response内写入一个字符流就行了,同时要注意编码

    response在进行字符编码的时候默认使用的是java默认的unicode编码

    public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            //设置response使用的码表,以控制respose以什么码表向浏览器写出数据
            response.setCharacterEncoding("UTF-8");
            //指定浏览器以什么码表打开服务器发送来的数据
            response.setHeader("content-type","text/html;charset=UTF-8");
            
            //以上两句的设置可以用这一句代替
            //response.setContentType("text/html;charset=UTF-8");
            
            String data = "中国";
            PrintWriter out = response.getWriter();
            out.write(data);        
        }

    2 如何使用response下载一个图片

    public class ResponseDemo extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {    
    
            //1.读这个文件(这个文件其实就是web里面的资源,在servlet里读的话用servletcontext,在普通类中使用类加载器)
            //2.读资源的话有两种方式,一种是把资源作为资源流输出, 一种是使用资源的绝对地址(这种方法可以得到文件的一些信息,比如文件名)
            String  path = this.getServletContext().getRealPath("/DownLoad/1.jpg");
            String filename = path.substring(path.lastIndexOf("\")+1);
            
            //通知浏览器怎么打开
            //如果下载文件是中文名称,需要使用url编码
            response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(filename,"UTF-8"));
            InputStream in= null;
            OutputStream out= null;
            try{
                in = new FileInputStream(path);
                int len = 0;
                byte buffer[] = new byte[1024];
                out = response.getOutputStream();
                while((len = in.read(buffer))>0){
                    out.write(buffer,0,len);
                }
            }finally{
                if(in !=null){
                    try{
                       in.close();
                    }catch(Exception e){
                       e.printStackTrace();
                    }
                }
                if(out !=null){
                    try{
                       out.close();
                    }catch(Exception e){
                       e.printStackTrace();
                    }
                }
            }
            
            
        }

    3. 如何向页面中加入动态图片(验证码)

    //构建一副图片(含有汉字的验证码图片)
    public class ResponseDemo2 extends HttpServlet {
        
    //定义图片的长和宽
    public static final int WIDTH = 200; public static final int HEIGTH = 50; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.首先在内存中构造一个图片 bufferimage 内存中的一张图片 //2.构造图象 //3.把内存中的图像输出到浏览器 //在内存中构建图像 BufferedImage image = new BufferedImage(WIDTH,HEIGTH ,BufferedImage.TYPE_INT_BGR); //向图像中写数据,拿到这个图像 Graphics g = image.getGraphics(); //1.设置背景色 setBackGround(g); //2.设置边框 setBorder(g); //3.画干扰线 drawRandomLine(g); //4.写随机数 //Graphics2D 可以旋转字符 drawRandomNumber((Graphics2D)g); //把图像写给浏览器,通过severlet的输出流 //先通知浏览器以什么格式打开,否则默认以文本打开 response.setContentType("image/jpeg"); //同时控制浏览器不能存放图片的缓存,不然刷新浏览器不能更新图片 response.setHeader("Cache-Control", "no-cache"); response.setHeader("Pragma", "no-cache");


    //向浏览器中输出图片 ImageIO.write(image,
    "jpg", response.getOutputStream()); } private void drawRandomNumber(Graphics2D g) { g.setColor(Color.RED); g.setFont(new Font("宋体",Font.BOLD, 20)); //汉字区间 ,java使用的是unicode码表,汉字在内存中存的不是汉字,都是它所对应的码值 //所有汉字都在unicode码表的4e00到9fa5
    //用正则表达式测试一个字符是不是汉字 [^u4e00-u9fa5] //常用汉字 String base = "u7684u4e00u662fu4e86u6211u4e0du4ebau5728u4ed6u6709u8fd9u4e2au4e0au4eecu6765u5230u65f6u5927u5730u4e3au5b50u4e2du4f60u8bf4u751fu56fdu5e74u7740u5c31u90a3u548cu8981u5979u51fau4e5fu5f97u91ccu540eu81eau4ee5u4f1au5bb6u53efu4e0bu800cu8fc7u5929u53bbu80fdu5bf9u5c0fu591au7136u4e8eu5fc3u5b66u4e48u4e4bu90fdu597du770bu8d77u53d1u5f53u6ca1u6210u53eau5982u4e8bu628au8fd8u7528u7b2cu6837u9053u60f3u4f5cu79cdu5f00u7f8eu603bu4eceu65e0u60c5u5df1u9762u6700u5973u4f46u73b0u524du4e9bu6240u540cu65e5u624bu53c8u884cu610fu52a8u65b9u671fu5b83u5934u7ecfu957fu513fu56deu4f4du5206u7231u8001u56e0u5f88u7ed9u540du6cd5u95f4u65afu77e5u4e16u4ec0u4e24u6b21u4f7fu8eabu8005u88abu9ad8u5df2u4eb2u5176u8fdbu6b64u8bddu5e38u4e0eu6d3bu6b63u611fu89c1u660eu95eeu529bu7406u5c14u70b9u6587u51e0u5b9au672cu516cu7279u505au5916u5b69u76f8u897fu679cu8d70u5c06u6708u5341u5b9eu5411u58f0u8f66u5168u4fe1u91cdu4e09u673au5de5u7269u6c14u6bcfu5e76u522bu771fu6253u592au65b0u6bd4u624du4fbfu592bu518du4e66u90e8u6c34u50cfu773cu7b49u4f53u5374u52a0u7535u4e3bu754cu95e8u5229u6d77u53d7u542cu8868u5fb7u5c11u514bu4ee3u5458u6d4eu8499u68cbu7aefu817fu62dbu91cau4ecbu70e7u8bef"; int x = 10; for (int i = 0; i < 5; i++) { //得到-30到30的随机数 int degree = new Random().nextInt()%30; String ch = base.charAt(new Random().nextInt(base.length()))+""; //设置旋转幅度 g.rotate(degree*Math.PI/180,x,20); g.drawString(ch, x, 20); g.rotate(-degree*Math.PI/180,x,20); x+=30; } } private void drawRandomLine(Graphics g) { g.setColor(Color.GREEN); for(int i=0;i<8;i++){ int x1= new Random().nextInt(WIDTH); int y1 = new Random().nextInt(HEIGTH); int x2= new Random().nextInt(WIDTH); int y2 = new Random().nextInt(HEIGTH); g.drawLine(x1, y1, x2, y2); } } private void setBorder(Graphics g) { //把图形上下文设置成白色 g.setColor(Color.BLUE); //用白色填充这个矩形 g.drawRect(1,1,WIDTH-2, HEIGTH-2); } private void setBackGround(Graphics g) { //把图形上下文设置成白色 g.setColor(Color.WHITE); //用白色填充这个矩形 g.fillRect(0,0,WIDTH, HEIGTH); } }

    然后把上面的图片加到一个html页面中:

    <!DOCTYPE html>
    <html>
      <head>
        <title>register.html</title>
      </head>
      
      <body>
        <form action="">
           
            用户名:<input type="text"><br/>
            认证码:<input type="text"><img src="/day1121/servlet/ResponseDemo2" onclick="changeImage(this)" alt="换一张"  style="cursor:hand">
            
        </form>
      </body>
      
      <script type="text/javascript">
         function changeImage(img){
           img.src = img.src +"?" + new Date().getTime();
    /*     在src后面加上一个随机数的目的是使得两次的url不同,这样就不会使用缓存里的图片 */
         }
      </script> 
      
    </html>

    4.控制浏览器定时刷新(使用refresh)

    1. 本页面重新请求服务器

    //控制浏览器定时刷新
    public class ResponseDemo4 extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            
            ////每隔3秒重新请求一次服务器
            response.setHeader("refresh", "3");
            String data = new Random().nextInt(100000)+"";        
            response.getWriter().write(data);
        }
    }

    2.登陆成功后,跳转到其他页面

    public class ResponseDemo4 extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            
            response.setContentType("text/html;charset=UTF-8");
            response.setHeader("refresh","3;url='/day1121/index.jsp");
            response.getWriter().write("恭喜你,登陆成功。本浏览器将在3秒后跳转到首页,如果没有跳转,请点击<a href='www.baidu.com'>超链接</a>");
        }
    }

    5.控制浏览器缓存(使用expires)

    public class ResponseDemo5 extends HttpServlet {
    
        //控制浏览器缓存
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            //缓存一小时
            //这样在一个小时之内请求此servlet都不会向浏览器发送请求,而是直接找系统中的页面
            //IE浏览器的缓存可以直接在文件夹中查看
            response.setDateHeader("expires",System.currentTimeMillis()+ 1000*3600);        
            String dataString = "ada";
            response.getWriter().write(dataString);
        }
    }

    6.使用重定向

    重定向的特点

    • 1.客户端会向服务器发送两次请求,以为着会有两个response和request
    • 2.重定向技术地址栏会发生变化
    public class ResponseDemo6 extends HttpServlet {
        
        //实现请求重定向
        //请求重定向能不用就不用吧,因为客户端会发送两次请求,加重服务器压力
        //一定要使用请求重定向的地方:
      //1.登陆
      //因为请求重定向会使得地址栏地址发生变化,当登陆成功后跳转到首页要在地址栏显示
        //2.购物
       //当servlet购买成功后,会跳转到购物车显示页面
        //如果使用转发,购买成功后如果每次刷新,会重复买
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            //方法1. 根据http协议
            response.setStatus(302);
            response.setHeader("location", "/day1121/index.jsp");
            
            //方法2.根据sun公司的封装方法
         //相当于上面的两句
            response.sendRedirect("/day1121/index.jsp");
        }
    }
  • 相关阅读:
    sql server中sql语句中单引号怎么转义?【转】
    如何配置Eclipse+Tomcat 开发环境【转】
    JBoss和Tomcat版本、及Servlet、JSP规范版本对应一览 【转】
    P1955 [NOI2015]程序自动分析 && 离散化学习 && lower_bound学习
    P1604 B进制星球
    [OI
    [OI
    Aiyi's Code Style for OI
    POJ1186 方程的解数
    [Daily Life]百首好歌
  • 原文地址:https://www.cnblogs.com/tech-bird/p/4116658.html
Copyright © 2020-2023  润新知