request域对象(十三)
一、利用请求域传递对象
1. request对象同时也是一个域对象,开发人员通过request对象在实现转发时,把数据通过request对象带给其它web资源处理。
setAttribute方法
getAttribute方法
removeAttribute方法
getAttributeNames方法
2. request对象提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发,从而共享请求中的数据。
二、request域对象
request可以获取请求信息。request在请求来时创建,在响应结束时结束。
request生命周期:
1. 当请求来时创建request对象
2. 当请求结束时,request就销毁。
3. 每次请求都是一个新的request对象。
request域对象,是建议使用,并被频繁使用的域对象,因为它声明周期比较短,也就代表着,它效率比较高,释放资源比较及时。
只要是域对象,就有setAttribute, getAttribute, removeAttribute操作。
三、重要概念 --- 请求转发
请求转发,它代表的是服务器的内部跳转。
当浏览器端发送请求:http://localhost:8080/day8_2/first,访问的是FirstServlet,在FirstServlet里面可以通过请求转发的方式访问SecondServlet,当访问完成后,要回到FirstServlet,在完成响应。请求转发就是服务器内部做了跳转。
代码:
请求转发:
RequestDispatcher requestDispatcher = request.getRequestDispatcher(String path);
requestDispatcher.forward(ServletRequest request, ServletResponse response);
细节讲解:
requestDispatcher.forward(ServletRequest request, ServletResponse response); 接收参数类型ServletRequest和ServletResponse,而它们分别是HttpServletRequest和HttpServletResponse的父接口,而将HttpServletRequest request和HttpServletResponse response传递给它是可以的,实现了多态。
RequestDispatcher requestDispatcher = request.getRequestDispatcher(String path); 参数path代表转发到哪个位置,它是服务器的内部跳转。表示的是在服务器端向访问某个servlet。/second。
FirstServlet:
package com.il.servlet.request;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FirstServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("first start...");
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/second");
requestDispatcher.forward(request, response);
System.out.println("first end...");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
SecondServlet
package com.il.servlet.request;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SecondServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("second...");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
控制台输出结果:
first start...
second...
first end...
问题:服务器内部跳转有什么用?
用来分工,让每一个servlet或资源完成自己功能。登录操作,firstservlet获取数据并完成处理,为了分工明确,让secondservlet完成登录成功失败处理。把正确与否的信息存储在request域中。
FirstServlet:
package com.il.servlet.request;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FirstServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
if("tom".equals(username.trim())&"123".equals(password.trim())) {
request.setAttribute("loginmessage", "登录成功");
}else {
request.setAttribute("loginmessage", "登录失败");
}
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/second");
requestDispatcher.forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
SecondServlet:
package com.il.servlet.request;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SecondServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//从request域中获取信息
String message = (String) request.getAttribute("loginmessage");
response.getWriter().write(message);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
注意,1. forward函数把FirstServlet中的request和response放到SecondServlet中,所以两个servlet公用一个request和response。
2. 执行完请求转发或重定向后,我们的response缓冲区会清空。而下面做的操作response.getWriter().write("helloworld"),向缓冲区写数据,无效。当forward执行,到SecondServlet中,通过response向浏览器写,forward结束后,清空缓冲区,但响应并不结束。结论:当forward或sendRedirect结束,很好的习惯是写return,后面内容不执行。
对于forward或sendRedirect后,它会清空response缓冲区(response获得输出流,既然有输出流肯定有缓冲区),那么执行的任何与缓冲区有关的操作都无效。养成习惯在执行完这两个操作后,直接加return。
推荐阅读
-
request(域对象)和response的区别和用法
-
第十三、四天 匿名函数 传入函数 偏函数 变量作用域
-
java web学习_浅谈request对象中get和post的差异
-
关于Java跨域Json字符转类对象的方法示例
-
Zend Framework教程之请求对象的封装Zend_Controller_Request实例详解
-
详解Django中Request对象的相关用法
-
javascript asp教程第八课--request对象
-
从源码解析Python的Flask框架中request对象的用法
-
解析JavaScript面向对象概念中的Object类型与作用域
-
浅谈jsp九大内置对象及四个作用域