JavaWeb中的请求转发与响应重定向-----基本技能

请求转发

定义

(。・∀・)ノ゙嗨,也不说什么定义了,直接上大白话-----

就是当客户端向一个服务器A请求一个资源,但是这个服务器A上没有该资源,那么服务器A向有该资源的服务器B请求,服务器A得到资源后再将此资源转发给客户端;

请求转发分方式

forward转发

功能描述----浏览器向MyServlet4发出请求,但是MyServlet4里没有想要的资源,于是MyServlet4将请求转发至MyServlet5

代码1---->>>

@WebServlet(urlPatterns = "/MyServlet4.do",loadOnStartup = 7)
public class MyServlet4 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("MyServlet4响应---");
        String fruit = req.getParameter("fruit");
        System.out.println("fruit--"+fruit);
        //将请求转发给另一个对象

        //首先获得一个请求转发器
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("MyServlet5.do");
//    由请求转发器做出转发动作
       // forward模式 转发
requestDispatcher.forward(req,resp);
    }
}
@WebServlet(urlPatterns = "/MyServlet5.do",loadOnStartup = 8)
public class MyServlet5 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");
        System.out.println("MyServlet5.do--收到了请求");
        PrintWriter writer = resp.getWriter();
        String []apple={"红富士","嘎啦","金帅","乔纳金","昂林","红香蕉","北斗"};
        for (int i = 0; i < apple.length; i++) {
            writer.write(apple[i]+" ");
        }

    }
}

在这里插入图片描述
在这里插入图片描述
简单描述一下阶段一和阶段二

阶段一是服务器A 收到了请求,发现自己处理不了,于是将 该请求以及响应对象传给了服务器B,由服务器B对请求做出响应,注意 服务器B中的请求对象与服务器A中的请求对象是同一个,回应对象亦然(因为服务器A在forward 转发时将两个作为参数传给了服务器B)

那么问题就来了,我在服务器A中预先响应一些信息,那么客户端能接收到在服务器A中的响应吗?

试一下
在这里插入图片描述什么原因你呢???
原因就是在我们请求转发时,会将转发的resp对象中的信息完全清空,然后交由受托服务器去处理;
因此,在forward转发模式下,请求应该完全交给目标资源去处理,我们在源组件中,不要作出任何的响应处理;
在forward方法调用之前先响应----
1,设置了解码方式,那么在客户端也接收不到该信息;
2,没设置解码方式,那么会影响到 真正响应服务的的响应
在这里插入图片描述

在forward方法调用之后,做出响应
1,设置解码和不设置对真正的响应没有什么影响;因为在这之前已经将请求和响应对象转发给真正响应的服务器了;
感兴趣的可以自己验证;

小结----

/*
* 1请求转发是一种服务器的行为,是对浏览器屏蔽
* 2浏览器的地址栏不会发生变化
* 3请求的参数是可以从源组件传递到目标组件的
* 4请求对象和响应对象没有重新创建,而是传递给了目标组件
* 5请求转发可以帮助我们完成页面的跳转
* 6请求转发可以转发至WEB-INF里
* 7请求转发只能转发给当前项目的内部资源,不能转发至外部资源
* 8常用forward

include转发


@WebServlet(urlPatterns = "/MyServlet6.do",loadOnStartup = 9)
public class MyServlet6 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//include模式下 做出响应的时源组件,所以在原组件中也要设置解码格式
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write("你想要什么种类的苹果?");

       //向MyServlet7转发
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("MyServlet7.do");
        requestDispatcher.include(req,resp);
        resp.getWriter().write("我们的苹果很好吃");
        System.out.println("我们的苹果很好吃");
    }
}


@WebServlet(urlPatterns = "/MyServlet7.do",loadOnStartup = 10)
public class MyServlet7 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter writer = resp.getWriter();
        String []apple={"红富士","嘎啦","金帅","乔纳金","昂林","红香蕉","北斗"};
        for (int i = 0; i < apple.length; i++) {
            writer.write(apple[i]+" ");
        }
    }
}

在这里插入图片描述
分析一下可以发现,include转发方式 真正响应的是 源组件,
既然是源组件,那么就可以在源组件中做出响应,该响应可以在转发之前也可以在转发之后;

转发之前的响应内容放在转发之前,之后则放在转发之后;

即服务器A处理不了的请求转发给另一个服务器B,由服务器B将处理好的请求返回给该服务器A,服务器A在此回应的基础上再做一些回应内容的添加;
原理如下图----
在这里插入图片描述

forword()处理特点

1由于forword()方法先清空用于存放响应正文的缓冲区,因此源Servlet生成的响应结果不会被发送到客户端,只有目标资源生成的响应结果才会被发送到客户端。

2如果源Servlet在进行**请求转发之前,已经提交了如下方法(flushBuffer(),close()方法),那么forward()方法抛出IllegalStateException。**为了避免该异常,不应该在源Servlet中提交响应结果。
如果用了flushBuffer()或者close()方法会出现什么情况呢?

就是要转发到的服务器不会做出任何响应,即接受不到转发过来的请求;

在这里插入图片描述

flushBuffer()和close()方法分析---->>>>

在这里插入图片描述在这里插入图片描述

总结
服务器响应的时候会有一个缓存,如果没有调用resp.flushBuffer()或者write.flush(),那么会等着所有响应内容都打包好了再一块返回客户端;
如果使用了,则会处理完一块数据发送一块数据给客户端**

include()处理特点

include与forward转发相比,包含有以下特点:

1源Servlet与被包含的目标资源的输出数据都会被添加到响应结果中。

2在目标资源中对响应状态码或者响应头所做的修改都会被忽略。

1,请求转发是服务器的动作,对浏览器屏蔽的.所以浏览器看不到地址栏有什么变化;
2,请求的参数是可以从源组件中传递到目标组件中的
3,请求对象和响应对象并没有重新创建而是传递给了目标组件
4,请求转发可以帮助我们完成页面跳转;
在这里插入图片描述5,请求转发可以转发到Web-inf下的资源
即请求转发可以请求到当前项目里的内容而不可以申请外部资源

响应重定向


//注解模式开发servlet
@WebServlet(urlPatterns={"/myServlet8.do"})
public class MyServlet8 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("myServlet9收到了请求");
        String fruit = req.getParameter("fruit");
        System.out.println("fruit--"+fruit);
       //响应重定向
        resp.sendRedirect("myServlet9.do");

    }
}

//注解模式开发servlet
@WebServlet(urlPatterns={"/myServlet9.do"})
public class MyServlet9 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       // req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter writer = resp.getWriter();
        String []apple={"红富士","嘎啦","金帅","乔纳金","昂林","红香蕉","北斗"};
        for (int i = 0; i < apple.length; i++) {
            writer.write(apple[i]+" ");
        }
    }
}

在这里插入图片描述 那响应重定向的工作原理是怎样的呢?

在这里插入图片描述简言之就是浏览器请求时处理不了请求,回应了一句你去哪个服务器看看吧;

小结:
1,响应重定向—时浏览器行为,时服务器给出处理后让重新指向另一个服务器地址;
2,重定向时,请求对象和响应对象都会重新建立,所以第一次请求时的参数是不会携带的;
3,重定向依旧可以跳转到html/jsp等网页资源
4,由于重定向时浏览器行为,所以不能访问WEB-INF中的资源的’
5.重定向可以帮助跳转到外部资源的;

在这里插入图片描述
可以看到302 重定向的信息;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodeMartain

祝:生活蒸蒸日上!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值