第4章 请求和响应

目录

4.1 HttpServletResponse对象

4.1.1 发送状态码相关的方法

1.setStatus(int status)方法

2.sendError(int sc)方法

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

4.1.3 发送响应消息实体相关的方法

1.getOutputStream()方法

2.getWriter()方法

4.2 HttpServletResponse应用

【任务4-1】解决中文输出乱码问题

【任务4-2】实现网页定时刷新并跳转

实现请求重定向

4.3 HttpServletRequest对象

4.3.1 获取请求行信息的相关方法

4.3.2 获取请求消息头的相关方法

利用Referer请求头防止“盗链”

HttpServletRequest应用

获取请求参数

【任务4-3】解决请求参数的中文乱码问题

4.4.2 通过Request对象传递数据

4.5 RequestDispatcher 对象的应用

4.5.1 RequestDispatcher 接口

4.5.2 请求转发

4.5.3 请求包含


Servlet最主要的作用就是处理客户端请求,并向客户端作出响应。为此,针对Servlet的每次请求,Web服务器在调用service()方法之前,都会创建两个对象,分别是HttpServletRequest和HttpServletResponse。其中,HttpServletRequest用于封装HTTP请求消息,简称request对象。HttpServletResponse用于封装HTTP响应消息,简称response对象。request对象和response对象在请求Servlet过程中至关重要,接下来通过一张图来描述浏览器访问Servlet的交互过程,如下

在Web服务器运行阶段,每个Servlet都只会创建一个实例对象。然而,每次HTTP请求,Web服务器都会调用所请求Servlet实例的service(HttpServletRequest request, HttpServletResponse response)方法,重新创建一个request对象和一个response对象

4.1 HttpServletResponse对象

在Servlet API中,定义了一个HttpServletResponse接口,它继承自ServletResponse接口,专门用来封装HTTP响应消息。由于HTTP响应消息分为状态行、响应消息头、消息体三部分。因此,在HttpServletResponse接口中定义了向客户端发送响应状态码、响应消息头、响应消息体的方法。

4.1.1 发送状态码相关的方法

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

1.setStatus(int status)方法

该方法用于设置HTTP响应消息的状态码,并生成响应状态行。由于响应状态行中的状态描述信息直接与状态码相关,而HTTP版本由服务器确定,因此,只要通过setStatus(int status)方法设置了状态码,即可实现状态行的发送。需要注意的是,正常情况下,Web服务器会默认产生一个状态码为200的状态行

2.sendError(int sc)方法

该方法用于发送表示错误信息的状态码,例如,404状态码表示找不到客户端请求的资源。在response对象中,提供了两个重载的sendError(int sc)方法,具体如下

在上面重载的两个方法中,第1个方法只是发送错误信息的状态码,而第2个方法除了发送状态码外,还可以增加一条用于提示说明的文本信息,该文本信息将出现在发送给客户端的正文中。

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

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

addHeader()、setHeader()、addIntHeader()、setIntHeader()方法都是用于设置各种头字段的,而setContentType()、setLocale()和setCharacterEncoding()方法用于设置字符编码,这些设置字符编码的方法可以有效解决乱码问题。

4.1.3 发送响应消息实体相关的方法

由于在HTTP响应消息中,大量的数据都是通过响应消息体传递的,因此,ServletResponse遵循以IO流传递大量数据的设计理念。在发送响应消息体时,定义了两个与输出流相关的方法,如下

1.getOutputStream()方法

该方法所获取的字节输出流对象为ServletOutputStream类型。由于ServletOutputStream是OutputStream的子类,它可以直接输出字节数组中的二进制数据。因此,要想输出二进制格式的响应正文,就需要使用getOutputStream()方法。

2.getWriter()方法

该方法所获取的字符输出流对象为PrintWriter类型。由于PrintWriter类型的对象可以直接输出字符文本内容,因此,想要输出内容全为字符文本的网页文档,需要使用getWriter()方法。

在Eclipse中创建Web项目chapter04,在项目的src目录下,新建一个名称为cn.itcast.chapter04.response的包,在包中编写一个名为PrintServlet的Servlet类,该类中使用了response对象的getOutPutStream()方法获取输出流对象,如下

在web.xml中配置完PrintServlet的映射后,启动了Tomcat服务器,在浏览器的地址栏中输入“http://localhost:8080/chapter04/PrintServlet”访问PrintServlet,浏览器的显示结果如下

浏览器显示出了response对象相应的数据。由此可见,respnose对象的getOutputStream()方法可以很方便的发送响应消息体。

接下来,对文件进行修改,使用getWriter()方法发送消息体,修改后的代码如下

重启Tomcat服务器,在浏览器的地址栏中输入地址“http://localhost:8080/chapter04/PrintServlet”再次访问PrintServlet,结果与4-2显示相同

虽然response对象的getOutputStream()和getWriter()方法都可以发送响应消息体,但是,它们之间互相排斥,不可同时使用,否则会发生IIIegalStateException异常,如下

发生异常的原因就是在Servlet中调用response.getWriter()方法之前已经调用了response.getOutputStream()方法

4.2 HttpServletResponse应用

【任务4-1】解决中文输出乱码问题

【任务目标】

由于计算机中的数据都是以二进制形式存储的,因此,当传输文本时,就会发生字符和字节之间的转换。字符与字节之间的转换是通过查码表完成的,将字符转换成字节的过程称为编码将字节转换成字符的过程称为解码,如果编码和解码使用的码表不一致,就会导致乱码问题。通过本任务的学习,读者能够解决中文输出乱码问题。

【实现步骤】

1.创建Servlet

在chapter04项目的cn.itcast.chapter04.response包中编写一个名为ChineseServlet的类,在该类中定义一个中文字符串,然后使用字符输出流输出,如文件4-3所示。

2.配置映射信息,查看运行结果

在web.xml中配置完ChineseServlet的映射后,启动Tomcat服务器,在浏览器的地址栏中输入地址“http://localhost:8080/chapter04/ChineseServlet”访问ChineseServlet,浏览器的显示结果如图4-4所示。

从图4-4中可以看出,浏览器显示的内容都是“??”,说明发生了乱码问题。实际上此处产生乱码的原因是response对象的字符输出流在编码时,采用的是ISO-8859-1的字符码表,该码表并不会兼容中文,会将“中国”编码为“63 63”(在ISO-8859-1的码表中查不到的字符就会显示63)。当浏览器对接收到的数据进行解码时,会采用默认的码表GB2312,将“63”解码为“?”。因此,浏览器将“中国”两个字符显示成了“??”,具体分析如图4-5所示。

为了解决上述编码错误,在HttpServletResponse接口中,提供了一个setCharacterEncoding()方法,该方法用于设置字符的编码方式,解析下来对文件4-3进行修改,在第7行和第8行代码之间增加一行代码,设置字符编码用的码表为UTF-8,代码具体如下

response.setCharacterEncoding("utf-8");

在浏览器的地址栏中输入URL“http://localhost:8080/chapter04/ChineseServlet”再次访问ChineseServlet,浏览器的显示结果如图4-6所示。

从图4-6可以看出,浏览器中显示的乱码虽然不是“??”,但也不是所需要的输出的“中国”。通过分析发现,这是由于浏览器解码错误导致的,因为response对象的字符输出流设置的编码方式为UTF-8,而浏览器使用的解码方式GB2312,具体分析过程如图4-7所示。

对于图4-7所示的解码错误,可以通过修改浏览器的解码方式解决。在浏览器中单击菜单栏中的【查看】【其他】【Unicode(UTF-8)】选项(或者用鼠标右击浏览器内部,在弹出的窗口中选择【编码】【其他】【Unicode(UTF-8)】),将浏览器的编码方式设置为UTF-8,浏览器的显示结果如图4-8所示。

从图中可以看出,浏览器的显示内容没有出现乱码,由此说明,通过修改浏览器的编码方式可以解决乱码,但是,这样的做法仍然是不可取的,因为不能让用户每次都去改动浏览器编码。为此,在HttpServletResponse对象中,提供了两种解决乱码的方案,具体如下。

第1种方式:

//设置HttpServletResponse使用utf-8编码
response.setCharacterEncoding("utf-8");
//通知浏览器使用utf-8解码
response.setHeader("Content-Type","text/html;charset=utf-8");

第2种方式:

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

通常情况下,为了使代码更加简洁,会采用第2中方式。接下来,对文件4-3进行修改,使用HttpServletResponse对象的第2中方式来解决乱码问题,修改后的代码如文件4-4所示。

启动Tomcat服务器,在浏览器的地址栏中输入地址“http://localhost:8080/chapter04/ChineseServlet”访问ChineseServlet,浏览器显示出了正确的中文字符,如图4-9所示。

【任务4-2】实现网页定时刷新并跳转

【任务目标】

在Web开发中,有时会遇到定时跳转页面的需求。在HTTP协议中,定义了一个Refresh头字段,它可以通知浏览器在指定的时间内自动刷新并跳转到其他页面。通过本任务的学习,读者能够股使用response对象实现网页的定时刷新并跳转。

【实现步骤】

1.创建Servlet

在chapter04项目的cn.itcast.chapter04.response包中编写一个名为RefreshServlet的类,该类使用response对象的setHeader()方法实现了网页的定时刷新并跳转的功能,如文件4-5所示。

2.配置映射信息,查看运行结果

在web.xml中配置完RefreshServelt映射后,启动Tomcat服务器,在浏览器的地址中输入地址“http://localhost:8080/chapter04/RefreshServlet”访问RefreshServlet,发现浏览器2秒后自动跳转到了传智播客的官网首页,如图4-10所示。

在实际开发中,有时需要当前页面具有自动刷新的功能,例如,在火车票售票页面,使用自动刷新功能查看车票的剩余情况。接下来,对文件4-5进行修改,使当前页面每隔3秒自动刷新一次,修改后的代码如文件4-6所示。

启动Tomcat服务器,在浏览器的地址栏中输入地址“http://localhost:8080/chapter04/RefreshServlet”访问RefreshServlet,可以看到浏览器每隔3秒刷新一次,并且输出了当前的时间值。

实现请求重定向

在某些情况下,针对客户端的请求,一个Servlet类可能无法完成全部工作。这时,可以使用请求重定向来完成。所谓请求重定向,指的是Web服务器接收到客户端的请求后,可能由于某些条件限制,不能访问当前请求URL所指向的Web资源,而是指定了一个新的资源路径,让客户端重新发送请求。

为了实现请求重定向,在HttpServletResponse接口中,定义了一个sendRedirect()方法,该方法用于生成302响应码和Location响应头,从而通知客户端重新访问Location响应头中指定的URL,sendRedirect()方法的完整语法如下所示。

public void sendRedirect(java.lang.String location) throws java.io.IOException

需要注意的是,参数location可以使用相对URL,Web服务器会自动将相对URL翻译成绝对URL,再生成Location头字段

为了使读者更好地了解sendRedirect()方法如何实现请求重定向,接下来,通过一个图来描述sendRedirect()方法的工作原理,如图4-11所示

在图4-11中,当客户端浏览器访问Servlet1时,由于在Servlet1中调用了sendRedirect()方法将请求重定向到Servlet2,因此,Web服务器会在此收到浏览器对Servlet2的请求消息。Servlet2对请求处理完毕后,再将响应消息回送给客户端浏览器。

了解了sendRedirect()方法的工作原理后,接下来,通过一个用户登录的案例,分步骤讲解sendRedirect()方法的使用,具体如下

(1)在chapter04项目的WebContent目录下编写用户登录的页面login.html和登录成功的页面welcome.html,如文件4-7和文件4-8所示。

(2)在chapter04项目的cn.itcast.chapter04.response包中编写一个名为LoginServlet的类,用于处理用户登录请求,如文件4-9所示

在文件4-9中,首先通过getParameter()方法分别获取用户名和密码,然后判断表单中输入的用户名和密码是否为指定的“itcast”和“123”,如果是则将请求重定向到welcome.html页面,否则重定向到login.html页面。

(3)在web.xml中配置完LoginServlet映射后,启动Tomcat服务器,在浏览器的地址栏中输入地址“http://localhost:8080/chapter04/login.html”访问login.html,浏览器的显示结果如图4-12所示。

(4)在图4-12所示的界面填写用户名“itcast”,密码“123”,单击登录按钮,浏览器的显示结果如图4-13所示。

从图4-13中可以看出,当用户名和密码输入正确后,浏览器跳转到了welcome.html页面。但是,如果用户名或者密码输入错误,则会跳转到图4-12所示的登录页面

4.3 HttpServletRequest对象

在Servlet API中,定义了一个HttpServletRequest接口,它继承自ServletRequest接口,专门用来封装HTTP请求消息。由于HTTP请求消息分为请求行请求消息头请求消息体3部分,因此,在HttpServletRequest接口中定义了获取请求行请求头请求消息体的相关方法。接下来,本节将针对这些方法进行详细的讲解。

4.3.1 获取请求行信息的相关方法

当访问Servlet时,会在请求消息的请求行中,包含请求方法、请求资源名、请求路径等信息,为了获取这些信息,在HttpServletRequest接口中,定义了一系列用于获取请求行的方法,如表4-2所示。

在表4-2中,列出了一系列用于获取请求消息行信息的方法,为了使读者更好地理解这些方法,接下来,通过一个案例来演示这些方法的使用。

在chapter04项目的src目录下,新建一个名称为cn.itcast.chapter04.request的包,在包中编写一个名为RequestLineServlet的类,该类中编写了用于获取请求行中相关信息的方法,如文件4-10所示。

在web.xml中配置完RequestLineServlet的映射后,启动Tomcat服务器,在浏览器的地址栏中输入地址“http://localhost:8080/chapter04/RequestLineServlet”访问RequestLineServlet,浏览器的显示结果如图4-14所示。

从图4-14中可以看出,浏览器显示出了请求RequestLineServlet时发送的请求行信息。由此可见,通过HttpServletRequest对象可以很方便的获取到请求行的相关信息。

4.3.2 获取请求消息头的相关方法

当请求Servlet时,需要通过请求头像服务器传递附加信息,例如,客户端可以接收的数据类型、压缩方式、语言等。为此,在HttpServletRequest接口中,定义了一系列用于获取HTTP请求头字段的方法,如表4-3所示。

表4-3列出了一系列用于读取HTTP请求消息头字段的方法,为了让读者更好的掌握这些方法,接下来通过一个案例来学习这些方法的使用。

在cn.itcast.chapter04.request包中编写一个名为RequestHeadersServlet的类,该类使用getHeaderNames()方法来获取请求消息头信息,如文件4-11所示。

在web.xml中配置完RequestHeaderServlet映射后,启动Tomcat服务器,在浏览器的地址栏中输入地址“http://localhost:8080/chapter04/RequestHeaderServlet”访问RequestHeadersServlet,浏览器的显示结果如图4-15所示。

利用Referer请求头防止“盗链”

在实际开发中,经常会使用Referer头字段,例如,一些站点为了吸引人气并提高站点访问量,提供了各种软件的下载页面,但是他们本身没有这些资源,知识将下载的超链接指向其他站点上的资源。而真正提供了下载资源的站点为了防止这种“盗链”,就需要检查请求来源,只接受本站链接发送的下载请求,组止其他站点连接的下载请求。接下来,通过一个案例,分步骤讲解如何利用Referer请求头防止“盗链”,具体如下。

(1)在cn.itcast.chapter04.request包中编写一个名为DownManagerServlet的类,负责提供下载内容,但它要求下载请求的链接必须是通过本网站进入的,否则,会将请求转发给下载说明的HTML页面。DownManagerServlet类的具体实现代码如文件4-12所示。

(2)在WebContent根目录下编写一个下载说明的文件download.html,在<body>元素中增加如下代码。

<a href="/chapter04/DownManagerServlet">download</a>

(3)在web.xml中配置完DownManagerServlet映射后,启动Tomcat服务器,在浏览器的地址栏中输入地址“http://localhost:8080/chapter04/DownManagerServlet”访问DownManagerServlet,浏览器的显示内容结果如图4-6所示。

从图4-16中可以看出,浏览器显示的是download.html页面的内容。这是因为第1次请求DownManagerServlet时,请求消息中不含Referer请求头,所以,DownManagerServlet将下载请求转发给了download.html页面。

(4)单击图4-16所示的“download”链接后,重新访问DownManagerServlet,这时,由于请求消息中包含了Referer头字段,并且其值与DownManagerServlet位于同一个Web站点。因此,DownManagerServlet接收下载请求,浏览器的显示结果如图4-17所示。

HttpServletRequest应用

获取请求参数

在实际开发中,经常需要获取用户提交的表单数据,例如用户名、密码、电子邮件等,为了方便获取表单中的请求参数,在HttpServletRequest接口的父类ServletRequest中,定义了一系列获取请求参数的方法,如表4-4所示

表4-4列出了HttpServletRequest获取请求参数的一系列方法。其中,getParameter()方法用于获取某个指定的参数,而getParameterValues()方法用于获取多个同名的参数。接下来通过一个具体的案例,分步骤讲解这两个方法的使用,具体如下。

(1)在chapter04项目的WebContent根目录下编写一个表单文件form.html,如文件4-13所示。

(2)在cn.itcast.chapter04.request包中编写一个名称为RequestParameterServlet的Servlet类,使用该Servlet获取请求参数,如文件4-14所示。

(2)在cn.itcast.chapter04.request包中编写一个名称为RequestParameterServlet的Servlet类,使用该Servlet获取请求参数,如文件4-14所示。

在文件4-14中,由于参数名为“hobby”的值可能有多个,因此,需要使用getParameterValues()方法,获取多个同名参数的值,返回一个String类型的数组,通过遍历数组,打印出每个“hobby”参数对应的值。

(3)在web.xml中配置完RequestParameterServlet映射后,启动Tomcat服务器,在浏览器的地址栏中输入地址“http://localhost:8080/chapter04/form.html”访问form.html页面,并填写表单相关信息,填写后的页面如图4-18所示。

(4)单击图4-18所示的【提交】按钮,在Ecilipse的控制台打印出了每个参数的信息,如图4-19所示。

【任务4-3】解决请求参数的中文乱码问题

【任务目标】

在填写表单数据时,难免会输入中文,如姓名、公司名称等。在文件4-13中,由于HTML设置了浏览器在传递请求参数时,采用的编码方式是UTF-8,但在解码时采用的是默认的ISO-8859-1,因此会导致乱码的出现。在浏览器的地址栏中输入地址“http://localhost:8080/chapter04/form.html”再次访问form.html页面,输入用户名为“传智播客”以及相关表单信息,如图4-20所示。

单击图4-20中的【提交】按钮,这是,控制台打印出了每个参数的值,具体如图4-21所示。

从图4-21可以看出,当输入的用户名为中文时,出现了乱码问题。通过本任务的学习,读者将学会如何处理请求参数的中文乱码问题。

【实现步骤】

1.设置编码方式

在HttpServletRequest接口中,提供了一个setCharacterEncoding()方法,该方法用于设置request对象的解码方式,接下来,对文件4-14进行修改,修改后的代码如文件4-15所示。该方法用于返回请求消息的实体部分的字符集编码。

2.查看运行结果

启动Tomcat服务器,再次访问form.html页面,输入用户名”传智播客“以及相关表单信息,控制台打印的结果如图4-22所示。

从图4-22可以看出,控制台输出的参数信息没有出现乱码。需要注意的是,这种及解决乱码的范式只对POST方式有效,而对GET方式无效。为了验证GET方式的演示效果,接下来,将form.html文件中method属性的值改为“GET”。重新访问form.html页面并填写中文信息,控制台的打印结果如图4-23所示。

从图4-23中可以看出,使用GET方式提交表单,用户名出现了乱码,这就验证了setCharacterEncoding()方法只对POST提交方式有效的结论。为了解决GET方式提交表单是出现的中文乱码问题,可以先试用错误码表ISO-8859-1将用户名重新编码,然后使用码表UTF-8进行解码。接下来,对文件4-15进行修改,在第10行和第11行代码之间增加一行代码·,如下所示

name=new String(name.getBytes("iso8859-1"),"utf-8");

重启Tomcat服务器,再次访问form.html网页,输入中文名“传智播客”,这时,控制台的打印结果没有出现乱码,如图4-24所示。

配置Tomcat解决GET提交方式中的中文参数乱码问题

对于GET请求参数的乱码问题,除了可以通过重新编码解码来解决外,还可以通过配置Tomcat来解决。在server.xml文件中的Connector结点下增加一个useBodyEncodingForURI的属性,设置该属性的值为true,如下所示。

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" useBodyEncodingForURI="true"/>

并在程序中调用response.setCharacterEncoding("GBK")方法,这种可以使消息头的编码方式和消息体一致,就能解决GET方式的乱码问题。

指的一提的是,由于通过Tomcat解决参数乱码问题是在服务器端操作的,操作非常不便,因此,建议读者在解决参数乱码时,不要使用配置Tomcat的方式,该方式只需了解即可。

4.4.2 通过Request对象传递数据

Request对象不仅可以获取一系列数据,还可以通过属性传递数据。在ServletRequest接口中,定义了一系列操作属性的方法,具体如下。

  • setAttribute()方法

该方法用于将一个对象与一个名称相关联后存储进ServletRequest对象中,其完整语法定义如下。

public void setAttribute(java.lang.String name, java.lang.Object o);

需要注意的是,如果ServletRequest对象中已经存在指定名称的属性,setAttribute()方法将会先删除原来的属性,然后在添加新的属性。如果传递给setAttribute()方法的属性值对象为null,则删除指定名称的属性,这时的效果等同于removeAttribute()方法。 

  • getAttribute()方法

该方法用于从ServletRequest对象中返回指定名称的属性对象,其完整的语法定义如下。

public java.lang.Object getAttribute (java.lang.String name);
  • removeAttribute()方法

该方法用于从ServletRequest对象中删除指定名称的属性,其完整的语法定义如下。

public void removeAttribute(java.lang.String name);
  • getAttributeNames()方法

该方法用于返回一个包含ServletRequest对象中的所有属性名的Enumeration对象,在此基础上,可以对ServletRequest对象中的所有属性进行遍历处理。getAttributeNames()方法的完整语法定义如下。

public java.util.Enumeration getAttributeNames();

需要注意的是,只有属于同一个请求中的数据才可以通过ServletRequest对象传递数据。关于ServletRequest对象操作属性的具体方法,将在后面的小结详细讲解。在此,大家需了解即可。

4.5 RequestDispatcher 对象的应用

4.5.1 RequestDispatcher 接口

当一个Web资源收到客户端的请求后,如果希望服务器通知另外一个资源去处理请求,这是,除了使用sendRedirec()方法实现请求重定向外,还可以通过RequestDispatcher接口的实例对象来实现。在ServletRequest接口中定义了一个获取RequestDispatcher对象的方法,如表4-5所示。

获取到RequestDiapatcher对象后,最重要的工作就是通知其他Web资源处理当前的Servlet请求,为此,在ResquestDispatcher接口中,定义了两个相关方法,如表4-6所示。

表4-6列举的两个方法中,forward()方法可以实现请求转发,include()方法可以实现请求包含。

4.5.2 请求转发

在Servlet中,如果当前Web资源不想处理请求时,可以通过forward()方法将当前请求传递给其他的Web资源进行处理,这种方式称为请求转发。为了使读者更好地理解使用forward()方法实现请求转发的工作原理,接下来通过一张图来描述,如图4-25所示。

从图4-25中可以看出,当客户端访问Servlet1时,可以通过forward()方法将请求转发给其他Web资源,其他Web资源处理完请求后,直接将响应结果返回到客户端。

了解了forward()方法的工作原理后,接下来,通过一个案例来学习forword()方法的使用。

在chapter04项目的cn.itcast.chapter04.request包中编写一个名为RequestForwardServlet的Servlet类,该类使用forword()方法将请求转发到一个新的Servlet页面,如文件4-16所示。

在文件4-16中,通过使用forward()方法,将当前Servlet的请求转发到ResultServlet页面,在cn.itcast.chapter04.request包中编写一个名为ResultServlet类,该类用于获取RequestForwardServlet类中保存在request对象中的数据并输出ResultServlet类的代码实现如文件4-17所示。

在web.xml中,添加完两个Servlet的映射信息后,启动Tomcat服务器,在浏览器中输入地址“http://localhost:8080/chapter04/RequestForwardServlet”访问RequestForwardServlet,浏览器的显示结果如图4-26所示。

从图4-26中可以看出,地址栏中显示的仍然是RequestForwardServlet的请求路径,但是浏览器中却显示出了ResultServlet中要输出的内容。这是因为请求转发是发生在服务器内部的行为,从RequestForwardServlet到ResultServlet属于一次请求,在一次请求中是可以使用request属性来进行数据共享的

4.5.3 请求包含

请求包含指的是使用include()方法将Servlet请求转发给其他Web资源进行处理,与请求转发不同的是,在请求包含返回的响应消息中,既包含了当前Servlet的响应消息,也包含了其他Web资源所做出的响应消息。为了使读者更好地理解使用include()方法实现请求包含的工作原理,接下来,通过一个图来描述,如图4-27所示。

从图4-27中可以看出,当客户端访问Servlet1时,Servlet1通过调用include()方法的使用。

首先在cn.itcast.chapter04.request包中编写两个Servlet,分别是IncludingServlet和IncludedServlet。其中,在IncludingServlet中使用include()方法请求包含IncludedServlet。这两个Servlet的具体实现代码如文件4-18、文件4-19所示。

在web.xml中,添加完两个Servlet的映射信息后,启动Tomcat服务器,在浏览器的地址栏中输入“http://localhost:8080/chapter04/IncludingServlet”访问IncludingServlet,浏览器的显示结果如图4-28所示。

从图4-28中可以看到,输出的中文字符出现了乱码,说明在文件4-19中,用于设置响应字符编码的第9行代码没有起到作用。这是因为浏览器在请求IncludingServlet时,用于封装响应消息的HttpServletResponse对象已经创建,该对象在编码时采用的是默认的ISO-8859-1,所以,当客户端对接收到的数据进行解码时,Web服务器会继续保持调用HttpServletResponse对象中的信息,从而使IncluedServlet中的输出内容发生乱码。

为了解决图4-28所示的乱码问题,接下来,对文件4-18进行修改,在第7行和第8行代码之间增加一行代码来设置浏览器显示内容时的编码,具体如下:

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

重新启动Tomcat服务器,通过浏览器重新访问IncludingServlet,此时,浏览器的显示结果如图4-29所示。

从图4-29可以看出,IncludeServlet中输出的中文字符正常显示了。需要注意的是,使用include()方法实现请求包含后,浏览器显示的URL地址是不会发生变化的。

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值