一个完整的jsp请求响应流程可以简单的使用下图表示:

  

  过滤器:直观的了解,就是对请求做一个过滤作用,比如身份验证,验证不通过的不让他继续往下走

  Servlet:请求处理中心,这个也是我们写业务逻辑的地方

  JSP:页面

  

  从上面的图可以了解到,当接收到一个请求时,它会先被过滤器刷一遍,这一步可以理解为对请求进行一些预处理,如字符编码,身份验证等等,如果满足条件就放行,否则重定向到其它页面(如异常页面),而那些放行的请求,会进一步去访问它们需要的资源

一、过滤器(Filter)

  过滤器是一个类,通常它的作用可以总结为两点:

  • 在客户端的请求访问后端资源之前,拦截这些请求。
  • 在服务器的响应发送回客户端之前,处理这些响应。

  过滤器是一个类,当然我们就可以自定义过滤器了,如下,我们定义一个过滤器:    

  

  1. package demo;
  2.  
  3. import java.io.IOException;
  4.  
  5. import javax.servlet.Filter;
  6. import javax.servlet.FilterChain;
  7. import javax.servlet.FilterConfig;
  8. import javax.servlet.ServletException;
  9. import javax.servlet.ServletRequest;
  10. import javax.servlet.ServletResponse;
  11.  
  12. public class MyFilter implements Filter {
  13.  
  14. @Override
  15. public void destroy() {
  16. // TODO Auto-generated method stub
  17. System.out.println("MyFilter:destroy");
  18. }
  19.  
  20. @Override
  21. public void doFilter(ServletRequest paramServletRequest, ServletResponse paramServletResponse,
  22. FilterChain paramFilterChain) throws IOException, ServletException {
  23. // TODO Auto-generated method stub
  24. System.out.println("MyFilter:Do Somethind Before");
  25. paramFilterChain.doFilter(paramServletRequest, paramServletResponse);//放行进入下一个过滤器
  26. System.out.println("MyFilter:Do Somethind After");
  27. }
  28.  
  29. @Override
  30. public void init(FilterConfig paramFilterConfig) throws ServletException {
  31. // TODO Auto-generated method stub
  32. System.out.println("MyFilter:init");
  33. }
  34.  
  35. }

  我们定义过滤器需要实现javax.servlet.Filter接口,接口里面有三个方法:

  init:应用程序初始化时,会创建过滤器实例,之后会执行init方法,而且整个周期只执行一次,同时init还有一个参数,可以获取到web.xml中配置过滤器时传入的参数信息

  doFilter:真正的过滤器操作都在这里,doFilter方法对每个需要过滤的请求(路由满足过滤器配置的url-pattern)都会执行一遍,我们还可以使用FilterChai.doFilter方法将请求传递给下一个过滤器

  destroy:在应用程序销毁的时候执行,可以在destroy方法中写一些释放内存的操作

  上面的过滤器,我们只是简单的使用输出一些信息而且,现在我们可以运行一下,不过在运行前,我们需要在web.xml中配置我们的过滤器:   

  

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns="http://java.sun.com/xml/ns/javaee"
  4. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  5. version="3.0">
  6. <display-name>demo</display-name>
  7.  
  8. <filter>
  9. <filter-name>MyFilter</filter-name>
  10. <filter-class>demo.MyFilter</filter-class>
  11. </filter>
  12. <filter-mapping>
  13. <filter-name>MyFilter</filter-name>
  14. <url-pattern>/*</url-pattern>
  15. </filter-mapping>
  16. </web-app>

    上面的配置是说,filter和filter-mapping是一对,它们拥有同样的filter-name节点,当接收到一个请求时,会根据请求的路由和filter的url-pattern进行匹配,如果匹配成功,则会根据filter-name去查找对应的filter,进而执行对应的filter-class

  上面的配置中的url-pattern是/*,它是匹配所有请求的意思,不管的的请求存不存在,都会匹配成功,进而执行过滤器的内容

  

  过滤器可以创建多个,比如我们再创建一个过滤器MyFilter2:    

  

  1. package demo;
  2.  
  3. import java.io.IOException;
  4.  
  5. import javax.servlet.Filter;
  6. import javax.servlet.FilterChain;
  7. import javax.servlet.FilterConfig;
  8. import javax.servlet.ServletException;
  9. import javax.servlet.ServletRequest;
  10. import javax.servlet.ServletResponse;
  11.  
  12. public class MyFilter2 implements Filter {
  13.  
  14. @Override
  15. public void destroy() {
  16. // TODO Auto-generated method stub
  17. System.out.println("MyFilter2:destroy");
  18. }
  19.  
  20. @Override
  21. public void doFilter(ServletRequest paramServletRequest,
  22. ServletResponse paramServletResponse, FilterChain paramFilterChain)
  23. throws IOException, ServletException {
  24. // TODO Auto-generated method stub
  25. System.out.println("MyFilter2:Do Somethind Before");
  26. paramFilterChain.doFilter(paramServletRequest, paramServletResponse);//放行进入下一个过滤器
  27. System.out.println("MyFilter2:Do Somethind After");
  28. }
  29.  
  30. @Override
  31. public void init(FilterConfig paramFilterConfig) throws ServletException {
  32. // TODO Auto-generated method stub
  33. System.out.println("MyFilter2:init");
  34. }
  35.  
  36. }

  web.xml中的配置如下,注意,MyFilter过滤器在MyFilter2前面  

  

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns="http://java.sun.com/xml/ns/javaee"
  4. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  5. version="3.0">
  6. <display-name>demo</display-name>
  7.  
  8. <filter>
  9. <filter-name>MyFilter</filter-name>
  10. <filter-class>demo.MyFilter</filter-class>
  11. </filter>
  12. <filter-mapping>
  13. <filter-name>MyFilter</filter-name>
  14. <url-pattern>/*</url-pattern>
  15. </filter-mapping>
  16. <filter>
  17. <filter-name>MyFilter2</filter-name>
  18. <filter-class>demo.MyFilter2</filter-class>
  19. </filter>
  20. <filter-mapping>
  21. <filter-name>MyFilter2</filter-name>
  22. <url-pattern>/*</url-pattern>
  23. </filter-mapping>
  24. </web-app>

  注意,这里添加多个filter可能会导致web.xml报错,导致程序无法启动,解决办法是删除web.xml,右键项目=》Java EE Tools=>Generate Deployment Descriptor Stub重新生成web.xml即可

  随便一个请求访问后(如:http://localhost:8080/demo)结果如下:

  

  它的执行顺序是

  init和destroy:后载入的过滤器先执行

  doFilter:因为MyFilter在MyFilter2前面,所以先执行,当输入MyFilter:Do Somethind Before,通过paramFilterChain.doFilter(paramServletRequest, paramServletResponse);将执行交给MyFilter2了,这个,当MyFilter2执行完输出后,才接着执行MyFilter后面的输出。

二、Servlet

  Servlet是服务器端程序,简单的理解,就是Servlet是按用户需求处理请求的地方,比如保存前端传递过来的数据等等

  我们可以创建一个Servlet,但是需要继承javax.servlet.http.HttpServlet,并重写doGet和doPost方法,但是我们一般只重写一个,另一个直接调用了:    

  

  1. package demo;
  2.  
  3. import java.io.IOException;
  4. import java.io.PrintWriter;
  5.  
  6. import javax.servlet.ServletException;
  7. import javax.servlet.http.HttpServlet;
  8. import javax.servlet.http.HttpServletRequest;
  9. import javax.servlet.http.HttpServletResponse;
  10.  
  11. public class MyServlet extends HttpServlet {
  12.  
  13. @Override
  14. protected void doGet(HttpServletRequest req, HttpServletResponse resp)
  15. throws ServletException, IOException {
  16. // TODO Auto-generated method stub
  17. System.out.println("MyServlet:doGet");
  18. doPost(req, resp);
  19. }
  20.  
  21. @Override
  22. protected void doPost(HttpServletRequest req, HttpServletResponse resp)
  23. throws ServletException, IOException {
  24. // TODO Auto-generated method stub
  25. String name = req.getParameter("name");
  26. if (name == null) {
  27. name = "World";
  28. }
  29.  
  30. System.out.println("MyServlet:doPost");
  31.  
  32. PrintWriter out = resp.getWriter();
  33. out.print("<html>");
  34. out.print("<head>");
  35. out.print("<title>Hello</title>");
  36. out.print("</head>");
  37. out.print("<body>");
  38. out.print("<p>Hello " + name + "</p>");
  39. out.print("</body>");
  40. out.print("</html>");
  41. }
  42.  
  43. }

  和过滤器一样,我们需要在web.xml中进行配置:    

  

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns="http://java.sun.com/xml/ns/javaee"
  4. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  5. version="3.0">
  6. <display-name>demo</display-name>
  7.  
  8. <filter>
  9. <filter-name>MyFilter</filter-name>
  10. <filter-class>demo.MyFilter</filter-class>
  11. </filter>
  12. <filter-mapping>
  13. <filter-name>MyFilter</filter-name>
  14. <url-pattern>/*</url-pattern>
  15. </filter-mapping>
  16. <filter>
  17. <filter-name>MyFilter2</filter-name>
  18. <filter-class>demo.MyFilter2</filter-class>
  19. </filter>
  20. <filter-mapping>
  21. <filter-name>MyFilter2</filter-name>
  22. <url-pattern>/*</url-pattern>
  23. </filter-mapping>
  24.  
  25. <servlet>
  26. <servlet-name>MyServlet</servlet-name>
  27. <servlet-class>demo.MyServlet</servlet-class>
  28. </servlet>
  29. <servlet-mapping>
  30. <servlet-name>MyServlet</servlet-name>
  31. <url-pattern>/hello/*</url-pattern>
  32. </servlet-mapping>
  33. </web-app>

  上面的配置是说拦截所有已hello开头的请求,不管资源是否存在,经过过滤器之后,统统进入MyServlet,并输入Hello实例,现在,让项目跑起来,打开浏览器,输入:http://localhost:8080/demo/abc

  

  

  控制台输出如下:

  

  为什么这么输出,读者可以好好体会一下

  我们还可以携带一个参数,比如http://localhost:8080/demo/hello/abc?name=zhangsan

  

三、JSP模板

  JSP文件类似Html文件,可以理解为JSP页面就是可以写Java代码的Html页面,了解JSP页面,就必须要回JSP的九大内置对象了,介绍的文章很多,这里就不介绍了,可以参考https://www.cnblogs.com/leirenyuan/p/6016063.html

  上面的例子中,我们在Servlet中通过PrintWriter直接输出了html字符串,这样对于开发篇幅大的页面很不方便,jsp就是个不错的选择

  首先,我们创建一个index.jsp:  

  

  1. <%@ page language="java" contentType="text/html; charset=utf-8"
  2. pageEncoding="utf-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <html>
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  7. <title>Hello</title>
  8. </head>
  9. <body>
  10. <p>我是JSP页面</p>
  11. <p>Hello
  12. <%
  13. String name = request.getParameter("name");
  14. if(name==null){
  15. name="World";
  16. }
  17.  
  18. out.print(name);
  19. %></p>
  20. </body>
  21. </html>

  项目运行起来后,打开浏览器输入:http://localhost:8080/demo/index.jsp?name=zhangsan

  

  控制台打印信息:

  

  因为不是通过Servlet的,所以就没有Servlet的打印信息了

  当然,我们也可以直接从Servlet中转发请求过来,我们修改MyServlet类中的代码如下    

  

  1. package demo;
  2.  
  3. import java.io.IOException;
  4. import java.io.PrintWriter;
  5.  
  6. import javax.servlet.ServletException;
  7. import javax.servlet.http.HttpServlet;
  8. import javax.servlet.http.HttpServletRequest;
  9. import javax.servlet.http.HttpServletResponse;
  10.  
  11. public class MyServlet extends HttpServlet {
  12.  
  13. @Override
  14. protected void doGet(HttpServletRequest req, HttpServletResponse resp)
  15. throws ServletException, IOException {
  16. // TODO Auto-generated method stub
  17. System.out.println("MyServlet:doGet");
  18. doPost(req, resp);
  19. }
  20.  
  21. @Override
  22. protected void doPost(HttpServletRequest req, HttpServletResponse resp)
  23. throws ServletException, IOException {
  24. // TODO Auto-generated method stub
  25. //String name = req.getParameter("name");
  26. //if (name == null) {
  27. // name = "World";
  28. //}
  29.  
  30. System.out.println("MyServlet:doPost");
  31.  
  32. //PrintWriter out = resp.getWriter();
  33. //out.print("<html>");
  34. //out.print("<head>");
  35. //out.print("<title>Hello</title>");
  36. //out.print("</head>");
  37. //out.print("<body>");
  38. //out.print("<p>Hello " + name + "</p>");
  39. //out.print("</body>");
  40. //out.print("</html>");
  41.  
  42. req.getRequestDispatcher("/index.jsp").forward(req, resp);
  43. }
  44.  
  45. }

  程序运行起来后,打开浏览器输入:http://localhost:8080/demo/hello/abc?name=zhangsan

  

  控制台打印信息如下:

  

  上面的信息有Servlet打印的信息,说明我们是有经过Servlet的

  学习JSP,除了过滤器和Servlet需要了解,感兴趣的可以了解一下监听器,这里就不做过多解释了

  

JSP请求响应流程入门介绍的更多相关文章

  1. 浏览器与服务端请求响应流程与HTTP协议

    浏览器与服务端请求响应流程图: 1.HTTP概要 1.1. 定义 HTTP(HyperText Transfer  Protocol,超文本传输协议)最早就是计算机与计算机之间沟通的一种标准协议,这种 ...

  2. SpringMVC 请求响应流程

    SpringMVC的工作原理图: SpringMVC流程 1.  用户发送请求至前端控制器DispatcherServlet. 2.  DispatcherServlet收到请求调用HandlerMa ...

  3. 一次http请求响应流程

    前端客户端 发起http请求 web服务器接收并解析http报文 通过WSGI协议发送给web框架 web框架创建请求对象 中间层处理 具体的视图处理-业务处理 中间层处理 创建http响应对象 返回 ...

  4. 阶段5 3.微服务项目【学成在线】_day02 CMS前端开发_25-前后端请求响应流程小结

    看图

  5. nginx的请求接收流程(二)

    在ngx_http_process_request_line函数中,解析完请求行之后,如果请求行的uri里面包含了域名部分,则将其保持在请求结构的headers_in成员的server字段,heade ...

  6. html5/css3响应式布局介绍及设计流程

    html5/css3响应式布局介绍 html5/css3响应式布局介绍及设计流程,利用css3的media query媒体查询功能.移动终端一般都是对css3支持比较好的高级浏览器不需要考虑响应式布局 ...

  7. jsp当做第二个servlet request的生命周期 请求 响应 不管中间经历多少个servlet 只要最后一个serlvt执行后 则生命周期结束 request的域消失

    jsp当做第二个servlet  request的生命周期   请求 响应  不管中间经历多少个servlet 只要最后一个serlvt执行后 则生命周期结束  request的域消失

  8. HTTP请求与服务器响应流程

    1. HTTP 简介 1.1定义 1.2 请求/响应报文格式 1.3请求方式--GET/POST     状态码 1.4 响应状态 2. HTTP请求,浏览器做了什么, 服务端处理解析过程 1:HTT ...

  9. springmvc执行流程详细介绍

    1.什么是MVC MVC是Model View Controller的缩写,它是一个设计模式 2.springmvc执行流程详细介绍 第一步:发起请求到前端控制器(DispatcherServlet) ...

随机推荐

  1. 【Linux】【Services】【VersionControl】Git基础概念及使用

    1. 简介 1.1. 版本控制工具: 本地版本控制系统: 集中化版本控制系统:CVS,SVN 分布式版本控制系统: BitKeeper,Git 1.2. 官方网站: https://git-scm.c ...

  2. matplotlib 画图中图和次坐标轴

    一: fig.add_axes 画图中图 fig = plt.figure() x = np.arange(1, 9, 1) y = np.linspace(1, 10, 8) left, botto ...

  3. 【VSCode】检测到 #include 错误。请更新 includePath。已为此翻译单元(C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\i686-

    win+r 运行cmd 输入"gcc -v -E -x c -"获取mingw路径: 我的: #include "..." search starts here ...

  4. 莫烦python教程学习笔记——使用波士顿数据集、生成用于回归的数据集

    # View more python learning tutorial on my Youtube and Youku channel!!! # Youtube video tutorial: ht ...

  5. Identity Server 4 从入门到落地(九)—— 客户端User和Role的解析

    前面的部分: Identity Server 4 从入门到落地(一)-- 从IdentityServer4.Admin开始 Identity Server 4 从入门到落地(二)-- 理解授权码模式 ...

  6. socket通道

    一.socket 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. 就是两个进程,跨计算机,他俩需要通讯的话,需要通过网络对接起来.这就是 socket 的作 ...

  7. vue文件上传及压缩(canvas实现压缩)

    // 读取文件结果 afterRead(files) { let that = this; let file = files.file; if (file === undefined) { retur ...

  8. 可视报表(Project)

    <Project2016 企业项目管理实践>张会斌 董方好 编著 原来一直有一个执念,做项目的人电脑上一定要安装Project软件,今天突然知道了,原来领导的电脑上,可以不装,因为,Pro ...

  9. C#面对抽象编程第一讲

    闲话不多说,面向对象编程是高级语言的一个特点,但是把它概括成面向抽象更容易直击灵魂,经过了菜鸟大家都要面对的是不要写这么菜的代码了. 上例子,这应该是大家都很熟悉耳熟能详的代码, so easy. 1 ...

  10. libevent源码学习(13):事件主循环event_base_loop

    目录开启事件主循环执行事件主循环校对时间 阻塞/非阻塞处理激活队列中的event事件主循环的退出event_base_loopexitevent_base_loopbreak开启事件主循环       ...