JSP

Jsp:用java语言+html语言 开发动态资源的技术

Jsp继承自servlet

Servlet技术: 开发动态资源。是一个java类,擅长写java代码。
jsp技术: 开发动态资源。用于通过java代码输出html代码。

 

Jsp的特点

1)jsp的运行必须交给tomcat服务器。
        tomcat的work目录: tomcat服务器存放jsp运行时的临时文件
2)jsp页面既可以写html代码,也可以写java代码。(html页面不能写java代码 ,而jsp页面可以写java代码)
        可以把jsp页面当做html页面在tomcat中访问


目录

Jsp的执行过程:

Jsp语法

Jsp的三大指令

include指令:

page指令:

taglib指令:

*Jsp的内置对象*

9大内置对象:

域对象详解:

EL表达式

Jsp标签

内置标签

JSTL标签

自定义标签


Jsp的执行过程

  1. 翻译)访问hello.jsp页面,tomcat扫描到jsp文件,在%tomcat%/work把jsp文件翻译成java源文件     (hello.jsp -> _hello_jsp.java
  2. 编译)tomcat服务器把java源文件编译成class字节码文件     (_hello_jsp.java -> _hello_jsp.class
  3. (实例化)tomcat服务器构造_hello_jsp类对象
  4. (调用service)tomcat服务器调用_hello_jsp类里面方法,返回内容显示到浏览器。

注意:

第一次访问jsp:->1.->2.->3.->4.

第n次访问jsp:->4.

jsp文件被修改了或jsp的临时文件被删除了,要重新走(1)翻译和(2)编译的过程


jsp翻译成的java文件:

public final class _hello_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent {

HttpJspBase类:

public abstract class org.apache.jasper.runtime.HttpJspBase extends javax.servlet.http.HttpServlet implements javax.servlet.jsp.HttpJspPage {

所以Jsp就是一个servlet程序
servlet的技术可以用在jsp程序中,jsp的技术并不是全部适用于servlet程序!


Servlet的生命周期:

  1. 构造方法(第1次访问)
  2. init方法(第1次访问)
  3. service方法
  4. destroy方法 

Jsp的生命周期:1.翻译->2.编译->3456.同Servlet

  1. 翻译: jsp->java文件
  2. 编译: java文件->class文件(servlet程序)
  3. 构造方法(第1次访问)
  4. init方法(第1次访问):_jspInit()
  5. service方法:_jspService()
  6. destroy方法:_jspDestroy()

 


 

Jsp语法

jsp页面中会被翻译成servlet程序:html语句会被翻译成  out.write("html语句");  jsp语句会被翻译成对应的java语句


Jsp表达式

语法:<%= 变量或表达式 %>
作用:向浏览器输出变量的值或表达式计算的结果
原理:表达式被翻译成  out.print(变量);  通过该方法向浏览器写出内容。表达式后面不需要带分号来结束


Jsp的脚本

语法:<% java代码  %>
作用:执行java代码
原理:把脚本中java代码原封不动拷贝到_jspService方法中执行。不能声明方法,因为代码在_jspService方法中


Jsp的声明
语法:<%!  声明变量或方法  %>
作用:声明jsp的变量或方法
原理:变量翻译成成员变量,方法翻译成成员方法。不能声明servlet程序已经存在的方法,如:_jspInit()···


Jsp的注释
语法: <%!-- jsp注释 --%>
注意:html的注释依然会被翻译和执行。而jsp的注释不能被翻译和执行。


Jsp的三大指令


include指令:

作用:在当前页面用于包含其他页面
语法:<%@ include file="路径/包含的页面.jsp" %>
原理:把被包含的页面(分页.jsp)的内容翻译到包含页面(主页.jsp)中,合并成翻译成一 个java源文件,再编译运行!这种包含叫静态包含(源码包含,先合并在翻译

 

如果使用静态包含,被包含页面中不需要出现全局的html标签了(如html、head、 body),只要body里的内容就行


page指令:

作用: 告诉tomcat服务器如何翻译jsp文件
<%@ page

language="java"         告诉服务器使用什么动态语言来翻译jsp文件,目前jsp只支持java

import="包名1 , 包名2"         导入java包,多个包之间用逗号分割

jsp执行过程中编码转换:jsp文件-①-> 保存到硬盘-②-> 翻译java源文件-③-> 编译class字节码-④-> 发送到浏览器-⑤-> 浏览器解码

pageEncoding="utf-8"          告诉服务器使用什么编码翻译jsp文件 ②③

contentType="text/html; charset=utf-8"         服务器发送浏览器的数据类型和内容编码。 ④   省略不写值会参考pageEncoding

注意:在eclipse工具中,①也会参考pageEncoding,所以只需要设置pageEncoding即可解决中文乱码问题

 

异常错误相关:

errorPage="目录/名称.jsp"         指定当前jsp页面的错误处理的跳转页面   比web.xml中的全局配置优先

isErrorPage="true"         指定当前页面是否为错误处理页面   false则没有exception内置对象

 

<!-- 在web.xml中 配置全局错误处理页面 -->
  <error-page>
  	<error-code>500</error-code>
  	<location>/路径/500错误跳转页面.jsp/html</location>
  </error-page>
  <error-page>
  	<error-code>404</error-code>
  	<location>/路径/404错误跳转页面.jsp/html</location>
  </error-page>

buffer="8kb"         jsp页面的缓存区大小

session="true"         是否开启session功能   false则没有session内置对象

isELIgnored="false"         是否忽略EL表达式

%>
 


taglib指令:

作用:在jsp页面导入标签库

<%@taglib uri="tld文件的<uri>" prefix="标签库简称<short-name>"%>         tld文件:声明标签


*Jsp的内置对象*

在jsp开发中,会频繁使用到一些对象。所以Sun公司设计Jsp时,在jsp页面加载完毕之后就会自动帮开发者创建好这些对象,而开发者只需要直接使用这些对象调用方法即可,这些创建好的对象就叫内置对象

9大内置对象:

内置对象名

类型

* request 

HttpServletRequest

response

HttpServletResponse

config

ServletConfig

* application 

ServletContext

* session 

HttpSession

exception

Throwable

page

Object(this)

out

JspWriter

* pageContext 

PageContext

 

Out对象:

out对象类型,JspWriter类的实例,相当于带缓存的PrintWriter
PrintWriter: response发送实体内容

wrier(内容):直接向浏览器写出内容。

JspWriter:

writer(内容):向jsp缓冲区写出内容。   缓冲区默认大小8kb

当满足以下条件之一,缓冲区内容写出到PrintWriter

  1. 缓冲区满了
  2. 刷新缓存区   out.flash();
  3. 关闭缓存区   buffer="0kb"
  4. 执行完毕jsp页面

pageContext对象:

pageContext对象的类型是PageContext,叫jsp的上下文对象

1)可以获取其他八个内置对象

例:jap翻译成的java文件
public class _hello_jsp {
	public void _jspService(request,response){
	//Service中创建所有的内置对象
	HttpSession session =···;
	ServletConfig config = ···;
	······
	//把其他8个内置对象封装到PageContext对象中
	PageContext pageContext  = 封装其他8个对象;
	//调用自定义方法,传入pageContext对象
	自定义方法(pageContext);
	}

	public void 自定义方法(PageContext pageContext){
	//从PageContext对象中获取其他的内置对象,就可以在自定义方法中使用Service中的内置对象
	JspWriter out = pageContext.getOut();
	HttpServletRequest rquest = pageContext.getRequest();
	······
		}
	}

 

在自定义标签的时候,PageContext对象会频繁使用到!

2)本身是一个域对象

因为pageContext可以获取其他对象,所以可以往其他的域对象中存取数据

保存数据

  1. 默认情况下,保存到page域。      pageContext.setAttribute("name");
  2. 可以向四个域对象保存数据。      pageContext.setAttribute("name",域范围常量)

获取数据

 

  1. 默认情况下,从page域获取。      pageContext.getAttribute("name")
  2. 可以从四个域中获取数据。      pageContext.getAttribute("name",域范围常量)
  3. 自动在四个域中搜索数据。      pageContext.findAttribute("name");   搜索顺序:page域 > request域 > session域 > context域(application域)

 

域范围常量:

PageContext.PAGE_SCOPE

PageContext.REQUEST_SCOPE

PageContext.SESSION_SCOPE

PageContext.APPLICATION_SCOPE

注意:从哪个域保存的数据就必须从哪个域取出


域对象详解

四个域对象:

pageContext           page域

request                    request域

session                   session域

application              context域

域对象作用:保存数据 和 获取数据 ,用于数据共享

域对象方法

setAttribute("name",Object)      保存数据

getAttribute("name")      获取数据

removeAttribute("name")      清除数据

域对象作用范围

page域:只能在当前jsp页面中使用

request域:只能在同一个请求链中使用(转发)

session域:只能在同一个会话(session对象)中使用。私有的

context域:只能在同一个web应用中使用。全局的


开发jsp的原则: 尽量在jsp页面中少写甚至不写java代码。EL表达式替换掉  jsp表达式,用jsp标签替换掉 jsp脚本


EL表达式

EL表达式作用: 向浏览器输出域对象中的变量值或表达式计算的结果

EL语法:${ 变量或表达式 }

1)输出基本数据类型变量

1.1 从四个域自动获取:${变量}

等价于:pageContext.findAttribute("变量");

1.2 指定域获取:${域范围.变量}     域范围:pageScoep / requestScope / sessionScope / applicationScope

等价于:pageContext.getAttribute("变量",域范围常量)

2)输出javabean对象的属性

先将对象放入域对象,然后使用 ${对象.xx属性}   相当于调用getXX()方法。  注意:XX并不是属性名,而是getXX()方法中get后的字母

等价于: <%=((对象类型)pageContext.findAttribute("对象")).getXX()%>

3)输出集合对象(List 和 Map)

先将集合放入域对象,然后使用 ${list集合[参数].xx属性} / ${map集合['键'].xx属性}   中括号相当于调用get(参数)方法

等价于:((集合类型)pageContext.findAttribute("集合")).get(参数/键)

4)EL表达式计算

算术表达式,比较运算,逻辑运算,判空

${name==null || name==""} / ${empty name }

 


Jsp标签

Jsp标签作用:在jsp页面执行java代码

Jsp标签分类

  1. 内置标签(动作标签): 不需要在jsp页面导入标签
  2. JSTL标签: 需要在jsp页面中导入标签
  3. 自定义标签 : 开发者自行定义,需要在jsp页面导入标签

- 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

内置标签

 

转发标签: <jsp:forward/>

参数标签: <jsp:pararm/>

<jsp:forward page="/路径">
    	<jsp:param value="jacky" name="name"/>
    	<jsp:param value="123456" name="password"/>
    </jsp:forward>

等价于:request.getRequestDispatcher("/路径?name=jacky&password=123456").forward(request,response);

包含标签: <jsp:include/>

 

<jsp:include page="/包含的页面.jsp">
   		<jsp:param value="lucy" name="name"/>
   	</jsp:include>

原理: 包含与被包含的页面先各自翻译成java源文件,然后再运行时合并在一起。动态包含可以传递参数先翻译再合并

- 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

JSTL标签

(java standard tag libarary / java标准标签库)

核心标签库(c标签库)

国际化标签(fmt标签库)

EL函数库(fn函数库)

xml标签库(x标签库)

sql标签库(sql标签库)

JSTL标签使用步骤

  1. 项目中导入jstl支持的jar包   (标签背后隐藏使用的java代码)
  2. jsp页面中使用taglib指令导入标签库<%@taglib uri="tld文件的<uri>"prefix="标签库简称<short-name>"%>
  3. 在jsp中使用标签

核心标签库的主要标签:   注意:有些参数中不能用el表达式

 

 

 

保存数据:c:set   保存数据到域中,默认保存到page域

<c:set var="name" value="jacky" scope="page"></c:set>

获取数据:c:out    控制value值输出。value值为null时使用default。escapeXml(默认true):对value值进行转义,当作文本内容输出

<c:out value="${name}" default="默认值" escapeXml="false"></c:out>

单条件判断:c:if

<c:if test="判断">true输出,false不输出</c:if>

多条件判断:choose标签+when标签+otherwirse标签

<c:choose>

<c:when test="判断1">if true 输出</c:when>

<c:when test="判断2">else if true 输出</c:when>

判断3、4、5······

<c:otherwise>else 输出</c:otherwise>

</c:choose>

循环数据:c:forEachc:forTokens

-------------------forEach标签:遍历数据 ------------------

<c:forEach begin="开始元素(默认0)" end="结束元素(默认遍历所有元素)" step="步数(默认1)" items="${要遍历的数据(集合)}"var="元素名称"varStatus="count属性(从1开始)">
普通遍历方法:(序号:${count属性.count} - 值:${元素名称} )<br/>

map集合遍历方法:(map键:${元素名称.key} - map值1:${元素名称.value.属性1 } - map值2:${元素名称.value.属性2 })<br/>
</c:forEach>

--------------forToken标签: 循环特殊字符串 ---------------

<%
String str = "java-php-c++-.net";
pageContext.setAttribute("str",str);
%>

<c:forTokens items="${str}" delims="-" var="s">
将字符串切割后循环输出:${s }<br/>
</c:forTokens>

重定向:c:redirect

<c:redirect url="http://www.baidu.com"></c:redirect>

- 3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

自定义标签

自定义标签开发步骤

1)编写一个普通的java类,实现SimpleTag接口继承SimpleTagSupport类覆盖doTag方法。叫标签处理器类

 

SimpleTagSupport中的代码:
	//传入pageContext对象
	private JspContext context;
	public void setJspContext(JspContext pc) {
	this.context = pc;
	}
	//提供getJspContext()方法获取pageContext
doTag方法内容:
	//得到pageContext对象
	PageContext pageContext = (PageContext)this.getJspContext();
	//编写实现标签功能的java代码······

 

2)在web项目的WEB-INF目录下建立对应的.tld文件,这个tld叫标签库的声明文件。(参考核心标签库的tld文件)

 

<!-- 标签库声明 -->
	<!-- 标签库的版本 -->
	<tlib-version>1.1</tlib-version>
	<!-- 标签库简称 -->
	<short-name> 标签库简称 </short-name>
	<!--  *tld文件的唯一标记*  -->
	<uri> tld文件的uri </uri>
<!-- 一个标签的声明 -->
	<tag>
	<!-- 标签名称 -->
	<name>标签名</name>
	<!-- *标签处理器类的全名* -->
	<tag-class>包名.类名</tag-class>
	<!-- 输出标签体内容格式 -->
	<body-content>JSP/scriptless/empty/tagdependent</body-content>
			<!-- 标签一个属性的声明 -->
    		<attribute>
    			<!-- 属性名称 -->
    			<name>属性名</name>
    			<!-- 是否必填 -->
    			<required>true</required>
    			<!-- 是否支持EL表达式 -->
    			<rtexprvalue>false</rtexprvalue>
   		 </attribute>
	</tag>

 

     输出标签体内容格式:

JSP 只能在传统标签中使用的。可以写和执行jsp的java代码。

scriptless:  标签体不可以写jsp的java代码

empty: 必须是空标签。

tagdependent :标签体内容可以写jsp的java代码,但不会执行

3)在jsp页面的头部导入自定义标签库

<%@taglib uri=" tld文件的uri " prefix=" 标签简称<short-name> "%>

4)在jsp中使用自定义标签

<标签库简称:标签名> </标签库简称:标签名>

 

 

自定义标签的执行过程:

例:http://localhost:8080/webroot/myTag.jsp 如何访问到自定义标签?
前提: tomcat服务器启动时,加载到每个web应用,加载每个web应用的WEB-INF目录下的所有文件!!!例如。web.xml、tld文件

 

    1. 访问mytag.jsp资源
    2. tomcat服务器把jsp文件翻译成java源文件->编译class->构造类对象->调用_jspService()方法
    3. 检查jsp文件的taglib指令,是否存在<uri>为指定名称的tld文件。如果没有,则报错
    4. 读到指定的.tld文件
    5. 读到<标签库简称:标签名> 到.tld文件中查询<tag>标签中是否存在<name>为标签名的标签
    6. 找到对应的<tag>标签,则读到<tag-class>内容
    7. 得到标签处理器类的全名包名.类名
构造myTag对象,然后调用myTag里面的方法

 

自定义标签处理器类的生命周期:

     SimpleTag接口: 调用顺序

void setJspContext(JspContext pc)      --设置pageContext对象,传入pageContext,通过getJspCotext()方法得到pageContext对象。(一定会调用

void setParent(JspTag parent)       --设置父标签对象,传入父标签对象,通过getParent()方法得到父标签对象。如果没有父标签,则不调用此方法。

void setXXX(值)     --设置属性值。

void setJspBody(JspFragment jspBody)      --设置标签体内容。标签体内容封装到JspFragment对象 中,然后传入JspFragment对象。通过getJspBody()方法得到标签体内容。如果没有标签体内容,则不调用此方法

void doTag()      --执行标签时调用的方法。(一定会调用

自定义标签的作用:

  1. 控制标签体内容是否输出  invoke方法
    //1.1 得到标签体内容
    	JspFragment jspBody = this.getJspBody();
    //1.2 执行invoke方法输出(不执行则不输出): 把标签体内容输出到指定的Writer对象中,writer为null就是默认往浏览器输出
    	jspBody.invoke(null);
    /*等价于:
    	JspWriter out = this.getJspContext().getOut();
    	jspBody.invoke(out);
    */
  2. 控制标签外余下内容是否输出         标签后余下内容默认自动输出,抛出skipPageExcepion异常则不输出
  3. 控制标签体内容重复输出         执行多次jspBody.invoke()方法
  4. 改变标签体内容
    //4.1 创建StringWriter临时容器
    	StringWriter sw = new StringWriter();
    //4.2 把标签体拷贝到临时容器
    	jspBody.invoke(sw);
    //4.3 从临时容器中得到标签体内容
    	String content = sw.toString();
    //4.4 改变内容
    	content = content.toLowerCase();
    //4.5 把改变的内容输出到浏览器。   不能使用jspBody.invoke(null)方式输出,因为jsbBody没有改变过
    	this.getJspContext().getOut().write(content);
  5. 标签的属性         tld文件中描术标签的属性标签处理器中添加每个属性对应的setter方法。就能在其中使用标签的属性值 
    //1.声明属性的成员变量
    	private Integer num;
    //2.关键点: 必须提供公开的setter方法,用于给属性赋值
    	public void setNum(Integer num) {
    		this.num = num;
    	}

==================================================================================

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值