zoukankan      html  css  js  c++  java
  • Servlet Response常用方法

    接下来记录一下Servlet Response相关的信息,在service方法中使用的是HttpServletResponse,它继承自ServletResponse,扩展了Http协议相关的内容,下面简单记录一下它的基本用法。

    response组成内容

    以下是一个常见response响应的内容,它包括状态行、响应头、一个空行和实体内容,其中"HTTP/1.1 200 OK"就是状态行,包括协议、状态代号和状态描述信息,下面有若干响应头,空行和实体内容这里没展示。

    HTTP请求中的常用响应头如下:
    1 Location: http://www.it315.org/index.jsp 配合302实现请求重定向
    2 Server:apache tomcat 服务器类型
    3 Content-Encoding: gzip 服务器发送数据的压缩格式
    4 Content-Length: 80 发送数据的长度
    5 Content-Language: zh-cn 发送数据的语言环境
    6 Content-Type: text/html; charset=GB2312 可接受数据格式和语言
    7 Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT 与请求头的if modified头呼应,主要跟缓存有关
    8 Refresh: 1;url=http://www.it315.org 定时刷新
    9 Content-Disposition: attachment;filename=aaa.zip 跟下载有关,下载文件名字aaa.zip
    10 Transfer-Encoding: chunked 分块编码
    11 Set-Cookie:SS=Q0=5Lb_nQ; path=/search
    12 ETag: W/"83794-1208174400000" Etag一般和MD5配合使用,验证文件完整性
    13 Expires: -1 通知浏览器是否缓存当前资源,如果这个头的值是一个以毫秒为单位的值,就是通知浏览器缓存资源到指定的时间点,如果值是0或-1则是通知浏览器禁止缓存。
    14 Cache-Control: no-cache 通知浏览器是否缓存的头,no-cache代表不缓存
    15 Pragma: no-cache 通知浏览器是否缓存的头,no-cache代表不缓存
    16 Connection: close/Keep-Alive 连接状态
    17 Date: Tue, 11 Jul 2000 18:23:51 GMT  Date可以用来判断是否来自缓存
     
    Response的方法,就是针对响应内容进行的,它可以设置状态码、设置响应头,设置响应内容。

    response常用方法

    response提供了常用的api,有如下三类,通过它可以实现response的诸多功能。

    设置状态码

    设置状态码有如下API

    (1)response.setStatus(int status) 设置状态码

    (2)response.setStatus(int status,String description),java8中已经被弃用了,被标记为过时deprecated

    下面设置状态码为404,测试。

     1 package com.boe.response;
     2 
     3 import javax.servlet.ServletException;
     4 import javax.servlet.annotation.WebServlet;
     5 import javax.servlet.http.HttpServlet;
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 import java.io.IOException;
     9 
    10 /**
    11  * 设置状态码
    12  */
    13 @WebServlet("/ResponseDemo05")
    14 public class ResponseDemo05 extends HttpServlet {
    15     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    16         //设置404
    17         response.setStatus(404);
    18         response.getWriter().write("Hello status");
    19     }
    20 
    21     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    22         doPost(request, response);
    23     }
    24 }

    访问页面后发现尽管能正常访问到资源,但是状态码被设置成了404。

    状态码404

    设置响应头

    设置影响头的方法,可以影响到页面的效果,有时候需要和上面设置状态码的方法配合使用,它常用的方法如下,前三个是set,后三个是add。

    (1)void setHeader(String name, String value)  用给定名称和值设置响应头。如果已经设置了头,则新值将重写以前的值。containsHeader 方法可用于测试在设置其值之前头是否存在
    (2)void setDateHeader(String name, long date) 给给定名称和日期值设置响应头,该日期根据距历元时间的毫秒数指定。如果已经设置了头,则新值将重写以前的值
    (3)void setIntHeader(String name, int value) 此方法的默认行为是对包装的响应对象调用 addIntHeader(String name, int value)。 
    (4)void addHeader(String name, String value) 用给定名称和值添加响应头,此方法允许响应头有多个值
    (5)void addDateHeader(String name, long date) 用给定名称和日期值添加响应头,该日期根据距历元时间的毫秒数指定,此方法允许响应头有多个值
    (6)void addIntHeader(String name, int value) 用给定名称和整数值添加响应头。此方法允许响应头有多个值
    关于API的使用,后面说功能时使用,以上常用的api就是setHeader,setDateHeader,后面response功能上面会使用这两种方法,下面简单了解一下setIntHeader方法,这个方法可以用在设置页面刷新频率,设置发送数据的长度等。
     1 package com.boe.response;
     2 
     3 import javax.servlet.ServletException;
     4 import javax.servlet.annotation.WebServlet;
     5 import javax.servlet.http.HttpServlet;
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 import java.io.IOException;
     9 
    10 /**
    11  * 设置使用setIntHeader方法
    12  */
    13 @WebServlet("/ResponseDemo06")
    14 public class ResponseDemo06 extends HttpServlet {
    15     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    16         //设置刷新
    17         /* response.setIntHeader("Refresh",2);
    18         response.getWriter().write("<font color='blue' size='10px'>this is setIntHeader method"+"+"+Math.random()*100+"</font>");*/
    19         //设置发送数据长度,一个英文字符代表1个长度
    20         response.setIntHeader("Content-Length",10);
    21         response.getWriter().write("I come from china");
    22 
    23     }
    24 
    25     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    26         doPost(request, response);
    27     }
    28 }

    实际效果,会每隔2秒刷新一次页面,这里没有截取gif,使用两张贴图记录一下。

    另外setIntHeader里如果设置Content-length,还可以控制输出到页面的数据长度,发现输出到页面的实际长度被截取了。

    设置响应消息

    有两种方法可以设置响应消息,如下。

    (1)ServletOutputStream getOutputStream() 
    (2)PrintWriter getWriter()  
    上文中的response.getWriter().write("Hello status"),就使用了PrintWriter。

    response常用功能

    response常用功能有请求重定向、控制缓存、页面刷新等。

    请求重定向

    请求重定向的原理就是设置状态码为302,并且在响应头里设置location的路径,就可以实现重定向,也可以直接使用现成api来实现。

     1 package com.boe.response;
     2 
     3 import javax.servlet.ServletException;
     4 import javax.servlet.annotation.WebServlet;
     5 import javax.servlet.http.HttpServlet;
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 import java.io.IOException;
     9 
    10 /**
    11  * 请求重定向
    12  */
    13 @WebServlet("/ResponseDemo02")
    14 public class ResponseDemo02 extends HttpServlet {
    15     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    16         //原理实现
    17         //设置状态码
    18         response.setStatus(302);
    19         //设置消息头
    20         response.setHeader("Location","http://www.baidu.com");
    21 
    22         //api实现
    23         //以上代码等效如下代码
    24         //response.sendRedirect("http://www.baidu.com");
    25     }
    26 
    27     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    28         doPost(request, response);
    29     }
    30 }

    访问ResponseDemo02后页面跳转到百度,重定向的地址是会改变的。

    控制缓存

    控制缓存有三个api可以使用,可以通过设置影响头的Cache-Control、Pragma和Expires来控制,参考前面对响应头的介绍和如下代码。

     1 package com.boe.response;
     2 
     3 import javax.servlet.ServletException;
     4 import javax.servlet.annotation.WebServlet;
     5 import javax.servlet.http.HttpServlet;
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 import java.io.IOException;
     9 import java.util.Date;
    10 
    11 /**
    12  * 浏览器缓存的设置
    13  */
    14 @WebServlet("/ResponseDemo04")
    15 public class ResponseDemo04 extends HttpServlet {
    16     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    17         //设置不使用缓存
    18         /*public void setDateHeader(String name, long date)
    19         用给定名称和日期值设置响应头。该日期根据距历元时间的毫秒数指定。如果已经设置了头,则新值将重写以前的值。
    20         containsHeader 方法可用于测试在设置其值之前头是否存在。*/
    21         //方式1
    22         if(response.containsHeader("Expires")){
    23             response.setDateHeader("Expires",-1);
    24         }
    25         //方式2
    26         response.setHeader("Cache-Control","no-cache");
    27         //方式3
    28         response.setHeader("Pragma","no-cache");
    29 
    30         Date date=new Date();
    31         String time = date.toLocaleString();
    32         //设置使用缓存
    33         //response.setDateHeader("Expires",System.currentTimeMillis()+1000*60*60*1);//1 hour
    34         //response.setHeader("Cache-Control","max-age=60");//60 s
    35 
    36         response.getWriter().write("<font color='blue'>"+time+"</font>");
    37 
    38 
    39     }
    40 
    41     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    42         doPost(request, response);
    43     }
    44 }

    当不使用缓存时,每次刷新一下页面,就会打印新的时间,这里就不展示了。当设置完使用缓存,在缓存的寿命范围内,时间都不会变的,目前在IE和火狐浏览器测试可以,chrome没有效果。

    页面刷新 

    页面刷新可以设置响应头的Refresh,里面一个时间参数单位为秒,一个刷新后页面的url地址,注意使用url,这个可以用在注册后隔几秒跳转到主页这种场景。以下代码就是实现访问ResponseDemo03请求后,等待3秒会刷新进入百度主页的功能。

     1 package com.boe.response;
     2 
     3 import javax.servlet.ServletException;
     4 import javax.servlet.annotation.WebServlet;
     5 import javax.servlet.http.HttpServlet;
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 import java.io.IOException;
     9 
    10 /**
    11  * 定时刷新
    12  */
    13 @WebServlet("/ResponseDemo03")
    14 public class ResponseDemo03 extends HttpServlet {
    15     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    16         //3 秒
    17         response.setHeader("Refresh","3;url=http://www.baidu.com");
    18     }
    19     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    20         doPost(request, response);
    21     }
    22 }

    response乱码处理

    涉及到响应,势必可能会有服务器和浏览器编解码不一致的问题,并会产生乱码,接下来使用字节流和字符流发送数据,查看乱码情况,使用如下基准代码进行调试,根据测试条件做调整即可。

     1 package com.boe.response;
     2 
     3 import javax.servlet.ServletException;
     4 import javax.servlet.annotation.WebServlet;
     5 import javax.servlet.http.HttpServlet;
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 import java.io.IOException;
     9 
    10 /**
    11  * 响应字节流和字符流的乱码处理
    12  */
    13 @WebServlet("/ResponseDemo01")
    14 public class ResponseDemo01 extends HttpServlet {
    15     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    16         //1 字节流
    17         System.out.println(response.getCharacterEncoding());
    18         //ISO-8859-1 tomcat默认的字符编码,针对字符流,对字节流无影响
    19         //response.getOutputStream().write("china".getBytes());
    20         //getByte()默认使用平台的字符编码,即GBK,而浏览器默认使用GBK解码,因此没有乱码
    21         //response.getOutputStream().write("中国".getBytes());
    22         /**
    23          * 一般浏览器都会设置utf-8解码,这里需指定服务器编码方式为utf-8,设置浏览器解码也是utf-8
    24          */
    25         //通知浏览器使用utf-8来解码
    26         /*response.setHeader("Content-Type","text/html;charset=utf-8");
    27         response.getOutputStream().write("中国".getBytes("utf-8"));*/
    28 
    29         //2 字符流
    30         //默认使用iso-8859-1将字符流转变成字节流,底层由Tomcat服务器来完成,会使用Tomcat默认的字符集
    31         //通知服务端发送数据时字符集utf-8
    32         //response.setCharacterEncoding("utf-8");
    33         //如果告诉浏览器使用何种字符集,则这句可以不用写,服务会在发送数据自动采用浏览器设置的字符集
    34         //通知浏览器指定utf-8读取
    35         //response.setHeader("Content-Type","text/html;charset=utf-8");
    36 
    37         //也可以用如下api
    38         //response.setContentType("text/html;charset=utf-8");
    39         //response.getWriter().write("我是英文");
    40     }
    41 
    42     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    43         doPost(request, response);
    44     }
    45 }

    字节流发送数据

    使用字节流发送数据使用ServletOutputStream的write方法,使用发现在不设置任何编码格式的情况下,浏览器能正常显示中文,并没有乱码产生,通过查看响应头发现也没有指定Content-Type。

    这是因为用getByte方法得到字节数组时,使用的是平台默认的字符集,即GBK,而当不指定浏览器解码字符集时也是使用平台默认的字符集GBK,两者一致因此没有产生乱码。

    一般浏览器会使用utf-8来解码,因此需要使用如下代码指定浏览器的解码字符集,以及服务器的编码字符集均为utf-8。

    1 response.setHeader("Content-Type","text/html;charset=utf-8");
    2 response.getOutputStream().write("中国".getBytes("utf-8"))

    修改后发现响应头里有指定Content-Type。

    字符流发送数据

    使用字符流发送数据使用PrintWriter的write方法,在不设置字符集的情况下,发现'我是英文'四个字显示四个问号,产生了乱码问题。

    这是因为字符流本质上还是会转化为字节流,当服务器不指定字符编码时,会默认使用tomcat的字符编码,即iso-8859-1,而浏览器不指定解码时默认使用GBK,因此会产生乱码,另外iso-8859-1是单字节编码无法表示中文,'我是英文'最后返回给浏览器3f 3f 3f 3f,显示四个问号。

    想要解决乱码问题也是通过统一编码方式,服务端使用setCharacterEncoding的方法指定,浏览器字符集有两种方法指定,两种都可以,本质上就是设置响应头里的Content-Type。

    1 //默认使用iso-8859-1将字符流转变成字节流,底层由Tomcat服务器来完成,会使用Tomcat默认的字符集
    2 //通知服务端发送数据时字符集utf-8
    3 //response.setCharacterEncoding("utf-8");
    4 //如果告诉浏览器使用何种字符集,则这句可以不用写,服务会在发送数据自动采用浏览器设置的字符集
    5 //通知浏览器指定utf-8读取
    6 //response.setHeader("Content-Type","text/html;charset=utf-8");
    7  
    8 //也可以用如下api
    9 //response.setContentType("text/html;charset=utf-8");

    修改后浏览器能正常显示中文。

     
    参考博文:
    (2)https://www.jianshu.com/p/da01a20a515e 分块编码Transfer-Encoding
    (5)https://www.jianshu.com/p/53fbd4d91a31 utf-8,gbk2312,iso-8859-1字符集
     
  • 相关阅读:
    SAP PI 如何实现消息定义查询
    EWM与ERP交互程序
    ITS Mobile Template interpretation failed. Template does not exist
    SAP Material Flow System (MFS) 物料流系统简介
    SAP EWM Table list
    EWM RF 屏幕增强
    SAP EWM TCODE list
    SAP扩展仓库管理(SAPEWM)在线研讨会笔记
    ERP与EWM集成配置ERP端组织架构(二)
    EWM RF(Radio Frequency)简介
  • 原文地址:https://www.cnblogs.com/youngchaolin/p/11533181.html
Copyright © 2011-2022 走看看