欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

request域对象(十三)

程序员文章站 2022-06-11 15:46:28
...

一、利用请求域传递对象

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操作。

三、重要概念 --- 请求转发

请求转发,它代表的是服务器的内部跳转。

request域对象(十三)

当浏览器端发送请求: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。