请求转发

定义

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

就是当客户端向一个服务器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]+" ");
        }

    }
}

JavaWeb中的请求转发与响应重定向-----基本技能_java
JavaWeb中的请求转发与响应重定向-----基本技能_java_02
简单描述一下阶段一和阶段二

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

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

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

在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]+" ");
        }
    }
}

JavaWeb中的请求转发与响应重定向-----基本技能_java_05
分析一下可以发现,include转发方式 真正响应的是 源组件,
既然是源组件,那么就可以在源组件中做出响应,该响应可以在转发之前也可以在转发之后;

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

即服务器A处理不了的请求转发给另一个服务器B,由服务器B将处理好的请求返回给该服务器A,服务器A在此回应的基础上再做一些回应内容的添加;
原理如下图----
JavaWeb中的请求转发与响应重定向-----基本技能_重定向_06

forword()处理特点

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

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

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

JavaWeb中的请求转发与响应重定向-----基本技能_服务器_07

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

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

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

include()处理特点

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

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

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

1,请求转发是服务器的动作,对浏览器屏蔽的.所以浏览器看不到地址栏有什么变化;
2,请求的参数是可以从源组件中传递到目标组件中的
3,请求对象和响应对象并没有重新创建而是传递给了目标组件
4,请求转发可以帮助我们完成页面跳转;
JavaWeb中的请求转发与响应重定向-----基本技能_请求转发_105,请求转发可以转发到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]+" ");
        }
    }
}

JavaWeb中的请求转发与响应重定向-----基本技能_http_11 那响应重定向的工作原理是怎样的呢?

JavaWeb中的请求转发与响应重定向-----基本技能_服务器_12简言之就是浏览器请求时处理不了请求,回应了一句你去哪个服务器看看吧;

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

JavaWeb中的请求转发与响应重定向-----基本技能_http_13
可以看到302 重定向的信息;