美文网首页
Servlet三——响应对象

Servlet三——响应对象

作者: 嗷老板 | 来源:发表于2018-03-31 20:32 被阅读0次

    一、响应对象的概述

      WEB服务器会针对每一个客户端发出的HTTP请求,分别的创建一个请求对象和一个响应对象。如果需要向客户端发送一些数据,需要使用响应对象。
      在之前的文章中,作者介绍了HTTP协议响应的组成,主要包括三个部分:响应行、响应头、响应体。这里不再过多介绍,重点介绍一下响应行中的响应码:

    • 1XX:浏览器发送的请求信息不完善,需要浏览器进一步补充资料
    • 2XX:响应正常完成
    • 3XX:本次请求已经完成,但是需要浏览器进行进一步的操作
    • 4XX:请求的资源错误
    • 5XX:服务器端错误

    二、向客户端发送中文的乱码问题

    1、原因

      我们在向客户端发送英文时,没有出现任何的问题,但是发送中文时,会出现乱码问题:

    response.getWriter().println("你好");
    
    中文乱码问题

      为什么会出现这种情况呢?
      我们通过调用响应对象的方法查看服务器发送数据的默认编码

        String encoding = response.getCharacterEncoding();
        response.getWriter().println(encoding);
    
    服务器发送数据默认编码

      而浏览器接收数据默认的编码格式为GBK,发送数据和接收数据的编码不一致,导致出现乱码问题。

    2、解决方式

    (1)字节流传输数据的解决方式

      我们可以通过调用响应对象获取字节输出流对象,调用write方法传输数据,由于字节输出流的默认编码就是GBK,所以不会出现乱码问题

    package com.demo;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class Demo4 extends HttpServlet {
        
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            ServletOutputStream os = response.getOutputStream();
            os.write("你好".getBytes());
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }
    
    字节流传输数据

    (2)字符流传输数据的解决方式

      使用字符流传输数据,我们需要告诉浏览器使用什么方式进行解码。

    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class Demo4 extends HttpServlet {
        
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("text/html;charset=UTF-8");
            
            response.getWriter().println("你好");
            
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }
    
    字符流传输数据

    三、响应头Refresh

      我们在访问文字直播网站的时候,经常能够发现网页每隔一段时间就会自动刷新;或者有时候支付宝在完成支付后,会有一个几秒后跳转回商家的提示页面,这些都可以用Refresh来实现。

    Refresh的作用:

    • 定时自动刷新
      response.setHeader("Refresh", 时间);
      示例:
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class Demo7 extends HttpServlet {
        
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().println("3秒后自动刷新!");
            response.setHeader("Refresh", "3");
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }
    
    定时自动刷新
    • 定时自动跳转
        跳转外部资源:response.setHeader("Refresh", "3;URL=https://www.baidu.com");
        跳转内部资源:response.setHeader("Refresh", "3;URL=/demo/Demo4")

    示例:

    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class Demo7 extends HttpServlet {
        
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().println("3秒后自动跳转到百度首页!");
            response.setHeader("Refresh", "3;URL=https://www.baidu.com");
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }
    
    跳转前
    跳转后

    跳转与转发的区别:

    • 转发:
        共享请求和响应对象
        只能是内部地址
        地址栏不会发生变化
    • 跳转:
        不共享
        内部地址和外部地址都可以
        地址栏会发生变化

    四、请求重定向

      一个WEB资源接收到客户端的请求之后,通知这个客户端去访问(请求)另外的一个WEB资源。

    示例:

    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class Demo8 extends HttpServlet {
        
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.sendRedirect("/demo/Demo4");
        }
    
        
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }
    
    请求重定向1
    请求重定向2

    转发和重定向的区别:

    • 请求次数:
        转发:一次请求一次相应
        重定向:两次请求两次响应
    • 浏览器的地址:
        转发:地址栏保持初值不会改变
        重定向:改变为重定向的页面
    • 作用范围:
        转发:只能是同一个项目的页面
        重定向:可以定向任意的页面,内部页面或者外部页面
    • URL以“/”开头的含义不同
        转发:代表当前web应用的根路径
        重定向:代表web服务器的根路径,重定向内部页面必须加上项目名
    • 变量的作用域:
        转发:request存放的变量不会失效(request域对象)
        重定向:request存放的变量失效,进入了一个新的request域。


      转发-包含-重定向的区别

    五、文件下载案例

    import java.io.FileInputStream;
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class Demo9 extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // 设置响应头
            response.setHeader("content-disposition", "attachment;filename=tomcat.png");
            // 获取字节输出流对象
            ServletOutputStream os = response.getOutputStream();
            // 创建字节输入流对象
            String path = getServletContext().getRealPath("/WEB-INF/tomcat.png");
            FileInputStream fis = new FileInputStream(path);
            //循环读取并向客户端发送数据
            int len = 0;
            byte[] bys = new byte[1024];
            while((len = fis.read(bys)) != -1){
                os.write(bys,0,len);
            }
            
            //释放资源
            fis.close();
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }
    
    
    下载文件1
    下载文件2

    注意:
      响应头中不能有中文,中文被认为是不安全的字符。如果必须有中文,那么需要将中文转义为UTF-8编码。

    String s = URLEncoder.encode("美女.jpg");
    response.setHeader("Content-disposition", "attachment;filename=" + s);
    

    相关文章

      网友评论

          本文标题:Servlet三——响应对象

          本文链接:https://www.haomeiwen.com/subject/onzwcftx.html