JSP的小心得
问题:Web容器(例如Tomcat)是怎么来执行jsp文件的?
首先它会将放在webapps目录下的jsp文件(这里以hello.jsp为例)翻译成hello_jsp.java文件并编译为hello_jsp.class(注意:生成的文件名都是小写字母),存放在Tomcat安装目录\work\Catalina\localhost\webDemo\org\apache\jsp路径下,打开.java源文件,你会看到hello_jsp类继承了httpJspBase类。而HttpJspBase类又是HttpServlet的子类,所以hello_jsp类也就间接实现了Servlet接口,也就是说Web容器把jsp文件转换成了一个servlet类了
然后Web容器根据配置文件(web.xml)和客户端(浏览器)的请求URL来确定使用哪一个servlet类.接下来调用这个servlet类的service()方法。在hello_jsp.java中看不到这个service()方法,并不代表它没有这个方法,只代表它没有重写这个方法。(除了重写之外,从父类继承的方法在其子类中,都是隐藏的,所以你看不到。)那么如果想看看在这个类中从其父类继承得到的方法长什么样?很简单!找到有这个方法的父类,查看方法的源码即可。那么如果需要调用这个类的service()方法怎么办?放心,No problem呀,它会去寻找所有父类里有这个方法的父类,然后再执行这个父类的方法体(在这里我们把这个机制或者行为笑称为“儿子继承的东西没找到,咱不怕,去找老子”),在这里说明一下:在子类中调用继承的方法,这个方法就是子类的方法,即SubClass.method(),只不过执行的方法体内容和其父类中的方法体内容一模一样而已。那么接着咱们就来说说这个父类HttpJspBase,在它的源码中,你会看到两个方法,第一个方法_japService(),被其子类hello_jsp类重写了。另外一个方法,源码如下
public void service(HttpServletRequest quest,HttpServletResponse response) throws ServletException,IOException{
_jspService(request,response);
}
这个父类中的servce()方法,子类hello_jsp继承得到的service方法也就是它。看到没有,多么简单的一个方法呀!上面提过了Web容器在确定使用哪一个sevlet类后,接着要干嘛?当然就是调用这个servlet的service()方法了,开始执行它的方法体,方法体中也没啥复杂的事情,就是调用本类中的_japService()方法,也就是hello_jsp类中的重写父类的_jspService()。
咱们接着看这个重写的_jspService()的方法体,里面有若干个out.write();这个方法的实参不就是jsp文件的HTML内容吗?哦,所以才有我们在浏览器上看到的输出内容。
所以在父类里定义的service()方法的作用我觉得很大:它把我们原始的继承Serlet接口并重写其service()方法的习惯转变为了继承HttpJspBase类并重写其_jspService()方法。这是一种技术上的改进和分支吧,也就造就了JSP技术的发展吧。与之类似的是HttpServlet类,它也间接实现了Servlet接口,重写了service()方法,特别是它继承了元老级的GenericServlet(这个类可是直接实现Servlet接口的第一代类呀,可谓是亲生的嫡长子呀!它提供了很多方法,可以说是一个重大改革,也为HttpServlet铺好了路,关于它以后有空再讲)。那么我们来看看Httpservlet类实现的service()方法吧
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException { HttpServletRequest request;
HttpServletResponse response; try {
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
} catch (ClassCastException e) {
throw new ServletException("non-HTTP request or response");
}
service(request, response);
}
HttpServletRequest和HttpServletResponse分别是ServletRequest和ServletResponse的子类,这样经过强转型,再最后调用自己的service方法,成功完成了接口方法到基类方法的转移了呀!还没有完,接下来才是HttpServlet的高明之处:看看他自己定义的那个service()的源码吧
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException { String method = req.getMethod(); if (method.equals(METHOD_GET)) {
long lastModified = getLastModified(req);
if (lastModified == -1) {
// servlet doesn't support if-modified-since, no reason
// to go through further expensive logic
doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
} catch (IllegalArgumentException iae) {
// Invalid date header - proceed as if none was set
ifModifiedSince = -1;
}
if (ifModifiedSince < (lastModified / 1000 * 1000)) {
// If the servlet mod time is later, call doGet()
// Round down to the nearest second for a proper compare
// A ifModifiedSince of -1 will always be less
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
} } else if (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp); } else if (method.equals(METHOD_POST)) {
doPost(req, resp); } else if (method.equals(METHOD_PUT)) {
doPut(req, resp); } else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp); } else if (method.equals(METHOD_OPTIONS)) {
doOptions(req,resp); } else if (method.equals(METHOD_TRACE)) {
doTrace(req,resp); } else {
//
// Note that this means NO servlet supports whatever
// method was requested, anywhere on this server.
// String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs); resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
}
}
比较长,言而言之,就是这些个逻辑实现,将Web容器最先调用servlet类的service()方法转移到了调用servlet类的doGet(),doPOST()等方法上,因为看不到这些底层的实现代码,所以就让我们产生了HttpServlet的入口是doGet()方法的假象。当然这也带来了简化流程的好处:继承了HttpServlet类的子类只要重写doGet (),doPOST()等方法即可。
总结:jsp实质上还是servlet,是一种加强版的servlet技术吧
JSP的小心得的更多相关文章
- ASP.NET MVC Autofac依赖注入的一点小心得(包含特性注入)
前言 IOC的重要性 大家都清楚..便利也都知道..新的ASP.NET Core也大量使用了这种手法.. 一直憋着没写ASP.NET Core的文章..还是怕误导大家.. 今天这篇也不是讲Core的 ...
- 下列哪个为JSP的小脚本的标签?(选择1项)
下列哪个为JSP的小脚本的标签?(选择1项) A.<% %> B.<@ %> C.<%! %> D.<%– %> 解答:A
- Qt使用com组件的一点小心得(使用Qt自带的工具dumpcpp生成.h和.cpp文件)
这几天工作中要用到Qt调用com组件,主要用到的类型有dll和ocx,使用他们的方法很简单:1.将com组件注册到系统中.2.使用Qt自带的工具dumpcpp将com组件生成cpp和头文件.3.然后就 ...
- 拼接Sql语句小心得
在往数据库插入数据时,需要根据数据和数据库中的列信息进行拼接,在本篇文章中,输出小心得.使用语言为 python. 拼接原始列信息 比如待插入数据库列信息为 deptNo,dName, Locate, ...
- BUI Webapp用于项目中的一点小心得
接触BUI也有一段时间,也用在了移动端的项目开发中,总的来说,该框架用起来也挺灵活的,控件可以自由定制,前提是自己能认真地学习该框架的api,因为api里面说的东西比较详细,如果没有仔细看的,可能有些 ...
- 用java编网页的学习流程,我的一些小心得(初学java到高深运用)
(1)java基础:首先得会写int,String,for循环,数组,**等等(熟练各种基础的关键字,各种java自带的排序,随即等等算法)什么是封装,继承,多态,然后private,public,p ...
- RIME-使用小心得
从4月份我才接触到RIME输入法,当时的感觉上相见恨晚的,现在感觉也不错,时至今日,想写点东西,也算是小感触吧. RIME称为中州韵输入法引擎,是开放源代码的输入法软件,其主页是http://rime ...
- 简单而又复杂的jsp(小知识)
JSP中的page标签中的pageEncoding属性和contentType属性 pageEncoding的默认值为ISO-8859-1 contentType的默认属性为:text/html; c ...
- Unity仪表盘显示UGUI制作小心得
最近在做设备仪表参数参数显示,由于模型摆放位置经常修改,加之要求不能在模型的下面添加东西,显示界面的位置也不得不跟着修改,一来二去就烦了,想了解决办法,现在总结如下: 1.仍然在模型下面新建Panel ...
随机推荐
- Redis的Set数据类型
Sets 就是一个集合,集合的概念就是一堆不重复值的组合.利用Redis提供的Sets数据结构,可以存储一些集合性的数据,比如在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一 ...
- Baseball Game
You're now a baseball game point recorder. Given a list of strings, each string can be one of the 4 ...
- js正则验证表达式
//上传文件大小验证 $.fn.checkFileTypeAndSize = function (options) { //默认设置 var defaults = { allowedExtension ...
- C# 用tabcontrol实现窗体类似网页排版的显示
这里做的比较简陋,可以美化下 把form设置为非顶级控件,直接放在tabcontrol里边,然后实现tabcontrol的拖拽移除tabpage显示form以及添加tabpage mousemove的 ...
- Django——model进阶(待完成)
https://www.cnblogs.com/yuanchenqi/articles/7570003.html 一.QuerySet 1.可切片 使用Python 的切片语法来限制查询集记录的数目 ...
- JavaScript(Two)
innerHtml xx.innerHtml 读取元素内的所有Html内容 xx.innerHtml = 新的值 替换元素内的所有Html内容 JS中不予许出现"-"; font- ...
- 使用angular帮你实现拖拽
拖拽有多种写法,在这里就看一看angular版的拖拽. <!DOCTYPE html> <html ng-app="myApp"> <head> ...
- java原生文件打包
一.背景 前端时间,自己做的项目需要打包功能,不想再引外部的jar包 便用java.util.zip做了下该功能 二.适用场景 生成多个word.excel.xml等文件,并要求打包下载的情形 例:项 ...
- 导致SharePoint发生Timeout的几处门槛设置
IIS connection time-out setting =========================== 如何修改? Click Start, point to All Programs ...
- 序列化Serializable
public interface Serializable 类的序列化由实现java.io.Serializable接口的类启用. 不实现此接口的类将不会使任何状态序列化或反序列化. 可序列化类的所有 ...