JSP

和Servlet技术一样,JSP也是SUN公司定义的一种开发动态web资源的技术,属于JavaEE技术之一。JSP实际上就是Servlet,它们在一起又称JSP/Servlet规范。

Servlet:写Java代码。在做HTML页面的输出时不方便(开发效率很低)

JSP:HTML+Java

1、JSP的原理及生命周期

当某个jsp页面第一次被请求时,会被Tomcat服务器的JSP引擎部分翻译成一个Servlet (☆),然后按照servlet的调用方式进行调用,过程如下:

当一个jsp页面被翻译成Servlet后,后面的过程,包括生命周期都和Servlet是类似的。所以说JSP就是Servlet,理解了JSP页面中的各个组成部分是如何被翻译成Servlet的,就掌握了JSP。学习JSP的过程中,应时常翻阅JSP对应的Servlet源码。

2、demo1_jsp.java类

上一小节中的demo1.jsp在访问时会被翻译成demo1_jsp.java,该类称为jsp的实现类(关于Tomcat中该类怎么命名不多说)。

demo1_jsp类继承自org.apache.jasper.runtime.HttpJspBase抽象类,该类除了继承HttpServlet类外,还实现了javax.servlet.jsp.HttpJspPage接口,在HttpJspPage接口中声明了一个_jspService()方法,它对应着jsp页面,绕晕了的看下图所示:

demo1.jsp中的几乎各种组成部分都能在demo1_jsp.java的_jspService()方法中找到(☆)。

3、JSP页面的组成部分

一个JSP页面可能会包含如下几个部分:JSP模板元素、Java脚本、JSP指令、JSP标签等等,这些部分都会被翻译到生成的Servlet中。

JSP模板元素即JSP页面中的HTML内容,翻译时直接放在out.write()方法中输出。

4、JSP中的JAVA脚本

1)JSP脚本片断:<% Java代码 %>

① JSP脚本片断中只能出现java代码,不能出现其它模板元素。JSP引擎在翻译JSP页面时,会将JSP脚本片断中的Java代码将被原封不动地放到Servlet的_jspService()方法中。

② 在一个JSP页面中可以有多个脚本片断,在两个或多个脚本片断之间可以嵌入文本、HTML标记和其他JSP元素。

③ 单个脚本片断中的Java语句可以是不完整的,但是,多个脚本片断组合后的结果必须是完整的Java语句。

<ul>

<%

for(int i = 0;i < 5; i ++){

%>

<li>第<%=i %></li>

<%

}

%>

</ul>

2)JSP脚本表达式:<%=Java变量或表达式 %>

JSP脚本表达式用于将程序数据输出到客户端。JSP引擎在翻译脚本表达式时,会在相应位置用out.print(…) 将表达式的值输给客户端(变量或表达式后面不能有分号!)。

3)JSP声明:<%! Java代码 %>

① JSP页面中编写的所有代码,默认会翻译到servlet的_jspService() 方法中,而JSP声明中的Java代码被翻译到_jspService方法的外面,所以JSP声明可用于定义JSP页面转换成的Servlet程序的成员变量和方法、静态代码块。

② JSP中九大隐式对象的作用范围仅限于_jspService()方法中,所以在JSP声明中不能使用这些隐式对象。

4)JSP注释:<%-- 注释信息 --%>

JSP引擎在将JSP页面翻译成Servlet程序时,忽略JSP页面中被注释的内容。

正规开发的JSP中应尽量避免出现Java脚本(可用标签封装)。

5、JSP指令

JSP指令是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分。在JSP 2.0规范中共定义了三大指令(page、include、taglib)。

基本语法格式:<%@ 指令 属性=”值” …… %>,如果一个指令有多个属性,这多个属性可以写在一个指令中,也可以分开写。

1)page指令:<%@ page …… %>,有以下常用属性:

① import:告知JSP引擎,导入哪些包。JSP引擎会在生成的Servlet中默认导入javax.servlet.*、javax.servlet.http.*、javax.servlet.jsp.*。如:

<%@ page import="java.util.*,java.sql.*" %> 等价于:

<%@ page import="java.sql.*" %>   <%@ page import="java.util.*" %>

② session:告知引擎是否在_jspService()代码中产生session对象,默认值true。

③ errorPage:告知引擎,如果当前页面出现了异常,应该转发到哪个页面上(“/”代表当前应用)。开发中一般会直接在web.xml中配置全局错误页面(两种写法):

<error-page>

<exception-type>java.lang.Exception</exception-type>

<location>/common/error.jsp</location>

</error-page>

<error-page>

<error-code>404</error-code>

<location>/common/404.jsp</location>

</error-page>

④ isErrorPage:告知引擎是否在_jspService()代码中产生exception对象,默认为false。利用该对象可以捕获页面中的异常,打印异常的详细信息。

⑤ contentType:☆ 告知引擎响应正文的MIME类型,在Servlet中被翻译成response.setContentType(xxx)。

⑥ pageEncoding:☆ 告知引擎,翻译JSP时(从磁盘上读JSP文件)所用的码表,同时还会设置响应正文的MIME类型。pageEncoding的默认值为“ISO-8859-1”。

如:pageEncoding=”UTF-8”相当于告知了引擎用UTF-8读jsp,并在servlet中response.setContentType(“text/html;charset=UTF-8”)

⑦ isELIgnored:告知引擎,是否忽略EL表达式。默认值是false,不忽略。

2)include指令:<%@ include file=”/demo2.jsp” %>,file属性以“/”开头代表当前应用。

3)taglib:<%@ taglib uri=”” prefix=”” %>,导入外部标签库,uri表示外部标签库的uri地址,好比名称空间,prefix相当于一个别名。

6、JSP标签

JSP标签也称之为Jsp Action(JSP动作)元素,它用于在jsp页面中提供业务逻辑功能,避免在jsp页面中直接编写java代码,造成jsp页面难以维护。

1)转发:

<jsp:forward page=”/demo2.jsp”>

<jsp:param name=”from” value=”demo1” />

</jsp:forward>

2)包含:

<jsp:include page=”/demo2.jsp” >

<jsp:param name=”from” value=”demo1” />

</jsp:include>

注意:

① JSP转发和包含标签实际上是对RequestDispatcher的两个方法(forward和include)的改写,且都可以包含<jsp:param>子标签,<jsp:param>中的name-value会以参数的形式加在page后。

② 动态包含和静态包含:除了include指令为静态包含,其余的全是动态包含,它们的区别如下图:

了解了上图后,对静态包含和动态包含的各种区别就很容易理解了,实际开发中,能用静态包含就不用动态包含!

3)JavaBean相关

JSP中提供了三个关于JavaBean组件的内置标签,分别为:

① <jsp:useBean>标签:

语法:<jsp:useBean id="beanName" class="package.class" scope="xxx"/>

属性:id属性用于指定JavaBean实例对象的引用名称和其存储在域范围中的名称,class属性用于指定JavaBean的完整类名,scope的取值为page、request、session、application四个中的一个,默认值为page属性。

作用:在指定的域范围内查找指定的JavaBean对象:

A. 如果存在则直接返回该JavaBean对象的引用。

B. 如果不存在则实例化一个新的JavaBean对象并将它以指定的名称存储到指定的域范围中。

② <jsp:setProperty>标签:

语法1:<jsp:setProperty name="beanName" property=”propertyName” value=”xxx” />

语法2:<jsp:setProperty name=”beanName” property=”propertyName | *” param=”xxx” />

属性:name指定JavaBean实例对象的引用名称,对应id属性;property 指定JavaBean的属性名,指定param时用请求参数设置JavaBean的属性。

③ <jsp:getProperty>标签:

语法:<jsp:getProperty name="beanName" property="propertyName" />

使用案例,注意事项都写在注释中了,直接看即可:

<jsp:useBean id="p" class="org.flyne.domain.Person" scope="page" />

<!-- 一定要注意value的写法:基本类型和字符串类型直接写,其他类型用表达式 -->

<jsp:setProperty name="p" property="name" value="Flyne" />

<jsp:setProperty name="p" property="age" value="24" />

<jsp:setProperty name="p" property="regTime" value="<%=new Date() %>" />

name: <jsp:getProperty name="p" property="name"/><br />

age: <jsp:getProperty name="p" property="age"/><br />

regTime: <jsp:getProperty name="p" property="regTime"/><br />

另外还可以使用请求参数设置JavaBean的属性:

<jsp:setProperty name="p" property="name" param="name"/>

<!-- 当JavaBean的属性名同请求参数名一致时还可以使用通配符 -->

<jsp:setProperty name="p" property="*" />

7、九大隐含对象和四大域对象(☆)

在_jspService方法的开始部分定义了9大对象(exception对象需自行开启,通过isErrorPage指定),在JSP页面中可以直接使用这9大对象。

隐含对象名称

类型

备注

request

javax.servlet.http.HttpServletRequest

response

javax.servlet.http.HttpResponse

session

javax.servlet.http.HttpSession

page指令有开关:session

application

javax.servlet.ServletContext

config

javax.servlet.ServletConfig

page

javax.servlet.http.HttpServlet

当前jsp对应Servlet的实例引用

exception

java.lang.Throwable

page指令有开关:isErrorPage

out

javax.servlet.jsp.JspWriter

相当于带缓存功能的PrintWriter

pageContext

javax.servlet.jsp.PageContext

很重要(☆)

其中pageContext、request、session、application被称为四大域对象,又称属性范围,在实际开发中被用于存放数据(核心是把握其生命周期):

pageContext

页面范围:存储的数据仅本页有效,开发中不用它来存储数据

request

请求范围:一次请求范围内均有效,经常用

session

会话范围:多次请求可共享数据,但不同的客户端不能共享,经常用

application

应用范围:开发中尽量少用,用时要做同步处理

8、PageContext抽象类

1)利用PageContext可以获取其他8个JSP隐含对象。

使用场景:试想有这样一个函数,需要同时用到上述9个隐含对象(有点极端),设置9个参数?错,只需传入pageContext对象,再利用pageContext对象的getRequest()、getResponse()、getSession()、getServletContext()等方法获取其余8个对象。(自定义标签时会用到)

2)操作其他3个域对象中的属性:

① void setAttribute(String name, Object value, int scope)

Object getAttribute(String name, int scope)

void removeAttribute(String name, int scope)

scope参数可取如下常量值:PAGE_SCOPE(页面范围)、REQUEST_SCOPE(请求范围)、SESSION_SCOPE(会话范围)、APPLICATION_SCOPE(应用范围)。

② Object findAttribute(String name) 依次在四个范围中查找指定名称的属性:pageContext --> request --> session --> application。

3)提供转发和包含的简易方法(forward、include)

9、其他问题

1)JSP中的异常处理技巧

① 运行时异常:如1 / 0的运算,此时需查看与JSP文件对应的的Servlet的源码。

② 出现语法错误时,一般IDE会报错,在浏览器中也可以看到错误的详细信息,此时直接定位到JSP文件中查看就行。

2)使用page指令解决JSP中文乱码(☆)

出现中文乱码问题主要还是因为读和写所用的码表不一致造成的:

JSP开发人员可以采用各种字符集编码来编写JSP源文件(如UTF-8、GBK),JSP引擎将JSP源文件翻译成的Servlet源文件默认采用ISO8859-1编码,因此,JSP引擎将JSP源文件翻译成Servlet源文件时,需要进行字符编码转换,通过pageEncoding属性指定,两者需要保持一致。

3)JSP最佳实践

由于Servlet和JSP各自的特点,在长期的软件实践中,人们逐渐把servlet作为web应用中的控制器组件来使用,而把JSP技术作为数据显示模板来使用。

本文来源于:http://www.flyne.org/article/502

jsp机制基础的更多相关文章

  1. JSP Web第四章整理复习 JSP技术基础

    P104 JSP简介 (1)基本概念:jsp技术.jsp.jsp网页组成 JSP技术基础java servlet和整个java体系的Web服务器端开发技术. JSP表示它是用java写的Web服务页面 ...

  2. JavaWeb:JSP技术基础

    JavaWeb:JSP技术 快速开始 介绍 JSP全称Java Server Pages,是一种动态网页开发技术.它使用JSP标签在HTML网页中插入Java代码.标签通常以<%开头以%> ...

  3. JSP/Servlet基础语法

    相关学习资料 http://my.oschina.net/chape/blog/170247 http://docs.oracle.com/cd/E13222_01/wls/docs81/webapp ...

  4. JSP入门基础知识详细版(通俗易懂)

    JSP 第一篇: 概述.原理.周期.指令.行为.内置对象.JavaBean (一) JSP概述以及简单使用 什么是JSP? JSP全名为Java Server Pages,java服务器页面.JSP是 ...

  5. java反射机制(基础版)

    package com.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import ja ...

  6. JSP(基础语法)

    一.JSP简介 JSP全称为Java Server Pages,其根本是一个简化的Servlet设计,它实现了在java当中使用HTML标签.JSP是一种动态网页技术标准也就是javaEE的标准.JS ...

  7. JAVA反射机制基础概念

    反射机制:所谓的反射机制就是java语言在运行时拥有一项自观的能力.通过这种能力可以彻底的了解自身的情况为下一步的动作做准备.下面具体介绍一下java的反射机制.这里你将颠覆原来对java的理解. J ...

  8. Android IPC机制基础

    概要 多进程概念及多进程常见注意事项 IPC基础:Android序列化和Binder 跨进程常见的几种通信方式:Bundle通过Intent传递数据,文件共享,ContentProvider,基于Bi ...

  9. JSP(1)—基础知识

    JSP(1)-基本知识 起源 在很多动态网页中绝大多数网页都是固定不变的只有局部内容需要动态产生和改变,如果使用Servlet程序来输出只有局部内容需要动态改变的网页,其中所有的的静态内容,也需要程序 ...

随机推荐

  1. Java 学习之路 之 泛型方法

    前面介绍了在定义类.接口时可以使用类型形参,在该类的方法定义和 Field 定义.接口的方法定义中,这些类型形参可被当成普通类型来用.在另外一些情况下,我们定义类.接口时没有使用类型形参,但定义方法时 ...

  2. 【USACO 2.2】Subset Sums (DP)

    N (1 <= N <= 39),问有多少种把1到N划分为两个集合的方法使得两个集合的和相等. 如果总和为奇数,那么就是0种划分方案.否则用dp做. dp[i][j]表示前 i 个数划分到 ...

  3. 【USACO 2.1】Ordered Fractions

    /* TASK: frac1 LANG: C++ URL: http://train.usaco.org/usacoprob2?S=frac1&a=dbgwn5v2WLr SOLVE: 直接枚 ...

  4. 使用redis避免客户端频繁提交数据

    避免客户端频繁向服务器提交表单的解决方案 使用redis 在order的model中增加函数 ) { try{ $key = "lock_" . $key; $num = $thi ...

  5. 用 phylomatic 软件生成的进化树

    用 phylomatic 软件生成的进化树 Phylomatic是在线软件,可以利用植物名录,按照APGIII的被子植物科的拓扑结构,生成进化树. 参考 张金龙博士 工作目录 setwd(" ...

  6. Python字符串基础一

    下一篇:Python 序列通用操作介绍 写在前面 下学期开始上计算机网络的课程,现在已经在看相关书籍,希望结合python写出一个网络爬虫程序.利用学习C++后的空余时间来看看Python并在这里总结 ...

  7. 轻松搞定C语言中复杂的声明

    参考资料: [1] <C专家编程> 第3章 分析C语言的声明,p64-66

  8. 【GCJ2008E】日程表 最小割

    Google Code Jam 2008 E 日程表 [题目描述] 热情的选手Sphinny正在看新一年的日程表,并发现已经安排了很多编 程竞赛.她将这一年的每一天都用以下三种方式之一在日程表上打标记 ...

  9. jdbc/ojdbc连oracle的三种方式(转)

    文章转自:http://blog.itpub.net/22664653/viewspace-1383092/ 前言  本文是一篇学习笔记,学习如何通过java jdbc /ojdbc 连接oracle ...

  10. 使用Guava来计算笛卡尔积

    以前做项目的时候计算笛卡尔积的时候,总是使用各种for循环来嵌套,最后往往在Sonar代码检查的时候总是会报警说for循环嵌套过深. 今天才知道Guava原来已经为我们提供了优雅的计算笛卡尔积的方法. ...