Java Web -- Servlet(13)HttpServletRequest详解(获取请求数据、请求分派、请求域)(2)

   

                                HttpServletRequest

----------------------------------------------------------------

(4)请求分派

Servlet API中定义了一个RequestDispatcher接口,俗称请求分派器。

它有两个方法

forward(ServletRequest request,ServletResponse response)

include(ServletRequest request,ServletResponse response)

Forward()方法用于将请求转发到RequestDispatcher实例封装的资源;

Include()方法用于将RequestDispatcher实例封装的资源作为当前响应内容的一部分包含进来。

而获取RequestDispatcher实例也主要有两种。

调用ServletContext接口提供的getRequestDispatcher(String url)方法

调用ServletRequest接口提供的getRequestDispatcher(String url)方法

区别:

调用ServletContext接口提供的getRequestDispatcher(String url)方法必须是绝对路径

调用ServletRequest接口提供的getRequestDispatcher(String url)方法可以是相对路径,也可以是绝对路径。

举例:

创建一个Servlet(demo1.java),代码如下:

import java.io.IOException;

import java.io.PrintWriter;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class demo1 extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {

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

request.setCharacterEncoding("utf-8");

PrintWriter out
= response.getWriter();

//提交到demo2、

out.println("<form
method=‘get‘ action=‘/demo/demo2‘>");

out.println("用户名:<input
type=‘text‘ name=‘username‘ /><br/>");

out.println("密 码:<input
type=‘password‘ name=‘pass‘ /><br/>");

out.println("<input
type=‘submit‘ value=‘提交‘ ");

out.println("</form>");

}

}

创建一个Servlet(demo2.java),代码如下:

import java.io.IOException;

import java.io.PrintWriter;

import java.util.Enumeration;

import javax.servlet.RequestDispatcher;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class demo2 extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {

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

request.setCharacterEncoding("utf-8");

//PrintWriter
out = response.getWriter();

//获取请求分派器

RequestDispatcher
dispatcher = request.getRequestDispatcher("demo3");

//将请求转发至指定路径的资源

dispatcher.forward(request,
response);

}

}

创建Servlet(demo3.java),代码如下:

import java.io.FileInputStream;

import java.io.IOException;

import java.io.PrintWriter;

import javax.servlet.ServletException;

import javax.servlet.ServletOutputStream;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class demo3 extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {

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

PrintWriter out
= response.getWriter();

request.setCharacterEncoding("utf-8");

//获得用户输入的用户名

String name =
request.getParameter("username");

out.println(name+"已经请求转发到demo3了");

}

}

原理:

当浏览器发起一次http请求时,Web服务器将demo2请求转发给第二个资源(即demo3),demo3将一次响应返回给服务器。

当调用这条语句时,并没有直接转发给浏览器,而是转发给Web服务器,Web服务器再调用。请求转发是发生在Web服务器。

效果如下:

在demo1中输入用户名和密码;

跳转的页面是demo2 ,显示的内容却是demo3的效果

这种情况下浏览器只发出一次请求,服务器也只返回一次响应。浏览器地址栏的URI是demo2,但服务器却只用demo3来进行响应的。在demo3中也可以获取客户端请求demo2是发送的参数数据。

(5)利用请求域属性传递对象数据

HttpServletRequest接口中提供了几个方法用来操作请求实例中存储的对象。

(1)setAttribute(String name,Object obj);

//将对象存储进HttpServletRequest实例中

(2)getAttribute(String name);

//检索存储在HttpServletRequest实例中的对象。

(3)getAttributeNames();

(4)removeAttribute(String name);

这种存储在HttpServletRequest中的对象称之为请求域属性,属于同一请求过程的多个处理模块之间可以通过请求域属性来传递对象数据,如通过请求转发的两个Servlet之间就可以通过请求域属性来传递对象数据,但通过重定向的两个Servlet之间就不能通过请求域属性来传递对象数据。

在请求分派的例子上,demo1不用改变。

demo2.java的代码如下:

import java.io.IOException;

import java.io.PrintWriter;

import java.util.Enumeration;

import javax.servlet.RequestDispatcher;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class demo2 extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {

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

request.setCharacterEncoding("utf-8");

//PrintWriter
out = response.getWriter();

//将一个字符串存放在请求域属性中

String
str = "hello world!";

request.setAttribute("str",str);

RequestDispatcher
dispatcher = request.getRequestDispatcher("demo3");

dispatcher.forward(request,
response);

}

}

demo3.java代码如下:

import java.io.FileInputStream;

import java.io.IOException;

import java.io.PrintWriter;

import javax.servlet.ServletException;

import javax.servlet.ServletOutputStream;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class demo3 extends HttpServlet
{

protected void doGet(HttpServletRequestrequest,
HttpServletResponseresponse)throws ServletException,
IOException {

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

PrintWriterout =response.getWriter();

request.setCharacterEncoding("utf-8");

Stringname =request.getParameter("username");

//从请求域属性中取出str这个对象。

String
str = (String)request.getAttribute("str");

out.println(name+"已经请求转发到demo3了<br/>");

out.println("我在demo3获取demo2请求域属性的值为:&"+str);

}

}

依然输出用户名和密码,提交。

效果如下:

request中的attribute只在一次请求有效。

不可以通过sendRedirect方式取得域对象中值,因为域对象只能在一次请求有效,sendRedirect重定向后request和response都是全新的。

//因为是在Web服务器中发生的,所以只需要填写资源名

request.getRequestDispatcher(“/资源名URI”).forward(request,response);

//因为发生在浏览器,浏览器就得知道要重定向到哪个Web应用

response.sendRedirect(“/Web应用/Web资源”);

用处:

通常在Servlet中处理客户请求,然后把需要返回给用户的动态数据利用请求域属性传递到JSP页面,在JSP页面中解析成HTML,在返回给客户端。

总结:重定向和请求分派(请求转发)的区别

虽然HttpServletRequest的sendRedirect()方法和RequestDispatcher的forward()方法都可以让浏览器获得另一个URL所指向的资源所做的响应,但两者的内部运行机制有着很大的区别。

(1)请求分派只能将请求转发给同一个Web应用的其他资源。

重定向不仅可以定向到当前Web应用的其他资源,也可以重定向到其他站点的资源上。

(2) 请求分派是在接收到客户端请求后通知服务器调用另一个Web资源,http状态码为307。

重定向是在接收到客户端请求后通知浏览器调用另一个Web资源,http状态码为302。

(3)重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变,有初始的URL地址变成重定向的目标URL;

而请求转发过程结束后,浏览器地址栏保持初始的URL地址不变

(4)请求分派的发起者和被调用者之间共享相同的request实例和response实例,它们属于同一个“请求/响应“过程

而重定向的发起者和被调用者使用各自的request实例和response实例,它们各自属于独立的“请求/响应”过程。

时间: 2024-08-05 15:01:12

Java Web -- Servlet(13)HttpServletRequest详解(获取请求数据、请求分派、请求域)(2)的相关文章

Java Web -- Servlet(11) HttpServletResponse详解(重定向)

当Web服务器收到客户端的http请求,(在程序继承HttpServlet的前提下)容器在调用Servlet的doGet()或doPost()方法时,会针对每一次请求创建一个HttpServletRequest接口的实例和一个HttpServletResponse接口的实例,封装成参数传给doGet()或doPost()方法. request和response分别代表客户端对Web服务器的请求 和 服务器对客户端的响应. HttpServlet的继承结构如下: ServletResponse的常

java网页爬虫简单实例详解——获取天气预报。

[本文介绍] 爬取别人网页上的内容,听上似乎很有趣的样子,只要几步,就可以获取到力所不能及的东西,例如呢?例如天气预报,总不能自己拿着仪器去测吧!当然,要获取天气预报还是用webService好.这里只是举个例子.话不多说了,上看看效果吧. [效果] 我们随便找个天气预报的网站来试试:http://www.weather.com.cn/html/weather/101280101.shtml 从图中可用看出,今天(6日)的天气.我们就以这个为例,获取今天的天气吧! 最终后台打印出: 今天:6日

Java Web自定义MVC框架详解 (转)

转自:http://blog.csdn.net/jackfrued/article/details/42774459 最近给学生讲Java Web,希望他们能够在学完这部分内容后自己实现一个MVC框架.但是突然发现百度上能搜索到的靠谱的资料并不是很多,有些只是原理没有代码实现,有些有 代码实现但是对于初学者来说理解起来还是比较困难,于是决定把自己讲自定义MVC框架的内容放在这里分享给大家,不仅仅是代码,也有原理和探讨.内容会比 较长,因为我打算用递增的方式讲解如何写一个自定义MVC框架,重点是前

Java web中WEB-INF目录详解

1.它是java的web应用的安全目录.所谓安全就是客户端无法访问,只有服务端可以访问的目录. 2.web.xml项目部署文件. 3.classes文件夹,用以防止*.class文件 4.lib文件夹,用于存放需要的jar包. WEB-INF中配置web.xml文件,添加<welcome-file-list> <welcome-file> 设定的首页文件名 <welcome-file> <welcome-fiel-list>

Servlet基础知识详解

Servlet基础知识详解 Servlet基础知识详解 Servlet程序执行全过程 Servlet映射路径 Servlet映射练习 Servlet生命周期 为什么要学习Servlet生命周期 Servlet重要的生命周期方法 模拟通过反射构造Servlet对象 Servlet单实例多线程 Servlet留给开发者的init方法 Servlet中核心对象学习 HttpServletRequest对象 HttpServletResponse对象 ServletConfig对象 ServletCon

HttpServletResponse和HttpServletRequest详解

HttpServletResponse,HttpServletRequest详解 1.相关的接口 HttpServletRequest HttpServletRequest接口最常用的方法就是获得请求中的参数,这些参数一般是客户端表单中的数据.同时,HttpServletRequest接口可以获取由客户端传送的名称,也可以获取产生请求并且接收请求的服务器端主机名及IP地址,还可以获取客户端正在使用的通信协议等信息.下表是接口HttpServletRequest的常用方法. 说明:HttpServ

HttpServletResponse,HttpServletRequest详解

HttpServletResponse,HttpServletRequest详解 1.相关的接口 HttpServletRequest HttpServletRequest接口最常用的方法就是获得请求中的参数,这些参数一般是客户端表单中的数据.同时,HttpServletRequest接口可以获取由客户端传送的名称,也可以获取产生请求并且接收请求的服务器端主机名及IP地址,还可以获取客户端正在使用的通信协议等信息.下表是接口HttpServletRequest的常用方法. 说明:HttpServ

HttpServletResponse和HttpServletRequest详解.RP

HttpServletResponse,HttpServletRequest详解 1.相关的接口 HttpServletRequest HttpServletRequest接口最常用的方法就是获得请求中的参数,这些参数一般是客户端表单中的数据.同时,HttpServletRequest接口可以获取由客户端传送的名称,也可以获取产生请求并且接收请求的服务器端主机名及IP地址,还可以获取客户端正在使用的通信协议等信息.下表是接口HttpServletRequest的常用方法. 说明:HttpServ

Web容器中DefaultServlet详解

Web容器中DefaultServlet详解 https://blog.csdn.net/qq_30920821/article/details/78328608 Web容器中DefaultServlet详解一.什么是defaultServlet 我们以最熟悉的Tomcat服务器为例.我们都知道Jsp和servlet都需要web容器才能运行.但是实际上呢我们的web应用中可以没有任何servlet或者jsp(至少表面上是这样的)只需要一个web.xml,设置在servlet 3.0中,这个也可以