JSP
JSP全称是Java Server Pages,它和Servlet技术一样,都是SUN公司定义的一种用于开发动态web页面(资源)的技术。
写JSP虽然就像是在写html,但JSP技术允许在页面中编写java代码,并允许开发人员在页面中获取request,reponse等web开发常用对象,实现与浏览器的交互,所以JSP也是一种动态web资源的开发技术。
JSP最佳实践
不管是JSP还是Servlet,最然都可以用于开发动态web资源,但是由于这2门技术各自的特点,在长期的软件实践中,人们逐渐把Servlet作为web应用中的控制器组件来使用,而把JSP技术作为数据显示模版来使用。
其原因为,程序的数据通常要美化后再输出:
让JSP即用java代码产生动态数据,又做美化会导致页面难以维护。
让servlet即产生数据,又在里面嵌套html代码美化数据,同样也会导致程序可读性差,难以维护。
因此最好的办法就是根据这两门技术的特点,让它们各自负责各自的,servlet只负责响应请求产生数据,并把数据通过转发技术带给JSP,数据的显示JSP来做。
JSP运行原理和九大隐式对象
- 每个JSP页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个java程序)去处理。JSP引擎先将JSP翻译成一个_jspServlet(实际上也是一个servlet),然后按照servlet的调用方式进行调用。
- 由于JSP第一次访问时会翻译成servlet,所以第一次访问通常会比较慢,但第二次访问,JSP引擎如果发现JSP没有变化,就不再翻译,而是直接调用,所以程序的执行效率不会受到影响。
- JSP引擎在调用JSP对应的_jspServlet时,会传递或创建9个与web开发相关的对象供_jspServlet使用。JSP技术的设计者为便于开发人员在编写JSP页面时获得这些WEB对象的引用,特意定义了9个对应的变量,开发人员在JSP页面中通过这些变量就可以快速获得这9大对象的引用。
- 9大隐式对象(类型)
- request(HttpServletRequest)
- reponse(HttpServletResponse)
- session(HttpSession)
- application(ServletContext)
- config(ServletConfig)
- exception(Exception)
- page(Object)
- out(JspWriter)
- pageContext(PageContext)
Out隐式对象
- out隐式对象用于向客户端发送文本数据。
- out对象是通过调用pageContext对象的getOut方法返回的,其作用和用法与ServletResponse.getWriter方法返回的PrintWriter对象非常相似。
- JSP页面中的out隐式对象的类型为JspWriter,JspWriter相当于一种带缓存功能的PrintWriter,设置JSP页面的page指令的buffer属性可以调整它的缓存大小,甚至关闭它的缓存。
- 只有向out对象中写入了内容,且满足如下任何一个条件时,out对象才去调用ServletResponse.getWriter方法,并通过该方法返回的PrintWriter对象将out对象的缓冲区中的内容真正写入到Servlet引擎提供的缓冲区中:
- 设置page指令的buffer属性关闭了out 对象的缓存功能
- out对象的缓冲区已满
- 整个JSP页面结束
- out隐式对象的注意事项
- 同时使用out和response.getWriter()输出数据。
- 示例:
- out.write("aaaa"); //后输出
- response.getWriter().write("bbbb"); //先输出
- 显示结果为:bbbb aaaaa
- 在JSP页面中建议使用out.write()输出,而不采用response.getWrite().write()输出。
Out隐式对象的工作原理图
pageContext隐式对象
- pageContext对象是JSP技术中最重要的一个对象,它代表JSP页面的运行环境。
- pageContext封装了对其它8大隐式对象的引用。
- pageContext是一个域对象,可以用来保存数据。
- pageContext还封装了WEB开发中经常涉及到的一些常用操作,例如引入和跳转其他资源,检索其它域对象中的属性等。
- 通过pageContext获得其他对象(主要用于自定义标签开发技术)
- getException(): 返回 exception 隐式对象
- getPage(): 返回 page 隐式对象
- getRequest(): 返回 request 隐式对象
- getResponse(): 返回 response 隐式对象
- getServletConfig(): 返回 config 隐式对象
- getServletContext(): 返回application隐式对象
- getSession(): 返回session隐式对象
- getOut(): 返回out隐式对象
- pageContext作为域对象
- pageContext对象的方法
- public void setAttribute(String name,Object value)
- public Object getAttribute(String name)
- public void removeAttribute(String name)
- pageContext对象中还封装了访问其它域的方法
- public Object getAttribute(String name, int Scope)
- public void setAttribute(String name,Object value, int scope)
- public void removeAttribute(String name, int scope)
- 代表各个域的常量
- PageContext.APPLICATION_SCOPE
- PageContext.SESSION_SCOPE
- PageContext.REQUEST_SCOPE
- PageContext.PAGE_SCOPE
- findAttribute方法
- 重点,查找各个域中的属性
- 按page request session application的顺序自动挨个查找,如果找到则返回对应属性值,如果没有找到,则返回Null
- pageContext对象的方法
- 引入和跳转到其他资源
- PageContext类中定义了一个forward方法和两个include方法来分别简化和替代RequestDispatcher.forward方法和include方法。
- 方法接收的资源如果以“/”开头,“/”代表当前web应用。
String data = (String)pageContext.getAttribute("data",PageContext.REQUEST_SCOPE);
out.write(data);
|
JSP语法
JSP模版元素
JSP页面中的HTML内容称之为JSP模版元素。
JSP模版元素定义了网页的基本骨架,即定义了页面的结构和外观。
JSP表达式(expression)
JSP脚本表达式用于将程序数据输出到客户端。
语法:<%= 变量或表达式 %>
举例:当前时间:<%= new java.util.Date() %>
JSP引擎在翻译脚本表达式时,会将程序数据转成字符串,然后在相应位置用out.print(...) 将数据输给客户端。
JSP脚本表达式中的变量或表示式后面不能有分号(;)
JSP脚本片段(scriptlet)
1 JSP脚本片段用于在JSP页面中编写多行java代码。
语法:<%
多行代码
%>
注意:JSP脚本片断中只能出现java代码,不能出现其他模版元素,JSP引擎在翻译JSP页面时,会将JSP脚本片断中的java代码原封不动的放到servlet的_jspService方法中。
JSP脚本片断中的java代码必须严格遵循java语法,例如,每执行语句后面必须用分号(;)结束。
2 在一个JSP页面中可以有多个脚本片断,在两个或多个脚本片断之间可以嵌入文本、HTML标记和其他JSP元素。
举例:
<%
int x = 10;
out.println(x);
%>
<p>这是JSP页面文本</p>
<%
int y = 20;
out.println(x);
%>
多个脚本片断中的代码可以相互访问,犹如将所有的代码放在一对<%%>之中的情况。
如: out.println(x);
3 单个脚本片断中的javav语句可以是不完整的,但是多个脚本片断组合后的结果必须是完整的java语句,
例如:
<%
for(int i = 1; i<5; i++)
{
%>
<H1>www.t315.org</H1>
<%
}
%>
JSP声明
JSP页面中编写的所有代码,默认会翻译到servlet的service方法中,而Jsp声明中的java代码被翻译到_jspService方法的外面。
语法:<%!
java代码
%>
所以,JSP声明可用于定义JSP页面转换成的Servlet程序的静态代码块、成员变量和方法。
多个静态代码块、变量和函数可以定义在一个JSP声明中,也可以分别单独定义在多个JSP声明中。
JSP隐式对象的作用范围仅限于Servlet的_jspService方法,所以在JSP声明中不能使用这些隐式对象。
JSP注释
JSP注释的格式:<%— —注释信息— —%>
JSP引擎在将JSP页面翻译成Servlet程序时,忽略JSP页面中被注释的内容。
JSP指令(directive)
JSP指令是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分。在JSP2.0规范中共定义了三个指令:
page指令:
include指令:
taglib指令:
JSP标签
JSP标签也称之为Jsp Action(JSP动作)元素,它用于在JSP页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成JSP页面难以维护。
JSP常用标签:
<jsp:include>标签
- <jsp:include>标签用于把另外一个资源的输出内容插入进当前JSP页面的输出内容之中,这种在JSP页面执行时的引入方式称为动态引入。
语法:
<jsp:include page="relativeURL" | <%= expression %>" flush="true|false" />
- page属性用于指定被引入资源的相对路径,它也可以通过执行一个表达式来获得。
- flush属性指定在插入其他资源的输出内容时,是否先将当前JSP页面的已输出的内容刷新到客户端。
<jsp:include>与include指令的比较
- <jsp:include>标签是动态引入,<jsp:include>标签涉及的2个JSP页面会被翻译成2个servlet,这2个servlet的内容在执行时进行合并。
- include指令是静态引入,涉及到的2个JSP页面会被翻译成一个servlet,其内容是在源文件级别进行合并。
- 不管是<jsp:include>标签,还是include指令,它们都会把两个JSP页面内容合并输出,所以这两个页面不要出现重复的HTML全局架构标签,否则输出给客户端的内容将会是一个格式混乱的HTML文档。
<jsp:forward>标签
- <jsp:forward>标签用于把请求转发给另外一个资源。
语法:
<jsp:forward page="relativeURL" | <%=expression%>" />
示例:
<jsp:forward page="/servlet/IndexServlet">将JSP页面中跳转到servlet首页
- page属性用于指定请求转发到的资源的相对路径,它也可以通过执行一个表达式来获得。
<jsp:param>标签
- 当使用<jsp:include>和<jsp:forward>标签引入或将请求转发给其它资源时,可以使用<jsp:param>标签向这个资源传递参数。
语法:
<jsp:include|forward page="relativeURL" | <%= expression%>">
<jsp:param name="paramerterName" value="parameterValue" | <%= expression%>" />
</jsp:include>
- <jsp:param>标签的name属性用于指定参数名,value属性用于指定参数值。
- 在<jsp:include>和<jsp:forward>标签中可以使用多个<jsp:param>标签来传递多个参数。