JSP请求响应流程入门介绍
一个完整的jsp请求响应流程可以简单的使用下图表示:
过滤器:直观的了解,就是对请求做一个过滤作用,比如身份验证,验证不通过的不让他继续往下走
Servlet:请求处理中心,这个也是我们写业务逻辑的地方
JSP:页面
从上面的图可以了解到,当接收到一个请求时,它会先被过滤器刷一遍,这一步可以理解为对请求进行一些预处理,如字符编码,身份验证等等,如果满足条件就放行,否则重定向到其它页面(如异常页面),而那些放行的请求,会进一步去访问它们需要的资源
一、过滤器(Filter)
过滤器是一个类,通常它的作用可以总结为两点:
- 在客户端的请求访问后端资源之前,拦截这些请求。
- 在服务器的响应发送回客户端之前,处理这些响应。
过滤器是一个类,当然我们就可以自定义过滤器了,如下,我们定义一个过滤器:
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");
} }
我们定义过滤器需要实现javax.servlet.Filter接口,接口里面有三个方法:
init:应用程序初始化时,会创建过滤器实例,之后会执行init方法,而且整个周期只执行一次,同时init还有一个参数,可以获取到web.xml中配置过滤器时传入的参数信息
doFilter:真正的过滤器操作都在这里,doFilter方法对每个需要过滤的请求(路由满足过滤器配置的url-pattern)都会执行一遍,我们还可以使用FilterChai.doFilter方法将请求传递给下一个过滤器
destroy:在应用程序销毁的时候执行,可以在destroy方法中写一些释放内存的操作
上面的过滤器,我们只是简单的使用输出一些信息而且,现在我们可以运行一下,不过在运行前,我们需要在web.xml中配置我们的过滤器:
<?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>
上面的配置是说,filter和filter-mapping是一对,它们拥有同样的filter-name节点,当接收到一个请求时,会根据请求的路由和filter的url-pattern进行匹配,如果匹配成功,则会根据filter-name去查找对应的filter,进而执行对应的filter-class
上面的配置中的url-pattern是/*,它是匹配所有请求的意思,不管的的请求存不存在,都会匹配成功,进而执行过滤器的内容
过滤器可以创建多个,比如我们再创建一个过滤器MyFilter2:
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");
} }
web.xml中的配置如下,注意,MyFilter过滤器在MyFilter2前面
<?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>
注意,这里添加多个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方法,但是我们一般只重写一个,另一个直接调用了:
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>");
} }
和过滤器一样,我们需要在web.xml中进行配置:
<?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>
上面的配置是说拦截所有已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:
<%@ 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>
项目运行起来后,打开浏览器输入:http://localhost:8080/demo/index.jsp?name=zhangsan
控制台打印信息:
因为不是通过Servlet的,所以就没有Servlet的打印信息了
当然,我们也可以直接从Servlet中转发请求过来,我们修改MyServlet类中的代码如下
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);
} }
程序运行起来后,打开浏览器输入:http://localhost:8080/demo/hello/abc?name=zhangsan
控制台打印信息如下:
上面的信息有Servlet打印的信息,说明我们是有经过Servlet的
学习JSP,除了过滤器和Servlet需要了解,感兴趣的可以了解一下监听器,这里就不做过多解释了
JSP请求响应流程入门介绍的更多相关文章
- 浏览器与服务端请求响应流程与HTTP协议
浏览器与服务端请求响应流程图: 1.HTTP概要 1.1. 定义 HTTP(HyperText Transfer Protocol,超文本传输协议)最早就是计算机与计算机之间沟通的一种标准协议,这种 ...
- SpringMVC 请求响应流程
SpringMVC的工作原理图: SpringMVC流程 1. 用户发送请求至前端控制器DispatcherServlet. 2. DispatcherServlet收到请求调用HandlerMa ...
- 一次http请求响应流程
前端客户端 发起http请求 web服务器接收并解析http报文 通过WSGI协议发送给web框架 web框架创建请求对象 中间层处理 具体的视图处理-业务处理 中间层处理 创建http响应对象 返回 ...
- 阶段5 3.微服务项目【学成在线】_day02 CMS前端开发_25-前后端请求响应流程小结
看图
- nginx的请求接收流程(二)
在ngx_http_process_request_line函数中,解析完请求行之后,如果请求行的uri里面包含了域名部分,则将其保持在请求结构的headers_in成员的server字段,heade ...
- html5/css3响应式布局介绍及设计流程
html5/css3响应式布局介绍 html5/css3响应式布局介绍及设计流程,利用css3的media query媒体查询功能.移动终端一般都是对css3支持比较好的高级浏览器不需要考虑响应式布局 ...
- jsp当做第二个servlet request的生命周期 请求 响应 不管中间经历多少个servlet 只要最后一个serlvt执行后 则生命周期结束 request的域消失
jsp当做第二个servlet request的生命周期 请求 响应 不管中间经历多少个servlet 只要最后一个serlvt执行后 则生命周期结束 request的域消失
- HTTP请求与服务器响应流程
1. HTTP 简介 1.1定义 1.2 请求/响应报文格式 1.3请求方式--GET/POST 状态码 1.4 响应状态 2. HTTP请求,浏览器做了什么, 服务端处理解析过程 1:HTT ...
- springmvc执行流程详细介绍
1.什么是MVC MVC是Model View Controller的缩写,它是一个设计模式 2.springmvc执行流程详细介绍 第一步:发起请求到前端控制器(DispatcherServlet) ...
随机推荐
- 【C#】【假条生成系统】【单位剖析】如何判断在文本框输入了几个人名?
我们规定,人名和人名之间使用顿号隔开 那么, 1个人,就是0个顿号 2个人,就是1个顿号 3个人,就是2个顿号 -- 所以我们可以判断文本框中顿号的出现次数. 出现0次,则为1人,出1次,则为两人. ...
- Gitlab Flow到容器
一.简介 长话短说,本文全景呈现我司项目组gitlab flow && devops Git Flow定义了一个项目发布的分支模型,为管理具有预定发布周期的大型项目提供了一个健壮的框架 ...
- Log4j2又爆雷!2.16.0存在DOS风险,升级2.17.0可解决
本以为,经过上周的2.16.0版本升级,Log4j2的漏洞修复工作,大家基本都要告一段落了. 万万没想到,就在周末,Log4j官方又发布了新版本:2.17.0 该版本主要修复安全漏洞:CVE-2021 ...
- 【大咖直播】Elastic 企业搜索实战工作坊(第二期)
借助 App Search 提供的内置功能,您可轻松打造卓越的搜索体验.直观的相关度调整以及开箱即用的搜索分析,不仅可以优化所提供的内容,其提供的 API 还可帮助您将位于各处的所有内容源关联在一起. ...
- CF134A Average Numbers 题解
Content 有 \(n\) 个数 \(a_1,a_2,a_3,...,a_n\).试求出使得 \(a_i\) 与其他所有整数的算术平均值相等的所有 \(i\). 数据范围:\(2\leqslant ...
- idea删除同一个模块后新建模块显示被占用
当我们某个模块因为什么原因需要删除重建的时候 ,输入完模块名称并不能创建出来,这是因为模块已经被注册 解决办法: 1.右键点击项目名称---选择Load/Unload Modules 2.将已经删除的 ...
- DG修复:异常关库导致的数据库启动失败ORA-01110及GAP修复
问题描述:正在应用的备库是一套11.2.0.4的rac环境,但是被直接crsctl stop cluster集群强制关库,重新启动之后导致数据库启动失败,报错 Errors in file /u01/ ...
- AcWing1264. 动态求连续区间和 (树状数组做法)
1.题目 给定 n 个数组成的一个数列,规定有两种操作,一是修改某个元素,二是求子数列 [a,b] 的连续和. 输入格式 第一行包含两个整数 n 和 m,分别表示数的个数和操作次数. 第二行包含 n ...
- SpringBoot(SpringMVC)使用addViewControllers设置统一请求URL重定向配置
只需要在配置中重写 addViewControllers方法 import org.springframework.context.annotation.Configuration; import o ...
- JAVAWeb项目实现在线预览、打开office文件
Web项目实现在线预览浏览word.ppt.excel文档方法 调用以下链接 https://view.officeapps.live.com/op/view.aspx?src=你的文档绝对路径 这里 ...