JSP:Java Server Page
1.JSP是什么:Java Server Page 是一种动态网页开发技术
jsp页面是以.jsp结尾的文件,是J2EE的一套规范。 JSP=Java+JSP标签+html+css.html文件是静态页面 js
.jsp 文件是动态页面
jsp页面允许我们在html代码中嵌入java代码,这样我们就可以在html中使用java代码来完成的功能了
简单的理解,jsp就是html页面+java代码,但是jsp中能写的内容还不止这些,可以包含如下内容:
①html标签 ②css ③javascript ④java代码 ⑤EL表达式
⑥引入并使用其他标签库,例如jstl标签库、struts2标签库等
所以jsp页面里面除了能写之前在html里面写东西之外,还可以写很多和java相关的东西,比如java代码、el表达式、动态标签库等(这些东西的本质都是执行java代码)
注意:jsp页面中可以只有java代码,也可以一句java代码也没有,也可以一句html页面也没有
****使用jsp页面完成一个HelloWorld程序
2.JSP的功能
a)JSP的作用来替换servlet显示信息的功能。
jsp本质上讲就是servlet,只不过servlet擅长控制,跳转,业务处理;jsp擅长前台展示.
out.println("<html><body><h1>"+h+"</h1>");
.....
out.println("</body></html>);
b)做动态网页开发
c)分层模式:Model1:javaBean,jsp组成(JSP除了做界面还要做控制层)
MVC模式:将控制层和视图层分离。
1) M(Model 模型)--->JavaBean,java类;包含三层架构
2) V(View 视图)--->jsp、html(显示)
3) C(Controller 控制器)---> Servlet(控制和转发请求) 、Struts2
3.jsp的运行
浏览器可以直接运行html页面,但是不能直接运行jsp页面。jsp是需要在拥有jsp引擎的服务器中运行的,例如tomcat服务器,所以jsp是运行在服务器端的,运行完之后,把动态生成的html页面再使用io流写回给浏览器,浏览器接收并且解析后再呈现出来效果.
4.jsp和servlet的关系
简单的讲, 一个jsp页面就是一个servlet。
jsp页面第一次被访问的时候,会被tomcat服务器编译成一个java类。这个java类默认继承HttpJspBase类,而HttpJspBase类是HttpServlet的子类。我们编写的jsp页面最终就被tomcat服务器编译成了一个HttpServlet的子类,所以说jsp本身就是一个servlet。那么jsp为什么是需要运行在tomcat服务器中原因也就很好理解了。jsp页面被tomcat服务器编译成的java文件及其class文件保存在tomcat服务器里面的work目录中,在这里的代码中,我们还可以看见它是如何使用io流把生成的html页面代码一行一行写回给浏览器的。
5.jsp的生命周期---JSP本身就是Servlet
1) 翻译阶段 hello.jsp--->hello_jsp.java
当容器接受到客户端第一次对jsp的请求后,先判断被请求的jsp是否存在,若不存在返回404错误,若存在,将该jsp先翻译成一个Servlet类。
2) 编译阶段 hello_jsp.java---->hello_jsp.class客户端第一次访问jsp页面,在服务器把jsp翻译成java文件并编译成class文件后,服务器会加载这个class文件内容,并且创建出此servlet对象(因为jsp就是一个servlet),然后调用这个servlet对象中的init方法进行初始化
如果我们想给jsp进行自定义的初始化内容,只要在【jsp声明】中重写_jspInit()方法即可。(查看源码可知)
例如:
<%!
public void jspInit(){
System.out.println("我的jsp自定义初始化");
}
%>
3) 执行阶段客户端访问jsp页面的时候,服务器会调用其对应的servlet对象中的一个指定方法_jspService(request,response),就是在这个_jspService(request,response)方法中使用io流,把动态生成的html一行一行写给了浏览器。注:本来是调用servlet对象中的service方法的,但是在HttpJspBase中重写的service方法中又调用了这个_jspService(request,response)方法
4) 销毁阶段
当服务器正常关闭的时候,jsp对应的servlet对象会被销毁,并且调用servlet中的destroy方法
如果我们在jsp对应的servlet对象销毁时完成一些工作,只要在jsp声明中重写jspDestroy()方法即可。(查看源码可知)
例如:
<%!
public void jspDestroy(){
System.out.println("我的jsp进行销毁");
}
%>
补充:
1) 如果被请求的jsp源文件内容发生变化,那么要重新将jsp翻译成Servlet,再编译、装载和实例化,最后运行Servlet。
2) 如果第二次请求jsp时,此时若被请求的jsp已经有对应的Servlet实例,那么就直接运行该Servlet。
3)通过上述jsp的生命周期可知,写完一个jsp项目之后,第一次部署运行的时候,整个项目的运行速度会慢一些,因为第一次访问运行jsp的时候,需要先翻译成.java文件,然后再编译成.class文件,最后再运行,这个过程会耗费一些时间,但是第二访问运行的时候就会比较快了.
//script.jsp
6.jsp中的元素:脚本元素,指令元素,动作元素6.1 脚本元素 :嵌套写java代码
a) 声明(Declaration)
语法: <%!声明的内容%>
作用: 在servlet中声明一些成员变量、成员方法和内部类
特点: 声明被翻译进servlet后变成了成员变量、成员方法和内部类
注意: 不能使用表达式和隐含对象
b) 表达式(Expression)
语法: <%=expression%>
作用: 将expression输出到out(输出流)中,expression可以是算术、逻辑、常量、关系表达式、变量、有返回值的方法、 jsp中的9种隐含对象。
类型 名字 含义
PageContext pageContext 当前的jsp页面的上下文
HttpServletRequest request 封装请求的信息
HttpSession session 会话对象
ServletContext application 指web应用
Object page 当前的jsp页面,指针this
HttpServletResponse response 封装响应的信息
JspWriter out 输出流
ServletConfig config 配置信息
Throwable exception 异常信息 (当isErrorPage=true时,才可以使用该对象)
特点: 表达式翻译进servlet后变成了out.print(expression),该代码处于_jspService()方法中。
注意: expression都一律被转换成字符串后再写到输出流out(JspWriter)中。另外,expression中不能有分号(;)。
c) 脚本(Scriptlet)
语法: <%java code%>
作用: 在jsp中嵌入任何java代码,不能嵌入成员变量、成员方法。所以在此模块申明的变量为局部变量。任何逻辑的代码都可以放在脚本标签中。如for循环,匿名或者局部内部类,连接数据库,创建对象等
特点: 脚本被翻译进servlet的_jspService()方法中。
6.2 指令元素:指令主要用来提供整个JSP网页相关的信息,并且用来设定JSP页面的相关属性
a) page指令
语法: <%@ page attributeName="attribuerValue"...%>
作用: 利用page指令中的属性可以和容器进行通信,这些属性的设置,对整个jsp都有影响。
page指令中的属性:
① language="java":定义当前页面使用的编程语言,目前只能是java
② contentType="text/html;charset=UTF-8"
定义response中的内容类型和编码格式和jsp页面的编码格式,
翻译后变成response.setContentType("text/html;charset=UTF-8")。
③ pageEncoding="UTF-8"定义当前jsp页面的编码格式
④i sErrorPage="true|false" 表明当前的页面是否为其它页面的errorPage目标,默认为false。
如果设置为true,则可以使用exception对象;反之,如果设置为false,则不可以使用exception对象
⑤ errorPage="error.jsp"默认忽略,定义此页面出现异常时调用的页面
⑥ import="package.class,package2.class2"和一般的java import意义一样,用","来隔开
⑦ session="true|false" 默认为true,指定这个jsp中是否可以使用session
⑧ buffer="none|8kb|sizekb" 默认为8kb,指定到客户端输出流的缓冲模式,
如果是none则不缓冲,如果指定数值,那么输出就用不小于这个值的缓冲区进行缓冲。
⑨ autoFlush="true|false" 默认为true
true 当缓冲区满时,到客户端的输出被刷新;false 当缓冲区满时,出现运行异常,表示缓冲溢出
⑩ isThreadSafe="true|false" 默认为true,用来设置jsp文件是否能支持多线程的使用。
如为true,那么一个jsp能够同时处理多个用户的请求;反之,一个jsp只能一次处理一个请求。
(11) info="text"关于jsp页面的信息,定义一个字符串,可以使用getServletInfo()获得
(12) extends="package.class"指定jsp对应的servlet类继承某个父类
(13) isELIgnored="true|false" 指定EL表达式语言是否被忽略,如为true则忽略,反之可以使用EL。
header.html
footer.html
b) include指令
语法: <%@ include file="url"%>,称为静态导入(静态包含)
作用: 在一个页面中导入另一个页面的内容(这些内容一般不会有变化,如公司的标题和版权等信息)。
特点: 在jsp翻译成servlet后就将把被导入的页面内容嵌入到servlet中。导入时间发生在 翻译阶段。被导入的资源: html、xml、jsp等
优点: 执行效率高(只翻译一次)
缺点: ①当被导入页面的内容发生变化,那么jsp必须要重新被翻译。②如果导入的多个页面,其中的一个页面的内容发生变化,就需要将所有的页面都翻译一次。
c) taglib指令
<%@ taglib uri="" prefix=""%>指定在jsp中要使用的标签库描述文件(*.tld)的路径
6.3 动作元素(jsp自带的标准标签)
语法: <jsp:tagName/>
a) 动态导入(动态包含)
语法: <jsp:include page="url" flush="true|false"/> 或者
<jsp:include page="url" flush="true|false">
{<jsp:param …/>}*
</jsp:include>
特点: 动态导入发生在 执行阶段,也就是在运行serlvet的时候才动态生成被导入页面的内容,然后嵌入到调用页面,最后将两个页面的内容一起,返回给客户端。
注意: 在翻译阶段并没有生成被导入页面的内容。没有跳转,请求还是同一个
缺点: 执行效率没有静态导入高
优点: 如果被导入页面的内容发生变化,调用页面不必重新翻译。
b) forward(服务器内部跳转)
语法: <jsp:forward page="url"/>或者
<jsp:forward page="url">
{<jsp:param …/>}*
</jsp:forward>
login.jsp 登录页面
loginCl.jsp 处理登录,
如果用户名和密码都是briup
就动态导入success.jsp
如果用户名和密码不是briup
就服务内部跳转到login.jsp
7.jsp中的注释7.1 HTML/XML注释
语法: <!-- content -->
注意: 它只能注释html、xml中的静态内容。不能注释脚本元素、指令元素和动作元素。如果注释,它们还是会被编译执行。
7.2 隐藏注释
语法: <%-- content --%>注意: 它可以注释jsp中所有的内容。
7.3 脚本注释语法: <%
//java code
/**
java code
*/
/*
java code
*/
%>
三种注释的区别:
servlet源文件 客户端页面源文件 浏览器显示
HTML/XML注释 出现 出现 不显示
隐藏注释 不出现 不出现 不显示
脚本注 出现 不出现 不显示
8.jsp页面中的路径
一般情况下,jsp中路径问题是和我们之前在servlet中讨论的html里面的路径问题是一样的,但是在jsp中可以动态获得该项目的url。
如果在jsp页面的上面写了这样一个脚本:
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
并且再<head>标签中加入了一个子标签:
<base href="<%=basePath%>" />
那么在这个jsp页面中,我们再去写上一个相对路径(最左边没有加/的那种路径),它就不是相对于地址栏中的当前路径了,而是要相对于这个basePath变量所代表的这个路径.