JSP、Servlet:重定向和请求转发

web项目

1、重定向

   Response对象在请求头中设置转发属性

//把响应头中的状态码改为302
response.setStatus(302);
//在请求头中设置location属性为要转发的路径
response.setHeader("location","http://www.sohu.com");

(1)这类请求首先客户端发起初始请求 http://localhost:8080/abc 这个我们配置的请求Servlet

GET /abc HTTP/1.1

Host: localhost:8080 User-Agent: insomnia/6.5.4 Accept: /

(2)Servlet通过response修改了状态码为302,并在响应头中添加转发路径 location属性,下面的响应信息发送到了客户端浏览

HTTP/1.1 302 < Content-Type: text/html;charset=utf-8 < Content-Language: zh-CN

< location:http://www.sohu.com

< Content-Length: 1072 < Date: Wed, 14 Aug 2019 07:18:10 GMT

(3)浏览器接收到响应消息后,发现响应是302,就在头属性中找出location属性,重新封装下面的Http请求 http://www.sohu.com ,再次发出请求

扫描二维码关注公众号,回复: 9032553 查看本文章

GET / HTTP/1.1

Host:http://www.sohu.com User-Agent: insomnia/6.5.4 Accept: /

因为直接操作响应头的代码有点麻烦,所以response把上面的两行代码封装成了sendRedirect()方法

特点:可以实现跨域转发(从localhost转到sohu.com)

response.sendRedirect("http://www.sohu.com");//重定向的过程
//等同于
//把响应头中的状态码改为302
response.setStatus(302);
//在请求头中设置location属性为要转发的路径
response.setHeader("location","http://www.sohu.com");

辨析重定向与请求转发:

转发是服务器行为,重定向是客户端行为。为什么这样说呢,这就要看两个动作的工作流程:
转发过程:客户浏览器发送http请求----》web服务器接受此请求--》调用内部的一个方法在容器内部完成请求处理和转发动作----》将目标资源发送给客户;在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。
重定向过程:客户浏览器发送http请求----》web服务器接受后发送302状态码响应及对应新的location给客户浏览器--》客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址----》服务器根据此请求寻找资源并发送给客户。在这里location可以重定向到任意URL,既然是浏览器重新发出了请求,则就没有什么request传递的概念了。在客户浏览器路径栏显示的是其重定向的路径,客户可以观察到地址的变化的。重定向行为是浏览器做了至少两次的访问请求的。
 

2、请求转发(服务器端)

(1)创建请求派发对象(ps:请求派发就是请求转发)

RequestDispatcher dispatcher = request.getRequestDispatcher("/bbc");//得到请求派发对象

(2)forWard(request,response)

dispatcher.forward(request,response);//转发

说明:用forward()方法转发,第一个Servlet无法向客户端响应,只有转给的第二个Servlet可以向客户端响应

(3)include(request,response)

dispatcher.include(request,response);//包含

说明:用include方法转发,第一个Servlet和第二个Servlet均可向客户端响应,响应顺序按代码顺序响应,形成一种第一个Servlet的响应信息包含第二个Servlet的响应信息效果。

code:

servlet1:

//请求转发
//        response.setStatus(302);
//        response.setHeader("location","http://www.sohu.com");
//        response.sendRedirect("http://www.sohu.com");//重定向
        response.getWriter().println("Hi every body!");
        RequestDispatcher dispatcher = request.getRequestDispatcher("/bbc");//得到请求派发对象
//        dispatcher.forward(request,response);//转发
        dispatcher.include(request,response);//包含
        response.getWriter().println("Hi every body!");
        System.out.println("asdfsdasdafafdsa");

servlet2:

public class OtherServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().println("Hello World !");
        response.getWriter().flush();
    }
}

补充:

服务器修改响应码跳转:

Redirect的实现

将response的状态码设为302

通过头部的"Location"指定重定向的路径

注:302是临时跳转

301是永久跳转,即每次访问都会跳转

302每次访问时都会先到达原路径,然后经过一次跳转后达到新的路径

301只有第一次访问时,会有一个有原路径跳转新路径的过程,之后在访问原路径是,就会直接到达新路径,而不再经过原路径跳转的过程

但301的使用要慎重,因为使用301后,重定向的路径会缓存到用户的浏览器中,用户访问时会只会从缓存中读取重定向的路径,而这个缓存没有过期时间的指定.如果用户不主动清缓存,则这个跳转会一直进行,此时在服务端是不可控的.

发布了64 篇原创文章 · 获赞 47 · 访问量 9557

猜你喜欢

转载自blog.csdn.net/weixin_42194284/article/details/99618795