简介:JSP是Sun公司为了解决Servlet在响应是不适合向外输出页面而提供的一种解决方案。JSP中既可以写HTML代码,也可以写java代码,解决了既要处理逻辑又要向外输出页面的难题。
JSP在第一次访问时,会被翻译成一个Servlet,访问JSP后看到的页面,其实就是Servlet在向外输出,而且第二次访问时,直接访问翻译后的Servlet。
JSP语法
1.模板元素:html代码
1)直接写在jsp页面中的内容称之为jsp页面中的模板元素。
2)模板元素在翻译过来的servlet中被out.write()原样输出到浏览器中。如:
out.write("\...index.jsp....\r\n");
2.JSP表达式
1)<%= 脚本表达式 %>常量、变量、表达式
2)在翻译过来的Servlet中,计算表达式的值原样输出,如:
out.print( 100+8 );
3.JSP脚本片段:<% 若干java语句 %>
1)在翻译过来的Servlet中,脚本片段被复制粘贴到对应位置执行(注意:写在jsp脚本片段中的内容,在翻译过来的Servlet中是方法的局部变量)
翻译前
<% for(int i=0; i<5; i++){ %>
Hello JSP~~~~~<br/>
<% } %>
翻译后
for(int i=0; i<5; i++){
out.write("\r\n");
out.write("\t\tHello JSP~~~~~<br/>\r\n");
out.write("\t");
}
2)多个脚本片段之间的变量可以互相访问
3)在某一个脚本片段中的java代码可以是不完整的,但是要求在翻译过来的Servlet中整体的代码必须是完整符合java语法的
4)任何文本、HTML标记、JSP元素必须在脚本片段之外。
4.JSP声明(不常用,可以用来定义方法、静态代码块、静态常量)
格式:<%! java代码 %>
写在jsp声明中的内容,在翻译过来的Servlet中会和service方法平级,称为类的成员,声明的是实例成员
5.JSP注释
格式:<%-- JSP注释 --%>
1)被JSP注释注释的内容, 在翻译的过程中被抛弃, 不会被翻译
<%-- out.write("aaa"); --%>
2)被java注释注释的内容, 在翻译的过程中被当作脚本片段翻译到servlet中, 但是由于被注释了, 所以也不会执行
<% //out.write("bbb"); %>
3)被HTML注释注释的内容, 在翻译过程中直接当作模版元素原样输出到浏览器, 也会出现在浏览器上。
<!-- <% out.write("ccc"); %> -->
!!!在jsp中最好使用jsp注释, 因为HTML注释后的java脚本还可能被执行。
6.JSP指令
<%@ 指令名称 若干属性声明... %>不会直接产生输出,用来指挥解析引擎如何来翻译当前JSP页面中其他部分的内容
1)page指令:用来声明当前JSP页面的基本属性的,page指令可以写在JSP页面的任意位置,但是为了可读性考虑,一般情况下最好放在JSP页面的最前面。格式:<%page..%>
page指令属性介绍
[ language="java" ] 当前JSP使用的开发语言;
[ extends="package.class" ] 当前JSP翻译成servlet后要继承的类,注意此值必须是一个servlet的子类,一般情况下不要改;
[ import="{ package.class | package.*}, ..." ] 导入需要使用到的包
可以在一个page指令的import属性中导入多个包,包名用逗号隔开。也可以通过多个page指令来分别导包。
[ session="true | false" ] 用来指定当前页面是否使用session,如果设置为true,则翻译过来的servlet中将会有对session对象的引用,于是可以直接在JSP中使用session隐式对象。但是这将导致一旦访问JSP就会调用request.getSession()方法,可能导致不必要的空间浪费。如果确定JSP中不需要session可以设为false。
[ errorPage="relative_url" ] 如果页面出错,将要跳转到的页面,除了在JSP中使用此属性指定错误页面外也可以在web.xml中配置整个web应用的错误页面,如果两个都设置则JSP中的此属性起作用
<error-page>
<error-code>404</error-code>
<location>/error/404.jsp</location>
/error-page>
[ isErrorPage="true | false" ] 如果设置此属性为false, 翻译过来的servlet中将不会含有Exception隐式对象,其中封装的就是上一个页面中抛出的异常信息,即上一个页面设置的errorPage属性的url为设置了isErrorPage属性页面的地址。
[ pageEncoding="characterSet | ISO-8859-1" ] 服务器翻译JSP时使用的编码集。可以保证文件的保存和浏览器显示,都使用相同的字符集。
[ buffer="none | 8kb | sizekb" ] out隐式对象所使用的缓冲区的大小,如果超过了指定内容的大小,会自动的flush(将out缓冲区中的数据放到response中)
[ autoFlush="true | false" ] out隐式对象是否自动刷新缓冲区,默认为true,不需要更改
2)include指令实现的包含叫做静态包含
多个jsp文件被翻译成index_jsp.java文件的过程中,就将需要包含的页面的内容直接拿进来,共同生成一个文件,最终由一个Servlet向外输出数据,这是源文件级别的包含,每次用户访问,请求不需要再多个Servlet之间进行包含,而是直接由一个Servlet返回应答内容;其他方式的包含叫做动态包含:被包含的页面各自翻译成Servlet,包含的过程其实就是各个Servlet分别执行后在输出流上的合并。
总结:静态包含的效率要高于动态包含,尽量使用静态包含。
3)taglib指令:指定在当前的JSP当中使用某一个标签库。
导入tld标签库文件
JSTL标签库
prefix为前缀,表示用什么来调用标签库中的标签,uri指定具体标签库的地址
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
JSP的九大隐式对象
概述:JSP翻译引擎在将JSP翻译成servlet的过程中, 在servlet里预先定义了九个对象, 因此我们可以在JSP页面中直接使用这九个对象
1.page(代表当前对象,即:JSP翻译后的Servlet实例)
2.request(代表本次的请求对象)
3.response(代表本次服务器给用户的应答对象)
4.config(ServletConfig)
5.application(ServleContext)
6.session(这个对象出现的前提是page属性中的session为true)
7.exception(封装的是前一个页面中封装的异常信息)
8.out(相当于response.getWriter();)
区别在于out对象自带缓冲区,使用out的话会先到达out缓冲区,然后到达response缓冲区,因为最后所有数据的最终目的地是response缓冲区,所以如果out和response.getWriter()混用可能会造成输出顺序上的混乱。
9.pageContext(代表当前JSP页面的运行环境的对象,通过该对象可以访问页面中的共享数据)
PageContext对象功能:
1)作为入口对象获取其他八大隐式对象
getPage()方法 返回page隐式对象
getRequest()方法 返回request隐式对象
getResponse()方法 返回response隐式对象
getServletConfig()方法 返回config隐式对象
getServletContext()方法 返回application隐式对象
getSession()方法 返回session隐式对象
getException()方法 返回exception隐式对象
getOut()方法 返回out隐式对象
page和pageContext有什么区别
1.page代表当前Servlet实例,不同用户访问的是同一个page对象,所以page对象不适合保存不同用户自己独立的数据,会有线程安全问题。
2.pageContext在请求到达页面时创建,在请求离开页面时销毁,因此每个用户访问的是自己的那个pageContext,彼此之间是独立的,适合用来保存用户自己独立的信息。
2)本身也是一个域对象, 也可以作为入口对象来操作其他三大作用域中的数据
- 作为域对象使用
setAttribute(String name, Object obj);
getAttribute(String name);
removeAttribute(String name);
getAttributeNames();
生命周期: 访问JSP页面开始时创建, 访问JSP页面结束时销毁
作用范围: 当前JSP页面
主要功能: 在当前JSP页面中共享数据
四大作用域的生命周期按从长到短的顺序排列:ServletContext > Session > request > pageContext
- 作为入口对象, 可以操作其他三大作用域
setAttribute(String name, Object value,int scope)
getAttribute(String name,int scope)
removeAttribute(String name,int scope)
其中pageContext中代表域的常量,即上述方法中的int参数scope。
PageContext.APPLICATION_SCOPE
PageContext.SESSION_SCOPE
PageContext.REQUEST_SCOPE
PageContext.PAGE_SCOPE
- 额外提供了:findAttribute(String name); //按照由小到大的顺序在四大作用域中搜寻指定名称的属性, 如果找到就返回, 如果都找不到就返回一个null
四大作用域排序:page< request< session< application(ServletContext)
3) 提供了便捷方法实现请求转发和包含
请求转发
<%
pageContext.forward("/index.jsp");
%>
请求包含
<%
pageContext.include("/index.jsp");
%>