zoukankan      html  css  js  c++  java
  • HttpServletResponse对象(一)

    Servlet是服务器端程序,主要用来交互式地浏览和修改数据,生成动态web内容。web服务器接收到客户端的Servlet请求后,如果检查到已经装载并创建了该Servlet的实例对象,则会创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表Http响应消息的HttpServletResponse对象,然后调用Servlet的service()方法,将请求和响应对象作为参数传递进去,这样客户端通过HttpServletRequest对象将请求发送给服务器,服务器通过HttpServletResponse对象将响应传递给客户端,达到通信的目的。

    1. HttpServletResponse对象介绍

    HttpServletResponse是一个继承了ServletResponse的接口,这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。查看HttpServletResponse的API,可以看到这些相关的方法。这里给出一个java EE的api帮助文档的链接:https://docs.oracle.com/javaee/7/api/

    1.1 负责向客户端发送数据的相关方法

    getOutputStream()方法用于返回Servlet引擎创建的字节输出流对象,Servlet程序可以按字节形式输出响应正文。而getWriter()方法用于返回Servlet引擎创建的字符输出流对象,Servlet程序可以按字符形式输出响应正文。

    其实PrintWriter对象输出字符文本内容时,它内部还是将字符串转换成了某种字符集编码的字节数组后再进行输出,使用PrintWriter对象的好处就是不用编程人员自己来完成字符串到字节数组的转换。 使用ServletOutputStream对象也能输出内容全为文本字符的网页文档,但是,如果网页文档内容是在Servlet程序内部使用文本字符串动态拼凑和创建出来的,则需要先将字符文本转换成字节数组后输出。这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。

    1.2 负责向客户端发送响应头的相关方法

    响应头向客户端提供一些额外信息,比如谁在发送响应、响应者的功能,甚至与响应相关的一些特殊指令。这些头部有助于客户端处理响应,并在将来发起更好的请求。

    1.3 负责向客户端发送响应状态码的相关方法

    当我们搜索一个页面找不到时,经常出现404 NOT FOUND,这个就是通过setStatus(int sc)这个方法实现的。

    1.4 响应状态码的常量

    HttpServletResponse定义了很多状态码的常量(具体可以查看Servlet的API),当需要向客户端发送响应状态码时,可以使用这些常量,避免了直接写数字,常见的状态码对应的常量:

    404:

    200:

    500:

    2. HttpServletResponse对象常见应用

    2.1 使用OutputStream流向客户端浏览器输出中文数据

    在服务器端,数据是以哪个码表输出的,那么就要控制客户端浏览器以相应的码表打开,比如:outputStream.write("中国".getBytes("UTF-8"));使用OutputStream流向客户端浏览器输出中文,以UTF-8的编码进行输出,此时就要控制客户端浏览器以UTF-8的编码打开,否则显示的时候就会出现中文乱码,那么在服务器端如何控制客户端浏览器以以UTF-8的编码显示数据呢?可以通过设置响应头控制浏览器的行为,例如:response.setHeader("content-type", "text/html;charset=UTF-8");通过设置响应头控制浏览器以UTF-8的编码显示数据。

    示例代码:

    package myTest;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class OutputStreamDemo extends HttpServlet {
    
        private static final long serialVersionUID = 4312868947607181532L;
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
        	
        	//使用OutputStream流输出中文
            outputChineseByOutputStream(response);
        }
        
        /**
         * 使用OutputStream流输出中文
         * @param request
         * @param response
         * @throws IOException 
         */
        public void outputChineseByOutputStream(HttpServletResponse response) throws IOException{
            String data = "使用OutputStream流向浏览器输出中文";
            //获取OutputStream输出流
            OutputStream outputStream = response.getOutputStream();
            //通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码
            response.setHeader("content-type", "text/html;charset=UTF-8");
            //将字符转换成字节数组,指定以UTF-8编码进行转换
            byte[] dataByteArr = data.getBytes("UTF-8");
            //使用OutputStream流向客户端输出字节数组
            outputStream.write(dataByteArr);
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    
    }
    

     data.getBytes()是一个将字符转换成字节数组的过程,这个过程中一定会去查码表,如果是中文的操作系统环境,默认就是查找查GB2312的码表,将字符转换成字节数组的过程就是将中文字符转换成GB2312的码表上对应的数字。

    配置web.xml,运行后输出如下结果:

    2.2 使用PrintWriter流向客户端浏览器输出中文数据

      1. 在获取PrintWriter输出流之前首先使用"response.setCharacterEncoding(charset)"设置字符以什么样的编码输出到浏览器,如:response.setCharacterEncoding("UTF-8");设置将字符以"UTF-8"编码输出到客户端浏览器,然后再使用response.getWriter();获取PrintWriter输出流,这两个步骤不能颠倒。即:

    //设置将字符以"UTF-8"编码输出到客户端浏览器
    response.setCharacterEncoding("UTF-8");
    //获取PrintWriter输出流
    PrintWriter out = response.getWriter();
    

      2. 再使用response.setHeader("content-type", "text/html;charset=字符编码");设置响应头,控制浏览器以指定的字符编码编码进行显示。

    //通过设置响应头控制浏览器以UTF-8的编码显示数据(浏览器向客户端输出为UTF-8形式)
    response.setHeader("content-type", "text/html;charset=UTF-8");
    

     示例代码如下:

    package myTest;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class PrintWriterDemo extends HttpServlet {
    
        private static final long serialVersionUID = 4312868947607181532L;
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
        	//使用PrintWriter流输出中文
            outputChineseByPrintWriter(response);
        }
    
        /**
         * 使用PrintWriter流输出中文
         * @param request
         * @param response
         * @throws IOException 
         */
        public void outputChineseByPrintWriter(HttpServletResponse response) throws IOException{
            String data = "使用PrintWriter流输出中文";
            //设置将字符以"UTF-8"编码输出到客户端浏览器
            response.setCharacterEncoding("UTF-8");
            //获取PrintWriter输出流
            PrintWriter out = response.getWriter();
            response.setHeader("content-type", "text/html;charset=UTF-8");
            //使用PrintWriter流向客户端输出字符
            out.write(data);
        }
        
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    }
    

     配置web.xml文件,运行后显示结果:

    对比可以看出,使用OutputStream流输出中文时,首先要将字符转换成字节。当需要向浏览器输出字符数据时,使用PrintWriter比较方便,省去了将字符转换成字节数组那一步。

    2.3 使用OutputStream或者PrintWriter向客户端浏览器输出数字

    示例代码如下:

    package myTest;
    
    import java.io.IOException;
    import java.io.OutputStream;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class NoDemo extends HttpServlet {
    
        private static final long serialVersionUID = 4312868947607181532L;
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
        	//使用OutputStream输出1到客户端浏览器
            outputOneByOutputStream(response);
        }
    
        /**
         * 使用OutputStream流输出数字1
         * @param request
         * @param response
         * @throws IOException 
         */
        public void outputOneByOutputStream(HttpServletResponse response) throws IOException{
            response.setHeader("content-type", "text/html;charset=UTF-8");
            OutputStream outputStream = response.getOutputStream();
            outputStream.write("使用OutputStream流输出数字1:".getBytes("UTF-8"));
            outputStream.write((1+" ").getBytes("UTF-8"));
        }
        
    }
    

     关键在于outputStream.write((1+" ").getBytes("UTF-8")); 1+""这一步是将数字1和一个空字符串相加,这样处理之后,数字1就变成了字符串1了,然后再将字符串1转换成字节数组使用OutputStream进行输出。运行结果如下:

    如果使用PrintWriter流输出数字,那么也要先将数字转换成字符串后再输出,代码如下:

    public void outputOneByPrintWriter(HttpServletResponse response) throws IOException{
            response.setHeader("content-type", "text/html;charset=UTF-8");
            response.setCharacterEncoding("UTF-8");
    //获取PrintWriter输出流 PrintWriter out = response.getWriter(); out.write("使用PrintWriter流输出数字1:"); out.write(1+""); }

    在开发过程中,如果希望服务器输出什么浏览器就能看到什么,那么在服务器端都要以字符串的形式进行输出。

     欢迎搜索微信公众号“程序员考拉”,关注更多精彩内容!

  • 相关阅读:
    LeetCode刷题之字符串
    LeetCode刷题之数组复习
    为什么要用移码来表示阶码(指数)呢?
    字节左移跟右移
    一个有趣的问题
    为什么对数组名取地址,得到的为整个数组的地址?
    在win10 64位下搭建汇编环境
    windows切换samba账号进行连接
    samba服务配置记录
    subversion钩子函数使用记录
  • 原文地址:https://www.cnblogs.com/naihuangbao/p/9705625.html
Copyright © 2011-2022 走看看