WEB核心之Response

HttpServletResponse

1. 概述

在开始阅读之前,我们先看一下HttpServletResponse官方的介绍。

public interface HttpServletResponse extends ServletResponse

	Extends the ServletResponse interface to provide HTTP-specific functionality in sending a response. For example, it has methods to access HTTP headers and cookies. 
	The servlet container creates an HttpServletResponse object and passes it as an argument to the servlet's service methods (doGet, doPost, etc).

  大概的意思是HttpServletResponse继承自ServletResponse,作为子类的它增加了与HTTP协议相关的操作,该对象专门用来封装HTTP的响应消息。由于HTTP中的响应消息分为响应行、响应头和响应体三部分。因此在HttpServletResponse接口中定义了向客户端发送响应状态码、响应消息头、响应消息体的方法。

2. Response的运行流程

在这里插入图片描述

  • 客户端发送请求,Tomcat引擎解析请求的资源。
  • tomcat服务器将请求的信息封装成Request对象,与此同时创建一个Response对象。
  • tomcat自动创建servlet对象,并调用其service方法,传递两个对象到我们自己写的Servlet的doGet和doPost方法。
  • 在doGet和doPost方法中,我们使用Response对象用输出流写东西会先写到Response缓冲区。
  • service方法结束,方法返回后,tomcat内核会去该Response缓冲区获取写出的内容。
  • tomcat从Response中获取写出的内容组装成一个http响应。
  • 客户端解析HTTP响应,显示页面。

注意:Response缓冲区的默认大小是8K

3. Response常用API

3.1 发送状态码的相关方法

  当servlet向客户端回送响应消息时,需要在响应消息中设置状态码。为此,在HttpServletResponse接口中,定义了两个发送状态码的方法,具体如下:

  • setStatus(int status)

  该方法用于设置HTTP响应消息的状态码,并生成响应状态行。需要注意的是,在正常的情况下,WEB服务器会默认产生一个状态码为200的响应行。

  • sendError(int sc)sendError(int sc,String message)

    这两个方法是用于发送表示错误信息的状态码,例如:404状态码表示找不到客户端请求的资源。第二个的字符串可以写我们自定义的错误信息。

注意:第一个方法只是会影响响应行的状态码的变化,不会出现相应的静态页面。后面两个方法,在改变状态码的同时还会返回对应的页面。

3.2 发送响应消息头相关的方法

  当Servlet向客户端发送响应消息时,由于HTTP协议的响应头字段有很多种,为此,在HTTPServletResponse接口中定义了一些列设置HTTP响应头字段的方法。

方法功能描述
void addHeader(String name, String value)添加值为字符串类型的响应头
void addIntHeader(String name, int value)添加值为int类型的响应头
void addDateHeader(String name, long date)添加值为Date类型的响应头
void setHeader(String name, String value)给响应头设置值
void setDateHeader(String name, long date)给响应头设置值
void setIntHeader(String name, int value)给响应头设置值
void addCookie(Cookie cookie)将Cookie对象写给客户端
  • 父类ServletResponse的方法
方法功能
void setBufferSize(int size)设置Response缓冲区的内存大小,默认8K
void setCharacterEncoding(String charset)设置服务器端的字符集(编码)
void setContentType(String type)该方法用于设置Servlet输出内容的MIME类型,对于HTTP来说就是设置Content-Type的值。如果响应的内容为文本时,此方法还可以设置字符编码,如:text/html;charset=UTF-8
void setLocale(Locale loc)该方法用于设置响应消息的本地化信息。对于HTTP协议来说,就是设置Content-Language响应头字段和Content-Type头字段中的字符集编码部分。需要注意的是,如果HTTP消息没有设置Content-Type头字段,setLocale()方法设置的字符集编码不会出现在HTTP消息的响应头中,如果调用setCharacterEncoding()或setContent-Type方法指定了响应内容的字符集编码,setLocale()的方法不再具有指定字符集编码的功能。
void setCharacterEncoding(String charset)该方法用于设置输出内容使用的字符编码。对于HTTP协议来说,就是设置Content-Type头字段中的字符集编码部分。如果HTTP消息没有设置Content-Type头字段,setCharacterEncoding()方法设置的字符编码不会出现在HTTP消息的响应头中。此方法比setContentType()和setLocale()方法的优先权高。它设置的结果将覆盖setContentType()和setLocale()方法所设置的字符码表。

3.3 发送响应消息体的方法

  • getOutputStream()
  • getWriter()

注意:虽然response对象的getOutPutStream()getWriter()方法都可以发送响应消息体,但是,他们之间互相排斥,不可同时使用,否则会发生IllegalStateException异常。发生异常的原因就是在Servlet中,调用response.getWriter()方法之前就已经调用了response.getOutPutStream()方法了。

3.4 中文输出乱码问题

  当我们利用获取的字符输出流向客户端输出中文的时候,客户端无法正确解析出我们输出的内容,显示的都是“??” ,说明发生了乱码问题。

  假如我们输出中文 武汉,会显示为 “??”

  出现中文乱码的时候肯定是字符码表不一致导致的问题,此处产生的原因是response缓冲区的默认编码是ISO-8859-1,此码表中没有中文,会将武汉通通编码为63 63。当浏览器对接收到的数据进行解码时,会采用默认的GB2312,将63解码为?

注意:在ISO-8859-1码表中查不到的字符就会编码为63。

  可以通过response的setCharacterEncoding(String charset)设置response的编码,假如我们设置的是UTF-8的编码。

  但我们发现客户端还是不能正常显示中文,这是我们能想到的还是编码问题,原因是虽然我们将response缓冲区的编码设置成UTF-8,但浏览器的默认编码是本地系统的编码,因为我们都是中文系统,所以客户端浏览器的默认编码是GBK,虽然我们可以手动修改浏览器的编码是UTF-8,但是这对用户来说非常的不友好,所以我们还要设置浏览器的解码方式。在HttpServletResponse对象中,提供了两种解决乱码的方案,具体如下:

  • 第一种方式

    //设置HTTPServletResponse使用utf-8编码
    response.setCharacterEncoding("utf-8");
    //通知浏览器使用utf-8解码
    response.setHeader("Content-Type","text/html;charset=utf-8");
    
  • 第二种方式

    //包含第一种方式的两个功能
    response.setContentType("text/html;charset=utf-8");
    

    注意:第二种方式更加简便,而且包含了第一种方式的功能,所以我们使用第二种简单的方式,忘记第一种方式吧。哈哈。还有一个需要注意的是我们需要在获取输出流之前调用该方法,否则还是会乱码。

3.5 Response的小知识

  • response的缓冲区大小默认是8K。
  • response获取的字节字节输出流和字符输出流不需要我们手动关闭,Tomcat帮我们关闭。
  • response对象的getOutPutStream()和getWriter()方法不能同时使用,会报异常。

4 常用的响应头

  • 重定向:需要配合Location响应头,指定响应的路径,需要与状态码302配合使用,完成跳转。

    response.setStatus(302);
    response.setHeader("Location", "http://www.baidu.com");
    
  • 重定向:有一个封装好的方法直接输入地址即可

    response.sendRedirect(resquest.getContextPath+"/servlet资源路径");
    
  • 刷新:配合响应头refresh使用,后面值的数字代表的是等待多少秒跳转到指定页面:

    response.setHeader("refresh", "5;url=http://www.baidu.com");
    
  • 告知浏览器文件的类型:

    response.setContentType(this.getServletContext().getMimeType(文件名));
    
  • 告知客户端文件以附件的形式下载:

    response.setHeader("Content-Disposition", "attachment;filename="+文件名);
    

    注意:关于下载文件的名称,每个客户端的解码方式不一样,针对不同的客户端我们要事先准备好相应格式的数据。

  • 解决输出中文乱码问题:

    response.setContentType("text/html;charset=UTF-8");
    
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值