Servlet 处理跳转和重定向

/ 0评 / 2

    Servlet的跳转和重定向也算是一种处理页面间转向的机制(之前Nginx挖的坑还没填,HTTPS配置完想设置重定向。然后莫名其妙的就配置不了,各种404Not Found==Https大势所趋所以不出三个月一定搞定)。而Servlet设置页面跳转以及重定向的初衷也是为了省去在doGet()方法亦或者是Service方法当中再去一步步写原来就有的页面作为响应体,将这个过程包装之后也就出现了重定向和跳转。

服务器内部跳转

        第一种情况:
            服务器内部跳转到一个页面中
            例如:

            String url = "/hello.html";
            //获得一个指向url的跳转对象
            RequestDispatcher dispatcher = request.getRequestDispatcher(url);
            //进行跳转 跳转的同时把request和response转发给要跳转到的url
            dispatcher.forward(request, response);

            或者:

            String url = "/hello.html";
            request.getRequestDispatcher(url).forward(request, response); 

        第二种情况:
            服务器内部跳转到一个servlet中

            String url = "/TestServlet";
            request.getRequestDispatcher(url).forward(request, response);

    服务器内部跳转的特点:
            1.需要使用request对象来完成
            2.服务器内部跳转期间,其实就是把请求request和响应response转发到一下资源中,所以在整个跳转期间所有涉及到的资源使用的都是同一个request和response。(我们可以利用这个特点将来在多个资源之间进行数据的传递)

            3.服务器内部跳转,【不会】改变浏览器地址栏中的地址

客户端重定向

        第一种情况:
            客户端重定向到一个页面中

            String url = "hello.html";
            response.sendRedirect(url);

        第二种情况:
            客户端重定向到一个servlet中

            String url = "TestServlet";
            response.sendRedirect(url);

    客户端重定向的特点:
            1.需要使用response对象来完成
            2.每一个客户端重定向,浏览器都会发出新请求,也就意味着在服务器内部会产生新的request对象和response对象

            3.客户端重定向,【会】改变浏览器地址栏中的地址

    
    以上两者直间的区别:

    跳转
    1.使用request完成
    2.跳转的本质是在服务器内部把请求和响应进行转发,转发给下一个资源
    3.如果request中有数据,在跳转到的每一个资源中都可以拿到一个数据(从开始到结束只有一个request对象)
    4.由于服务器跳转是把请求和响应在服务器内部中来回转发,所以浏览器的地址栏中的地址是不受影响的,所以始终还是第一次发出请求的地址
    5.在设置跳转的资源地址的时候,路径的前面一般要加上/
        例如 String path = "/a.html";
    重定向
    1.使用response完成
    2.重定向的本质是把资源路径通过响应返回给浏览器(通过响应头信息),让浏览器向这个新地址发送一个新请求
    3.如果request中有数据,重定向后在新的资源中是拿不到这个数据的(重定向会发一个全新的请求,但是数据在上一个老的请求中)
    4.由于重定向让浏览器发出新的请求,所以浏览器地址栏中的地址会变成新请求的地址
    5.在设置重定向的资源地址的时候,路径的前面一般不加/
        例如 String path = "a.html";
        但是如果一定要加/的话,那么还需要额外加上一个项目名
        例如 String path = "/web_test/a.html";
        同时也可以动态获取项目:req.getContextPath()
            String path = req.getContextPath()+"/a.html";

Demo:

package xin.string;

import java.io.IOException;

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;
@WebServlet("/checkname")
public class CheckByname extends HttpServlet{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		String url = "/failed.html";
		String servletUrl = "/checkpass";
		if(req.getParameter("username").equals("Tom")){
			req.getRequestDispatcher(servletUrl).forward(req, resp);
		}else{
			RequestDispatcher dispatcher = req.getRequestDispatcher(url);
			dispatcher.forward(req, resp);
		}		
	}
}

package xin.string;

import java.io.IOException;

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;

@WebServlet("/checkpass")
public class CheckBypasswrod extends HttpServlet{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		String url = "/hello.html";
		String failed = "error.html";
		if(req.getParameter("password").equals("123456")){
			RequestDispatcher dispatcher = req.getRequestDispatcher(url);
			dispatcher.forward(req, resp);
		}else{
			resp.sendRedirect(failed);
		}
	}
}

    以上两个程序完成了服务器内部跳转以及客户端重定向这些操作。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注