但是,它有很多不敷,最直不雅观的感想熏染该当便是:
在Java代码里输出HTML代码实在是太丢脸、太繁琐、太随意马虎出错了;如果想改变一下HTML呈现效果就必须修正HTML代码,以是还必须重新编译Java代码。以是,JSP技能应运而生了。
JSP的全称是JavaServer Page,截止到目前最新版本彷佛是2.3,但在JCP官网(https://jcp.org/en/home/index)又只能搜到2.1版本(关于JCP上如何下载规范可以参考这篇文章)。如果有读者知道如何下载JSP 2.3版本的规范(或者没有),请奉告一下。
Servlet要天生HTML
对付Web运用来说,HTML页面每每很主要,数量也比较多,每个页面中的HTML代码也比较多。
而动态天生的HTML页面也是如此,大部分展示构造/效果/元素都是相同的,仅仅只是数据不一样。
可以这么说,Servlet代码中大部分是HTML代码。
以是,我们是否能够利用逆向思维:在HTML页面中通过某种语法嵌入少量的Java代码,然后让工具自动天生Servlet的代码?
JSP核心事理答案当然是可行的,JSP正是这样的技能。
这种在HTML页面中嵌入Java代码的页面就叫JSP页面。我们编写JSP页面,由Servlet容器转换成Servlet并编译成Java字节码文件,当第一个该JSP页面的要求到来时Servlet容器就会加载对应的Servlet并天生Servlet工具,后面的处理就跟前面所先容的Servlet技能相同了。
以是,第一次要求JSP页面的时候,总会比较慢,由于须要转换成Servlet并编译,再加载Servlet类文件并天生Servlet实例。
当然,我们(便是Servlet容器的开拓者)就必须改造Servlet容器,让它能够识别、转换JSP页面,然后能够自动的编译转换成的Servlet代码。这样的Servlet容器就叫做JSP容器,以是合起来叫做Servlet/JSP容器。
Servlet/JSP容器乃至能够自动检测到JSP页面的修正并重新编译和加载,以是,我们修正JSP页面后并不须要重新启动Servlet/JSP容器。
可以说,JSP的核心事理/实质便是Servlet。
JSP基本语法既然是HTML代码中嵌入Java代码,那么JSP页面的主体当然便是HTML,这部分就利用HTML的语法编写。
那么Servlet/JSP容器是如何识别嵌入的Java代码呢?
JSP利用符号“<%”和“%>”来将Java代码或与Java代码干系的东西包围住,比如:
“<%--”和“--%>”及个中央的内容是JSP的注释,它不会发送到浏览器端,差异于HTML的注释“<!--”和“-->”。“<%@”和“%>”及个中央的的内容是JSP的指令,用来设置页面的一些参数,import依赖的Java包,包含其他JSP页面等等。“<%”和“%>”中间可以直接写Java代码,这叫JSP的脚本。“<%=”和“%>”及个中央的的内容是JSP的表达式,用来直接输出表达式的打算结果。“<%!”和“%>”及个中央的的内容是JSP的声明,用来声明该页面利用的变量和方法。以是,Servlet/JSP容器一旦碰着上述的符号,它就知道该如何转换成Java代码了。
JSP其他技能事实上,JSP技能在不断的蜕变(任何技能都是这样,蜕变便是为了进步,创造不敷,办理不敷)。
JSP其他的干系技能有:
JSP的动作,它很像HTML或XML的标签,我预测它便是利用下面的JSP的标签技能实现的,比如:<jsp:useBean id=\"大众xxx\"大众 class=\公众java.util.Date\"大众 /><jsp:setProperty name=\"大众xxx\公众 property=\公众yyy\"大众 value=\公众zzz\公众 /><jsp:getProperty name=\"大众xxx\"大众 property=\公众yyy\"大众 /><jsp:include page=\公众xxx/yyy.jsp\"大众> <jsp:param name=\"大众xxx\"大众 value=\"大众yyy\"大众 /></jsp:include><jsp:forward page=\公众xxx/yyy.jsp\"大众> <jsp:param name=\公众xxx\"大众 value=\"大众yyy\"大众 /></jsp:forward>JSP的标签,这包括JSP自带的标准标签JSTL(JSP Standard Tag Library,即JSP标准标签库)、可以扩展自己所须要标签的自定义标签技能和标签文件技能。它的利用很像XML标签,当然,扩展自己的标签就比较繁芜了。表达式措辞(Expression Language,简称EL),彷佛此技能与JSP技能是相互独立的,但JSP里面用它还是相称频繁的,不知道当时开拓EL是否紧张便是为了在JSP中利用,我没有去穷究了。JSP页面片段,紧张是为了肃清重复,提高复用。
可以明确的是,目前JSP的紧张用场便是起到一个模板的浸染,并只管即便采取EL来访问运用数据,而不再利用JSP声明、JSP表达式和JSP脚本来实现业务逻辑,业务逻辑交给独立的Servlet来实现(当然,后来涌现的MVC模式中Servlet仅用来充当掌握器)。
这样更好理解我们把JSP页面的内容分成两大类:
一类便是HTML代码,这个就像编写普通的HTML页面那样编写就行,我们把这类代码叫做模板元素。另一类便是JSP干系的部分,这是通过规定的某种符号来识别的,这类代码就叫做JSP语法元素。无论如何,一个JSP页面都会转换成一个Servlet,即不管是模板元素还是JSP语法元素,它终极都会转换成Java代码。
以是,转换成的这些Java代码一定在一个Servlet类的源代码中,而Servlet接口中最主要的方法便是那个service()方法。
这样看来,转换成的这些Java代码可以看作是service()方法中的内容,比如:
模板元素实在转换成Java代码便是:writer.println(\公众<html>\公众)等类似这样的。JSP脚本则直接拷贝即可。JSP隐式工具实际上是Servlet/JSP容器天生并传进来的参数,比如request便是HttpServletRequest实例、application便是ServletContext实例、config便是ServletConfig实例、pageContext便是javax.servlet.jsp.PageContext实例、out是javax.servlet.jsp.JspWriter实例(类似从ServletResponse.getWriter()得到的Writer)等等。JSP表达式就转换成:writer.print(\公众表达式的打算结果\"大众)。JSP动作和标签肯定就转换成对应的处理类的调用代码。EL则转成访问附加到某个隐式工具的属性中的数据,即getAttribute(\"大众xxx\公众)名为xxx的属性工具(它实在是你的业务实体类工具),然后就可以访问xxx中的数据。还有一些则转换成Servlet类文件的其他内容,比如:
JSP的page指令导入Java包的部分。JSP声明可以声明该页面利用的变量和方法,即该页面转换成的Servlet类的成员变量和成员方法。总结现在,我们就可以利用JSP技能来改造前面的租房网运用了。
我们要长于利用逆向思维;一旦你以为写代码很繁琐,很多重复的地方,那么就表示哪里有问题,或者该当改进,乃至有可能抽象出来一种新技能;JSP的实质便是Servlet,由于它须要被转换成Servlet;JSP目前一样平常用来当HTML模板,仅利用EL来访问数据,而不在个中编写Java脚本了。