JSP+Servlet+Struts2的基本原理学习笔记
2016-02-24 21:15
519 查看
一 JSP 基本原理
概念
JSP的本质是Servlet,当用户向指定Servlet发送请求时,Servlet利用输出流动态生成HTML页面,包括每个静态的HTML标签和所有在HTML页面中出现的内容,即JSP页面的内容有两部分:标准的HTML标签、静态的页面内容,这些内容与静态的HTML一致和受java程序控制的内容,由java脚本动态加载。
原理
事实上,JSP是Servlet的一种特殊形式(一个特殊的java类),每个JSP页面就是一个Servlet实例——JSP页面由系统编译成Servlet,Servlet再负责响应用户请求。即,JSP其实也是Servlet的一种简化,使用JSP时,其实还是使用Servlet,因为Web应用中的每个JSP页面都会由Servlet容器生成对应的Servlet。对于Tomcat而言,JSP页面生成的Servlet放在work路径对应的Web应用下。
如\webapps\myapp\test.jsp
当启动Tomcat后,可以在Tomcat的work\Catalina\localhost\myapp\org\apache\jsp目录下找到如下文件:test_jsp.java和test_jsp.class。这两个文件都是Tomcat生成的,Tomcat根据JSP页面生成对应Servlet的Java文件及class文件
init():初始化JSP/Servlet的方法
destroy():销毁JSP/Servlet之前的方法
service():对用户请求生成响应的方法
工作原理可以概括为如下:
当服务器启动后,当Web浏览器端发送过来一个页面请求时,Web服务器先判断是否是JSP页面请求。
如果该页面只是一般的HTML/XML页面请求,则直接将HTML/XML页面代码传给Web浏览器端。
如果请求的页面是JSP页面,则由JSP引擎检查该JSP页面,
如果该页面是第一次被请求、或不是第一次被请求但已被修改,则JSP引擎将此JSP页面代码转换成Servlet代码,
然后JSP引擎调用服务器端的Java编译器javac.exe对Servlet代码进行编译,
把它变成字节码(.class)文件,然后再调用JAVA虚拟机执行该字节码文件,然后将执行结果传给Web浏览器端。
如果该JSP页面不是第一次被请求,且没有被修改过,则直接由JSP引擎调用JAVA虚拟机执行已编译过的字节码.class文件,然后将结果传送Web浏览器端。
需要注意的是
JSP文件不是在服务器启动的时候转换成 Servlet 类的。而是在被客户端访问
的时候才可能发生转换的 ( 如 JSP 文件内容没有被更新等,就不再发生 Servlet 转换 )。
JSP页面中没有任何业务逻辑处理,它只是简单的检索Servlet先前创建的Beans或者对象,再将动态内容插入预定义的模板
经过上面的介绍可以总结为:
JSP文件必须在JSP服务器内运行
JSP文件必须生成Servlet才能执行
每个JSP页面的第一个访问者熟读很慢,因必须等JSP编译成Servlet
JSP页面的访问者无需安装客户端,甚至不需要可以运行的java运行环境
Servlet开发工作原理
流程图:
当客户端浏览器向服务器请求一个Servlet时,Servlet容器收到该请求后
首先到容器中检索与请求匹配的Servlet实例是否已经存在。
若不存在,则Servlet容器负责加载并实例化出该类Servlet的一个实例对象,接着容器框架负责调用该实例的init()方法来对实例做一些初始化工作,然后Servlet容器运行该实例的service() 方法。
若Servlet实例已经存在,则容器框架直接调用该实例的service()方法。
service()方法在运行时,自动派遣运行与用户请求相对应的doXX()方法来响应用户发起的请求。
通常,每个Servlet类在容器中只存在一个实例,每当请求到来时,则分配一条线程来处理该请求
2.Servlet生命周期
Servlet 没有 main 方法,不能够独立的运行,它的运行需要容器的支持,Tomcat 是最常用的 JSP/Servlet 容器。
Servlet 运行在 Servlet 容器中,并由容器管理从创建到销毁的整个过程。
Servlet 的生命周期
(1) 创建Servlet实例
Servlet容器装载和实例化一个Servlet,创建出该 servlet类的一个实例。
Servlet何时被创建:
1,默认情况下,当WEB客户第一次请求访问某个Servlet的时候,WEB容器将创建这个Servlet的实例。
2,当web.xml文件中如果
注意:在web.xml文件中,某些Servlet只有
(2) 初始化
在Servlet实例化完成之后,Web容器负责调用该Servlet实例的init()方法,在处理用户请求之前,来做一些额外的初始化工作。
(3) 处理请求
Servlet初始化后,将一直存在于容器中,用于响应客户端的请求。当Servlet容器接收到一个Servlet请求时,便运行与之对应的servlet实例的service()方法,service()方法再派遣运行与请求相对应的doXX(doGet,doPost)方法来处理用户请求。
对于用户到达Servlet的请求,Servlet容器会创建特定于这个请求的ServletRequest对象和ServletResponse对象,然后调用Servlet的service方法。service方法从ServletRequest对象获得客户请求信息,处理该请求,并通过ServletResponse对象向客户返回响应信息。
(4) 销毁
当 Servlet 容器决定将一个 Servlet 从服务器中移除时 ( 如 Servlet 文件被更新 ),便调用该 Servlet 实例的 destroy() 方法,在销毁该 Servlet 实例之前,来做一些其他的工作。
当WEB应用被终止,或Servlet容器终止运行,或Servlet容器重新装载Servlet新实例时,Servlet容器会先调用Servlet的destroy()方法,在destroy()方法中可以释放掉Servlet所占用的资源。
其中,(1)(2)(4) 在 Servlet 的整个生命周期中只会被执行一次。
在Struts2框架中的处理大概分为以下几个步骤
1 客户端初始化一个指向Servlet容器(例如Tomcat)的请求
2 请求被提交到一系列(主要是三层)的过滤器(Filter),如(ActionContextCleanUp、其他过滤器(SiteMesh等)、 FilterDispatcher)。注意这里是有顺序的,先ActionContextCleanUp,再其他过滤器(SiteMesh等)、最后到FilterDispatcher。
3 接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action ,FilterDispatcher是控制器的核心。
4 如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy
5 ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类
6 ActionProxy创建一个ActionInvocation的实例。
7 ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
8 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可 能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper
在上述过程中所有的对象(Action,Results,Interceptors等)都是通过ObjectFactory来创建的。
1、客户端浏览器发出HTTP请求.
2、根据web.xml配置,该请求被FilterDispatcher接收
3、根据struts.xml配置,找到需要调用的Action类和方法, 并通过IoC方式,将值注入给Aciton
4、Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证。
5、Action执行完毕,根据struts.xml中的配置找到对应的返回结果result,并跳转到相应页面
6、返回HTTP响应到客户端浏览器
由于web的应用时给予请求/响应架构的应用,所以不管哪个MVC WEB框架,都需要在web.xml中配置该框架的核心Serlet或Filter,这样才让框架接入web应用中
如果需要以Post方式提交请求,则定义包含表单数据的JSP页面。如果仅仅只是一GET方式发送请求,则无须此步骤。
定义处理用户请求的Action
这一步也是所有MVC框架中必不可少的。因这步Action是MVC的C,即控制器。在MVC框架中,控制器是由两部分组成,即拦截所有用户请求,处理请求的通用代码都是有核心控制器完成。而实际的业务控制由Action处理
配置Action
通过指定哪个请求对用哪个Action进行处理,从而让核心控制器根据该配置来创建合适的Action实例,并调用该Action的业务控制方法。
配置处理结果和物理视图资源之间的对应关系
如下代码的配置:
编写视图资源
概念
JSP的本质是Servlet,当用户向指定Servlet发送请求时,Servlet利用输出流动态生成HTML页面,包括每个静态的HTML标签和所有在HTML页面中出现的内容,即JSP页面的内容有两部分:标准的HTML标签、静态的页面内容,这些内容与静态的HTML一致和受java程序控制的内容,由java脚本动态加载。
原理
事实上,JSP是Servlet的一种特殊形式(一个特殊的java类),每个JSP页面就是一个Servlet实例——JSP页面由系统编译成Servlet,Servlet再负责响应用户请求。即,JSP其实也是Servlet的一种简化,使用JSP时,其实还是使用Servlet,因为Web应用中的每个JSP页面都会由Servlet容器生成对应的Servlet。对于Tomcat而言,JSP页面生成的Servlet放在work路径对应的Web应用下。
如\webapps\myapp\test.jsp
<!-- 这是一jsp页面--> <%@ page contentType="text/html;charset=GBK" language="java" errorPage="" %> <htmlxmlns="http://www.w3.org/1999/xhtml"> <head> <title>JSP页面</title> </head> <body> <!-- 下面是java脚本--> <% for(int i =0; i<7;i++){ out.println("<font size ='" + i + "'>"); %> 这是个验证页面 <br/> <%}%> </body> </html>
当启动Tomcat后,可以在Tomcat的work\Catalina\localhost\myapp\org\apache\jsp目录下找到如下文件:test_jsp.java和test_jsp.class。这两个文件都是Tomcat生成的,Tomcat根据JSP页面生成对应Servlet的Java文件及class文件
/* * Generated by the Jasper component of Apache Tomcat * Version: Apache Tomcat/8.0.8 * Generated at: 2014-05-23 16:56:11 UTC * Note: The last modified time of this file was set to * the last modified time of the source file after * generation to assist with modification tracking. */ package org.apache.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; public final class test_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent { private static final javax.servlet.jsp.JspFactory _jspxFactory = javax.servlet.jsp.JspFactory.getDefaultFactory(); private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants; private javax.el.ExpressionFactory _el_expressionfactory; private org.apache.tomcat.InstanceManager _jsp_instancemanager; public java.util.Map<java.lang.String,java.lang.Long> getDependants() { return _jspx_dependants; } public void _jspInit() { _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig()); } public void _jspDestroy() { } public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) throws java.io.IOException, javax.servlet.ServletException { final javax.servlet.jsp.PageContext pageContext; javax.servlet.http.HttpSession session = null; final javax.servlet.ServletContext application; final javax.servlet.ServletConfig config; javax.servlet.jsp.JspWriter out = null; final java.lang.Object page = this; javax.servlet.jsp.JspWriter _jspx_out = null; javax.servlet.jsp.PageContext _jspx_page_context = null; try { response.setContentType("text/html; charset=GBK"); pageContext = _jspxFactory.getPageContext(this, request, response, "", true, 8192, true); _jspx_page_context = pageContext; application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out; out.write("\r\n"); out.write("\r\n"); out.write("\r\n"); out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\r\n"); out.write("\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n"); out.write("<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n"); out.write("<head>\r\n"); out.write("\t<title> JSP页面 </title>\r\n"); out.write("\t<meta name=\"website\" content=\"http://www.crazyit.org\" />\r\n"); out.write("</head>\r\n"); out.write("<body>\r\n"); out.write("<!-- 下面是Java脚本 -->\r\n"); for(int i = 0 ; i < 7; i++) { out.println("<font size='" + i + "'>"); out.write("\r\n"); out.write("这是个验证页面</font>\r\n"); out.write("<br/>\r\n"); } out.write("\r\n"); out.write("</body>\r\n"); out.write("</html>"); } catch (java.lang.Throwable t) { if (!(t instanceof javax.servlet.jsp.SkipPageException)){ out = _jspx_out; if (out != null && out.getBufferSize() != 0) try { out.clearBuffer(); } catch (java.io.IOException e) {} if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); else throw new ServletException(t); } } finally { _jspxFactory.releasePageContext(_jspx_page_context); } } }
init():初始化JSP/Servlet的方法
destroy():销毁JSP/Servlet之前的方法
service():对用户请求生成响应的方法
工作原理可以概括为如下:
当服务器启动后,当Web浏览器端发送过来一个页面请求时,Web服务器先判断是否是JSP页面请求。
如果该页面只是一般的HTML/XML页面请求,则直接将HTML/XML页面代码传给Web浏览器端。
如果请求的页面是JSP页面,则由JSP引擎检查该JSP页面,
如果该页面是第一次被请求、或不是第一次被请求但已被修改,则JSP引擎将此JSP页面代码转换成Servlet代码,
然后JSP引擎调用服务器端的Java编译器javac.exe对Servlet代码进行编译,
把它变成字节码(.class)文件,然后再调用JAVA虚拟机执行该字节码文件,然后将执行结果传给Web浏览器端。
如果该JSP页面不是第一次被请求,且没有被修改过,则直接由JSP引擎调用JAVA虚拟机执行已编译过的字节码.class文件,然后将结果传送Web浏览器端。
需要注意的是
JSP文件不是在服务器启动的时候转换成 Servlet 类的。而是在被客户端访问
的时候才可能发生转换的 ( 如 JSP 文件内容没有被更新等,就不再发生 Servlet 转换 )。
JSP页面中没有任何业务逻辑处理,它只是简单的检索Servlet先前创建的Beans或者对象,再将动态内容插入预定义的模板
经过上面的介绍可以总结为:
JSP文件必须在JSP服务器内运行
JSP文件必须生成Servlet才能执行
每个JSP页面的第一个访问者熟读很慢,因必须等JSP编译成Servlet
JSP页面的访问者无需安装客户端,甚至不需要可以运行的java运行环境
二 Servlet&Struts基本知识
Servlet是Java提供的用于开发Web服务器应用程序的一个组件,运行在服务器端,由Servlet容器所管理,用于生成动态的内容。Servlet是平台独立的Java类,编写一个Servlet,实际上就是按照Servlet规范编写一个Java类Servlet开发工作原理
流程图:
当客户端浏览器向服务器请求一个Servlet时,Servlet容器收到该请求后
首先到容器中检索与请求匹配的Servlet实例是否已经存在。
若不存在,则Servlet容器负责加载并实例化出该类Servlet的一个实例对象,接着容器框架负责调用该实例的init()方法来对实例做一些初始化工作,然后Servlet容器运行该实例的service() 方法。
若Servlet实例已经存在,则容器框架直接调用该实例的service()方法。
service()方法在运行时,自动派遣运行与用户请求相对应的doXX()方法来响应用户发起的请求。
通常,每个Servlet类在容器中只存在一个实例,每当请求到来时,则分配一条线程来处理该请求
2.Servlet生命周期
Servlet 没有 main 方法,不能够独立的运行,它的运行需要容器的支持,Tomcat 是最常用的 JSP/Servlet 容器。
Servlet 运行在 Servlet 容器中,并由容器管理从创建到销毁的整个过程。
Servlet 的生命周期
(1) 创建Servlet实例
Servlet容器装载和实例化一个Servlet,创建出该 servlet类的一个实例。
Servlet何时被创建:
1,默认情况下,当WEB客户第一次请求访问某个Servlet的时候,WEB容器将创建这个Servlet的实例。
2,当web.xml文件中如果
<servlet>元素中指定了
load-on-startup>子元素时,Servlet容器在启动web服务器时,将按照顺序创建并初始化Servlet对象。
注意:在web.xml文件中,某些Servlet只有
<serlvet>元素,没有
<servlet-mapping>元素,这样我们无法通过url的方式访问这些Servlet,这种Servlet通常会在
<servlet>元素中配置一个
<load-on-startup>子元素,让容器在启动的时候自动加载这些Servlet并调用init()方法,完成一些全局性的初始化工作。
(2) 初始化
在Servlet实例化完成之后,Web容器负责调用该Servlet实例的init()方法,在处理用户请求之前,来做一些额外的初始化工作。
(3) 处理请求
Servlet初始化后,将一直存在于容器中,用于响应客户端的请求。当Servlet容器接收到一个Servlet请求时,便运行与之对应的servlet实例的service()方法,service()方法再派遣运行与请求相对应的doXX(doGet,doPost)方法来处理用户请求。
对于用户到达Servlet的请求,Servlet容器会创建特定于这个请求的ServletRequest对象和ServletResponse对象,然后调用Servlet的service方法。service方法从ServletRequest对象获得客户请求信息,处理该请求,并通过ServletResponse对象向客户返回响应信息。
(4) 销毁
当 Servlet 容器决定将一个 Servlet 从服务器中移除时 ( 如 Servlet 文件被更新 ),便调用该 Servlet 实例的 destroy() 方法,在销毁该 Servlet 实例之前,来做一些其他的工作。
当WEB应用被终止,或Servlet容器终止运行,或Servlet容器重新装载Servlet新实例时,Servlet容器会先调用Servlet的destroy()方法,在destroy()方法中可以释放掉Servlet所占用的资源。
其中,(1)(2)(4) 在 Servlet 的整个生命周期中只会被执行一次。
Struts2工作原理
流程图:在Struts2框架中的处理大概分为以下几个步骤
1 客户端初始化一个指向Servlet容器(例如Tomcat)的请求
2 请求被提交到一系列(主要是三层)的过滤器(Filter),如(ActionContextCleanUp、其他过滤器(SiteMesh等)、 FilterDispatcher)。注意这里是有顺序的,先ActionContextCleanUp,再其他过滤器(SiteMesh等)、最后到FilterDispatcher。
3 接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action ,FilterDispatcher是控制器的核心。
4 如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy
5 ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类
6 ActionProxy创建一个ActionInvocation的实例。
7 ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
8 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可 能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper
在上述过程中所有的对象(Action,Results,Interceptors等)都是通过ObjectFactory来创建的。
Struts2工作流程
请求–>响应的流程图:1、客户端浏览器发出HTTP请求.
2、根据web.xml配置,该请求被FilterDispatcher接收
3、根据struts.xml配置,找到需要调用的Action类和方法, 并通过IoC方式,将值注入给Aciton
4、Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证。
5、Action执行完毕,根据struts.xml中的配置找到对应的返回结果result,并跳转到相应页面
6、返回HTTP响应到客户端浏览器
Struts2应用的开发流程
在web.xml文件中定义核心Filter来拦截用户由于web的应用时给予请求/响应架构的应用,所以不管哪个MVC WEB框架,都需要在web.xml中配置该框架的核心Serlet或Filter,这样才让框架接入web应用中
如果需要以Post方式提交请求,则定义包含表单数据的JSP页面。如果仅仅只是一GET方式发送请求,则无须此步骤。
定义处理用户请求的Action
这一步也是所有MVC框架中必不可少的。因这步Action是MVC的C,即控制器。在MVC框架中,控制器是由两部分组成,即拦截所有用户请求,处理请求的通用代码都是有核心控制器完成。而实际的业务控制由Action处理
配置Action
通过指定哪个请求对用哪个Action进行处理,从而让核心控制器根据该配置来创建合适的Action实例,并调用该Action的业务控制方法。
配置处理结果和物理视图资源之间的对应关系
如下代码的配置:
<action name ="login" class="test.gmail.app.action.LoginAction"> <result name="input">/WEB-INF/content/loginForm.jsp</result> <result name="error">/WEB-INF/content/error.jsp</result> <result name="success">/WEB-INF/content/welcom.jsp</result> </action>
编写视图资源
相关文章推荐
- 继承,装饰者模式和动态代理之间的区别
- 《JAVA编程思想》日志(一)------对象导论
- 10个精妙的Java编码最佳实践
- 328. Odd Even Linked List
- 在springmvc中配置jedis:
- 简易的java操作数据库进行增删改查
- java多线程-Semaphore信号量使用
- 191. Number of 1 Bits
- Maven简明教程(2)---eclipse集成
- Java中遍历删除List多个元素
- JAVA内存溢出解析
- 235. Lowest Common Ancestor of a Binary Search Tree
- 【6-5】HBASE的Java接口
- Java中几种数据类型的转化
- 3、使用Java api 和 jni混合方式调用OpenCV
- Leetcode旅途三
- java 文件输入输出流 文件的复制
- 13. Roman to Integer
- SSM——Spring
- Struts2之文件下载