Response容器详解

Response和我们在之前说到的Request容器是一一对应的,他是web容器在用户每次请求服务端的时候,创建的一对容器对象,Response容器是服务端返还给客户机的一个响应内容对象容器,比如说:响应头,响应行,实体数据等信息,而Request容器对象是,代表用户请求服务端的的一个容器对象,比如客户机的请求头,请求行,以及携带的参数信息等。所以说Request容器对象和Response容器对象是一一对应的,他们两的生命周期也是一样的,就是在一次用户请求中。

下面先来看一下Response对象的相关方法吧:

addCookie(Cookie cookie):这个方法是向Response容器中添加一个Cookie,然后服务器容器会自动的将这个Cookie回写给客户机的,至于Cookie的相关知识我们会在后面的文章中进行详解,这篇文章中这个方法暂时用不到。

 

addDateHeader(String name ,long date):这个是向客户机添加一个时间值属性的响应头信息,比如那个缓存的响应头expires

 

addHeader(String name,String value):这个是向客户机添加一个字符串值属性的响应头信息,比如重定向的响应头location

 

addIntHeader(String name ,int value):这个是向客户机添加一个字符串属性的响应头信息

 

containsHeader(String name):这个方法是判断是否含有这个响应头信息字段

 

encodeURL(String name):这个方法是用于url改写的功能的,这个和session有关,等到说session那篇文章的时候在详细说明

 

sendRedirect(String name):这个方法是用于请求重定向的,和响应头中的location字段的作用相同

 

setHeader(String name,String value)/setIntHeader(String name,int value)/setDateHeader(String name,long date):这些方法和addHeader方法是相对应的,唯一和addHeader不同的是,addHeader是向Response中添加一个响应头信息,而setHeader是修改一个响应头信息的。

 

setStatus(int value):通过这个方法是设置响应码的,比如:200,304,404等。

 

getOutputStream():通过这个方法可以拿到一个字节流,然后可以向Response容器中写入字节数据,最后客户机向Response容器中拿去数据进行显示

 

getWriter():通过这个方法可以拿到一个字符流(PrintWriter),然后可以向Response容器中写入字符数据,最后客户机向Response容器中拿去数据进行显示。

 

setContentLength():通过这个方法设置服务器向用户返回的数据长度。

 

setContentType():方法可以直接设置响应头content-type的内容。

 

第一个例子:通过Response进行数据的输出,下面是一个测试的方法,这个方法只要在service方法中调用即可,传递一个HttpServletResponse对象,就可以进行输出的

HttpServletResponse对象,就可以进行输出的
public void test(HttpServletResponse response) throws Exception{  
    // 使用OutputStream字节流进行数据的输出  
    response.getOutputStream().write("Hello World".getBytes());  
        } 

这个例子很简单就是将字符串写到response容器中,然后客户机从容器中拿取数据进行显示即可,但是这里我们需要注意的,当我们在使用response.getOutputStream()这样获取一个OutputStream流的时候,我们在使用完之后,并不需要手动的去关闭,系统会自动关闭它,如果我们手动去关闭这个流的话,还会引发一些问题。

这里我们输出的是"Hello World"英文,使用浏览器去访问的时候是没有乱码问题,下面我们在将代码改写一下

response.getOutputStream.write("中国".getBytes("utf-8"));

这时候我们使用浏览器去访问数据的时候,当然我们可能会看到"中国",也有可能看到的是乱码,原因很简单,如果浏览器使用的是gb2312码表打开的话,就是乱码,如果是使用utf-8码表打开的话,就是正常的数据。当然我们可以手动的去设置浏览器的打开码表,默认的是gb2312(系统默认码表),那么如果我们使用utf-8将数据写入到Response中,然后浏览器使用的是默认的码表去拿取数据进行显示,那肯定是乱码了,那么我们该怎么办呢?,让用户手动的去修改浏览器的打开码表,那貌似太恶心了,所以这里我们就要介绍一个响应头字段的作用了,Content-type:这个头就是告诉浏览器以什么方式打开数据,并且指定相应的码表,具体代码如下:

response.setHeader("Content-type", "text/html;charset=utf-8");  

这样,我们就可以告诉浏览器以utf-8码表去显示数据,这样也就不会再有乱码的问题了

这里我们在扩展一下就是还有一种方式控制浏览器的打开码表,那就是使用<meta>标签来实现:

1.response.getOutputStream().write("<meta http-equiv='content-type' content='text/html;charset=utf-8'>".getBytes());  

这里我们组建了一个<meta>标签,并将这个标签写入到Response容器中,当客户机使用去拿取这段数据的时候,发现有html中的标签<meta>所以会通过一些处理会把上面的字符串当做是是html代码来显示。这里使用了<meat>标签来解决乱码问题的。

 

上面使用的是字节流的方式来给客户机发送数据的,有时候我们可能会使用字符流来显示数据,因为字符流在特定场合下回比字节流更方便的输出,其实这里使用response.getWriter()来获取一个PrintWriter字符流对象,然后我们可以使用PrintWriter对象的write方法直接写字符串数据,但是这里也是需要来解决乱码的问题,而且这里的需要解决的问题比上面的字节流更麻烦

response.getWriter.write("中国");

通过上面的方法进行输出,显示的是乱码,首先servlet将"中国"字符串写入到Response容器中,但是这里需要注意的一个问题就是,将"中国"写入到Response中,那么Response容器中是怎么存储"中国"字符串的,因为Response这些技术都是老外发明的,所以他们肯定是使用iso8859-1编码来进行存储字节数据的,所以这里就会有一个大问题,因为我们知道iso8859-1使用的是单个字节表示一个字符的,而gb2312使用的是两个字节,utf-8使用的是三个字节,所以Response将使用iso8859-1码表进行编码,那么存储的是两个乱码字节,所以,当客户机从Response容器中去拿取数据的时候显示的肯定是乱码,那么当我们使用

1.response.setHeader("Content-type","text/html;charset=utf-8")  

来设置浏览器的打开数据的码表,但是我们会发现还是显示两个??,这个也是很简单的,因为我们在编写JavaSE中,也会知道这个问题就是将utf-8这种多字节的码表转到低字节码表iso8859-1,当我这时候在将结果转成utf-8的数据,这时候是不可能在转回原始数据的。所以说我们应该去修改Response容器的码表,将其码表改成utf-8,这时候就可以"中国"写入到Response容器中,而且会以utf-8的码表进行存储的,当客户机在用utf-8码表打开的时候就不会有问题了

 

上面我们使用字节流来进行书写数据的时候,是没有问题的,因为是将"中国"的字节数据直接写到Response容器中的,所以不会涉及到Response容器编码的问题。

所以说当我们在使用字符流写入数据的时候,我们一定要记得修改Response容器的编码,不然会出现乱码的

response.setCharacterEncoding("utf-8");  
response.setHeader("content-type", "text/html;charset=utf-8");  

所以要用这两行代码的,同时response对象中还有一个方法:setContentType,这个方法可以直接设置Content-type字段的值

response.setContentType("text/html;charset=utf-8");

其实这一行代码就相当于上面的两行代码的效果,因为在setContentType方法中已经调用了setCharacterEncoding方法设置了Response容器的编码了

 

项目应用:弹窗

 

$.ajax({
        url: ctx+'/ticket/confirm/exchange/check',
        // 数据发送方式
        type: "post",
        data: {
            "idTickets":idTickets,
            "exchangeCode":_exchangeCode,
            "showDate":$("#getShowDate").val()
            
        },
        // 接受数据格式
        dataType : "json",
        // 要传递的数据
        // 回调函数,接受服务器端返回给客户端的值,即result值
        success : function(data) {
            if(data.status=="true"){
                $(yanzhengBtn).hide();//验证按钮隐藏
                $(yanzhengBtn).next("button").show();//取消按钮显示
                
                $(yanzhengBtn).next("button").siblings("#dhq").css("visibility","hidden");//-按钮隐藏
                $(yanzhengBtn).prev("input").attr("readonly","true");//设置输入框只读
                $(yanzhengBtn).siblings("span").show();//显示可兑换票种
                
                
                //设置票种数据
                var _idTicket = data.ticketId;
                var _selectedTicket;
                for(var i =0;i<_preOrder.ticketSellplanList.length;i++){
                    var _ticket = _preOrder.ticketSellplanList[i];
                    if(_ticket.ticketId==_idTicket&&_ticket.haveExchange){
                        var _tempExchange = {exchangeCode:_exchangeCode,discountPrice:_ticket.discountPrice};
                        _ticket.exchangeList.push(_tempExchange);
                        _selectedTicket = _ticket;
                        break;
                    }
                }
                $(yanzhengBtn).siblings("span").children("span").html(_selectedTicket.ticketName);//设置可兑换票种名称
                //设置全订单使用的记录
                _preOrder.exchangeList[_exchangeCode] = _exchangeCode;
                
                var realPay = parseFloat($("#shouldPayMoney").val()) - parseFloat(_selectedTicket.discountPrice);
                realPay = realPay.toFixed(2);
                $("#totalMoney").html(realPay<0?0:realPay);//显示的金额
                $("#shouldPayMoney").val(realPay);//应付金额,用于优惠码取消时金额
                
            } else {
                jAlert(data.message, "兑换券提示");
            }
            restoreOnClick(obj);
            showLoading(false);
        },
        error: function(){
            jAlert("网络繁忙.", "兑换券提示");
            restoreOnClick(obj);
            showLoading(false);
        }
});

 

后台:

 

if(StringUtil.isEmpty(idTickets)){
            obj.put("status", "false");
            obj.put("message", "缺失参数idTickets.");
            response.getWriter().print(obj);
            return;
        }

 

 

 

 

 

 

posted @ 2017-05-10 11:10  十月围城小童鞋  阅读(221)  评论(0编辑  收藏  举报