JSP请求响应流程入门介绍

Wesley13
• 阅读 454

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

  JSP请求响应流程入门介绍

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

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

  JSP:页面

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

一、过滤器(Filter)

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

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

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

   JSP请求响应流程入门介绍 JSP请求响应流程入门介绍

package demo;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class MyFilter implements Filter {

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
        System.out.println("MyFilter:destroy");
    }

    @Override
    public void doFilter(ServletRequest paramServletRequest, ServletResponse paramServletResponse,
            FilterChain paramFilterChain) throws IOException, ServletException {
        // TODO Auto-generated method stub
        System.out.println("MyFilter:Do Somethind Before");
        paramFilterChain.doFilter(paramServletRequest, paramServletResponse);//放行进入下一个过滤器
        System.out.println("MyFilter:Do Somethind After");
    }

    @Override
    public void init(FilterConfig paramFilterConfig) throws ServletException {
        // TODO Auto-generated method stub
        System.out.println("MyFilter:init");
    }

}

View Code

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

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

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

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

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

   JSP请求响应流程入门介绍 JSP请求响应流程入门介绍

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    <display-name>demo</display-name>

    <filter>
        <filter-name>MyFilter</filter-name>
        <filter-class>demo.MyFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

View Code

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

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

  JSP请求响应流程入门介绍

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

   JSP请求响应流程入门介绍 JSP请求响应流程入门介绍

package demo;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class MyFilter2 implements Filter {

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
        System.out.println("MyFilter2:destroy");
    }

    @Override
    public void doFilter(ServletRequest paramServletRequest,
            ServletResponse paramServletResponse, FilterChain paramFilterChain)
            throws IOException, ServletException {
        // TODO Auto-generated method stub
        System.out.println("MyFilter2:Do Somethind Before");
        paramFilterChain.doFilter(paramServletRequest, paramServletResponse);//放行进入下一个过滤器
        System.out.println("MyFilter2:Do Somethind After");
    }

    @Override
    public void init(FilterConfig paramFilterConfig) throws ServletException {
        // TODO Auto-generated method stub
        System.out.println("MyFilter2:init");
    }

}

View Code

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

   JSP请求响应流程入门介绍 JSP请求响应流程入门介绍

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    <display-name>demo</display-name>

    <filter>
        <filter-name>MyFilter</filter-name>
        <filter-class>demo.MyFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter>
        <filter-name>MyFilter2</filter-name>
        <filter-class>demo.MyFilter2</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFilter2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

View Code

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

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

  JSP请求响应流程入门介绍

  它的执行顺序是

  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方法,但是我们一般只重写一个,另一个直接调用了:    

   JSP请求响应流程入门介绍 JSP请求响应流程入门介绍

package demo;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        System.out.println("MyServlet:doGet");
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        String name = req.getParameter("name");
        if (name == null) {
            name = "World";
        }
        
        System.out.println("MyServlet:doPost");

        PrintWriter out = resp.getWriter();
        out.print("<html>");
        out.print("<head>");
        out.print("<title>Hello</title>");
        out.print("</head>");
        out.print("<body>");
        out.print("<p>Hello " + name + "</p>");
        out.print("</body>");
        out.print("</html>");
    }

}

View Code

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

   JSP请求响应流程入门介绍 JSP请求响应流程入门介绍

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    <display-name>demo</display-name>

    <filter>
        <filter-name>MyFilter</filter-name>
        <filter-class>demo.MyFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter>
        <filter-name>MyFilter2</filter-name>
        <filter-class>demo.MyFilter2</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFilter2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <servlet>
        <servlet-name>MyServlet</servlet-name>
        <servlet-class>demo.MyServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/hello/*</url-pattern>
    </servlet-mapping>
</web-app>

View Code

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

  JSP请求响应流程入门介绍

  控制台输出如下:

  JSP请求响应流程入门介绍

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

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

  JSP请求响应流程入门介绍

三、JSP模板

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

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

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

   JSP请求响应流程入门介绍 JSP请求响应流程入门介绍

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Hello</title>
</head>
<body>
    <p>我是JSP页面</p>
    <p>Hello 
        <%
            String name = request.getParameter("name");
            if(name==null){
                name="World";
            }
            
            out.print(name);
        %></p>
</body>
</html>

View Code

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

  JSP请求响应流程入门介绍

  控制台打印信息:

  JSP请求响应流程入门介绍

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

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

   JSP请求响应流程入门介绍 JSP请求响应流程入门介绍

package demo;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        System.out.println("MyServlet:doGet");
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        //String name = req.getParameter("name");
        //if (name == null) {
        //    name = "World";
        //}
        
        System.out.println("MyServlet:doPost");

        //PrintWriter out = resp.getWriter();
        //out.print("<html>");
        //out.print("<head>");
        //out.print("<title>Hello</title>");
        //out.print("</head>");
        //out.print("<body>");
        //out.print("<p>Hello " + name + "</p>");
        //out.print("</body>");
        //out.print("</html>");
        
        req.getRequestDispatcher("/index.jsp").forward(req, resp);
    }

}

View Code

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

  JSP请求响应流程入门介绍

  控制台打印信息如下:

  JSP请求响应流程入门介绍

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

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

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Easter79 Easter79
3年前
swap空间的增减方法
(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这