JSP基础
来源:互联网 发布:python canny边缘检测 编辑:程序博客网 时间:2024/06/13 04:09
JSP(Java Server Pages,java服务器页面),其根本是一个简化的Servlet设计,一种动态网页技术标准。它实现了Html语法中的java扩展(以 <%, %>形式)。
JSP与Servlet一样,是在服务器端执行的。通常返回给客户端的就是一个HTML文本,因此客户端只要有浏览器就能浏览。Java Servlet是JSP的技术基础,而且大型的Web应用程序的开发需要Java Servlet和JSP配合才能完成。
JSP是以JAVA语言作为脚本语言的。
一个JSP页面可以被分为以下几部份:
- 静态数据
- JSP指令
- JSP脚本元素和变量
- JSP动作
- 用户自定义标签
一、JSP的执行过程和生命周期
(一)JSP的执行过程
- 1、浏览器发送一个请求给服务器,寻找某JSP页面。
- 2、tomcat服务器载入JSP文件,然后将jsp转化为servlet(存放在%tomcat%/work)。这种转化只是简单地将所有模板文本(html)改用println()语句输出,并且将所有的JSP元素转化成Java代码。(转化jsp文件名字的格式:在文件名前面加上一个”“符号,并且将.符号替换成符号,例如,hellow.jsp 变为 _hellow_jsp.java)
- 3、tomcat将该servlet翻译和编译成可执行类(class文件),tomcat服务器将会构造该servlet类。
4、然后服务器调用该类的方法,并将输出在HTTP响应中上交给Web服务器。Web服务器以静态HTML网页的形式将HTTP响应返回到的浏览器中。
一般,tomcat服务器会检查JSP文件对应的servlet是否已经存在,并且检查JSP文件的修改日期是否早于servlet。如果JSP文件的修改日期早于对应的servlet,那么容器就可以确定JSP文件没有被修改过并且servlet有效。否则,重新翻译和编译。当第一次访问该jsp页面是,需要经过翻译、编译、构造和调用过程。当第二次访问则只会直接的调用方法显示内容即可。
(二)JSP生命周期
JSP生命周期就是从创建到销毁的整个过程,类似于servlet生命周期,区别在于JSP生命周期还包括将JSP文件转化为servlet。
- 编译阶段:解析JSP文件,将JSP文件转为servlet,编译servlet。
- 初始化阶段:加载与JSP对应的servlet类,创建其实例,调用初始化方法
- 执行阶段:调用与JSP对应的servlet实例的服务方法
- 销毁阶段:调用与JSP对应的servlet实例的销毁方法,然后销毁servlet实例
二、JSP转化Servlet
在JSP执行的过程中,需要将JSP转化成servlet的。那么是如何转化的呢?
我们可以先编写一个简单的jsp文件,来看看它转化成servlet成什么样子的。
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>demo</title></head><body> <%-- 这里表示循环输出3个标题--%> <% for(int i=0;i<3;i++){ %> <h3>标题<%=i %></h3> <% } %></body></html>
假如,jsp是直接在tomcat服务器运行的,可以在tomcat目录的\work\Catalina\localhost\appsupport\org\apache\找到对应的的servlet文件。假如在eclipse上的tomcat服务其运行的,可以在workspace目录的.metadata.plugins\org.eclipse.wst.server.core\tmp1\work\Catalina\localhost\(项目名称)\org\apache\找到对应的servlet文件。
我们可以查看,该jsp文件转化成的servlet的部分代码。
我们可以看到,有类似Servlet的_jspInit()、_jspService()和_jspDestroy()方法。(在jsp的生命周期中调用)
以及,调用out对象write方法,直接输出静态内容。
以及,直接将JSP的java代码直接放在了_jspService()方法当中。
public final class demo_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent, org.apache.jasper.runtime.JspSourceImports { //与生命周期相关的方法 public void _jspInit() { } public void _jspDestroy() { } public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) throws java.io.IOException, javax.servlet.ServletException {//.... //JSP的内置对象 final javax.servlet.jsp.PageContext pageContext; javax.servlet.http.HttpSession session = null; final javax.servlet.ServletContext application; final javax.servlet.ServletConfig config; javax.servlet.jsp.JspWriter out = null; final java.lang.Object page = this; javax.servlet.jsp.JspWriter _jspx_out = null; javax.servlet.jsp.PageContext _jspx_page_context = null; try { //... //调用out对象write方法,直接输出静态内容。 out.write("\r\n"); out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n"); out.write("<html>\r\n"); out.write("<head>\r\n"); out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\r\n"); out.write("<title>demo</title>\r\n"); out.write("</head>\r\n"); out.write("<body>\r\n"); out.write("\t"); out.write('\r'); out.write('\n'); out.write(' '); //直接将JSP的java代码直接放在了_jspService()方法当中。 for(int i=0;i<3;i++){ out.write("\r\n"); out.write("\t\t<h3>标题"); out.print(i ); out.write("</h3>\r\n"); out.write("\t"); } out.write("\r\n"); out.write("</body>\r\n"); out.write("</html>"); } catch (java.lang.Throwable t) { //... } finally { //... } } //...}
三、JSP语法
(一)JSP的模板,即是静态数据(HTML)
静态数据在输入文件中的内容和输出给HTTP响应的内容完全一致。JSP页面中的html代码就是JSP的模板。
(二)JSP脚本
JSP脚本可以包含任意量的Java语句、变量(局部变量)、方法或表达式。在JSP转化成servlet过程中,把脚本中java代码原封不动地拷贝到该servlet的_jspService方法方法中执行。
语法:<% 这里编写java代码 %>
例如:
<!--JSP脚本,在 <%%>里面编写java代码--><% //在页面输出当前时间 SimpleDateFormat sdf = new SimpleDateFormat(); String curDate = sdf.format(new Date()); out.write(curDate);%>
(三)JSP表达式
JSP表达式中包含的脚本语言(java)表达式,先被转化成String,通过out.print()方法输出到表达式出现的地方。
语法:<%=这里编写变量或表达式%>
例如:
<!--jsp表达式--><% //声明一个变量 String name = "lee";%><!--向页面输出该变量--><%=name %>
(五)JSP声明
一个声明语句可以声明一个或多个变量(全局变量)、方法,不能重复定义同名的变量和方法。
语法:<%! 这里编写变量或方法%>
例如:
<!--JSP声明--><% //声明一个变量(全局变量) String name = "lee"; //声明一个方法 public void method(){ //方法体 }%>
(六)JSP注释
注释一段代码。在jsp页面的中,可以写html注释和jsp注释。但是html注释会作为一个html内容来输出,但是jsp注释则不会。
语法:<%-- 这里编写注释--%>
例如:
<!--JSP注释--><%-- <jsp:forward page=""></jsp:forward>--%>
(七)例子
<%@ page language="java" contentType="text/html; charset=utf-8" import="java.io.IOException" pageEncoding="utf-8" buffer="1kb" %><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>title</title></head><body> <%-- 在JSP声明中,声明一个全局变量,和一个方法 --%> <%! String str1 = "lee"; //输出指定内容 public void printContent(String content, PageContext pageContext) throws IOException{ //获取out对象 JspWriter out = pageContext.getOut(); //调用out对象输出内容 out.write(content); } %> <%-- 在JSP脚本中, 声明一个局部变量,和调用自定义方法 --%> <% String str2 = "wang"; printContent(str2,pageContext); %> <%-- 在JSP表达式中,输出全局变量 --%> <%= str1%></body></html>
四、JSP指令
JSP指令用来设置整个JSP页面相关的属性,它并不直接产生任何可见的输出,而只是告诉引擎如何处理其余JSP页面。
语法: <%@ 指令名称 属性=“值”%>
(一)include指令
JSP页面可以通过include指令来包含其他文件。例如JSP文件、HTML文件或文本文件。被包含文件是被直接添加该JSP页面中,随着JSP页面编译执行,叫做静态包含。被包含文件一般不需要全局的html内容,例如<html>、<body>、<head>
等标签。
include指令的语法为: <%@ include file="被包含页面的url" %>
(二)page指令
Page指令为容器提供JSP页面的属性说明。一个JSP页面可以有多个page指令。
语法:
<%@ page attribute="value" %>
page指令的重要属性:
errorPage可以指定当前JSP页面发生异常时需要转向的错误处理页面。例如
<%@ page errorPage="uri" %>
也可以在web.xml文件配置错误处理页面。web.xml配置和errorPage都有的话,以errorPage优先。
<error-page> <!--当发生500错误时,跳转到指定错误处理页面--> <error-code>500</error-code> <location>uri</location></error-page><error-page> <!--当发生404错误时,跳转到指定错误处理页面--> <error-code>404</error-code> <location>uri</location></error-page>
(三)taglib指令
引入一个自定义标签集合,包括库路径、自定义标签。
语法:<%@ taglib uri="uri" prefix="前缀" %>
uri属性为标签库的uri,prefix属性指定标签库的前缀。
五、JSP内置对象
JSP内置对象是JSP容器为每个页面提供的Java对象,开发者可以直接使用它们而不用显式声明。
在jsp页面加载完毕之后,服务器就会自动帮开发者创建好这些对象,开发者就可以直接调用这些对象。这些服务器创建好的对象叫做内置对象。
我们主要来了解一下out和pageContext对象:
(一)out对象
out对象是JspWriter的实例,是向客户端输出内容常用的对象。
1、我们可以看看的JSP转化的Servlet
JSP页面,使用了out对象输出:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>title</title></head><body> <% out.write("hellow world!"); %></body></html>
部分Servlet代码:
public final class hellow_jsp extends HttpJspBase implements JspSourceDependent,JspSourceImports {//... public void _jspService(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException { //... try { response.setContentType("text/html; charset=utf-8"); //... //1、获取pageContext对象实例 pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true); //2、从pageContext对象的方法中获取out对象 out = pageContext.getOut(); //3、使用out对象输出静态内容 out.write("\r\n"); out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n"); out.write("<html>\r\n"); out.write("<head>\r\n"); out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\r\n"); out.write("<title>Insert title here</title>\r\n"); out.write("</head>\r\n"); out.write("<body>\r\n"); out.write("\t"); //4、使用out对象输出指定内容 out.write("hellow world!"); out.write("\r\n"); out.write("</body>\r\n"); out.write("</html>"); } catch (java.lang.Throwable t) { //... } finally { //... }}
2、与buffer缓冲区的关系
当以下情况下,out才会输出
1)缓冲区满了
可以调用out对象的getRemaining()来查看缓冲区的剩余空间大小,调用getBufferSize()来查看缓冲区的大小。
2)刷新缓冲区
可以调用out对象的flush()来刷新缓冲区。
3)关闭缓冲区
可以通过page指令来设置buffer缓冲区的大小为0kb,关闭缓冲区。
<%@ page buffer="0kb" %>
4)执行完jsp页面
我们可以编写一个JSP页面来看看
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" buffer="8kb" %><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>title</title></head><body> <% //调用out对象输出 out.write("this is the out Object."); //调用response对象来输出 response.getWriter().write("this is the response Object."); %></body></html>
我们可以看到的结果是用response对象输出的内容,在out对象输出的内容的前面。但是我们却是先调用out对象的,事情上,是因为out对象输出的内容会先输出在缓冲区(满足条件才会从缓冲区中输出),而response对象是直接输出在浏览器中。因此,才会出现先输出response对象输出的内容,等到整个JSP页面执行完后,才会从缓冲区中输出out对象输出的内容。
其它条件,这里就不多做解释。
(二)pageContext对象
pageContext对象是PageContext类的实例,该对象储存了另外八个内置对象的引用,因此可以通过该对象来获取其他的对象的实例。该对象也包含了传递给JSP页面的指令信息和数据。
1、获取其他的内置对象
pageContext对象存储了另外八个内置对象的引用。因此自定义的方法可以通过传递PageContext对象,来获取其他的内置对象。调用方法如下:
abstract Exception getException()//The current value of the exception object (an Exception).abstract Object getPage()//The current value of the page object (In a Servlet environment, this is an instance of javax.servlet.Servlet).abstract ServletRequest getRequest()//The current value of the request object (a ServletRequest).abstract ServletResponse getResponse()//The current value of the response object (a ServletResponse).abstract ServletConfig getServletConfig()//The ServletConfig instance.abstract ServletContext getServletContext()//The ServletContext instance.abstract HttpSession getSession()//The current value of the session object (an HttpSession).abstract JspWriter getOut()//The current value of the out object (a JspWriter).
2、往不同域对象存取数据
pageContext对象可以作为域对象使用,而且可以往不同的域对象中存取数据。因此该对象定义了不同域的范围(对应着四大域对象):
1、APPLICATION_SCOPE(application范围)
2、PAGE_SCOPE(page范围)
3、REQUEST_SCOPE(scope范围)
3、SESSION_SCOPE(session范围)
当没有指定某域,则默认page域。
//获取数据public abstract Object getAttribute(String name)//指定范围的public abstract Object getAttribute(String name, int scope)//存储数据public abstract void setAttribute(String name, Object value)//指定范围的public abstract void setAttribute(String name, Object value, int scope)//移出数据public abstract void removeAttribute(String name)//指定范围的public abstract void removeAttribute(String name, int scope)//pageContext对象还有个特殊方法,可以从不同的域中查找数据,顺序为page域-request域-session域-application域public abstract Object findAttribute(String name)
(三)四大域对象(引用,权侵删)
(一)ServletContext
1、生命周期:当Web应用被加载进容器时创建代表整个web应用的ServletContext对象,当服务器关闭或Web应用被移除时,ServletContext对象跟着销毁。
2、作用范围:整个Web应用。
3、作用:
- a)在不同Servlet 之间转发
- this.getServletContext().getRequestDispatcher(“/servlet/Demo10Servlet”).forward(request, response);
方法执行结束,service就会返回到服务器,再有服务器去调用目标servlet,其中request会重新创建,并将之前的request的数据拷贝进去。
- this.getServletContext().getRequestDispatcher(“/servlet/Demo10Servlet”).forward(request, response);
- b)读取资源文件。
- 由于相对路径默认相对的是java虚拟机启动的目录,所以我们直接写相对路径将会是相对于tomcat/bin目录,所以是拿不到资源的。为了解决这个问题ServletContext提供了:
this.getServletContext().getRealPath(“/1.properties”),给进一个资源的虚拟路径,将会返回该资源在当前环境下的真实路径。
this.getServletContext().getResourceAsStream(“/1.properties”),给一个资源的虚拟路径返回到该资源真实路径的流。- 当在非servlet下获取资源文件时,就没有ServletContext对象用了,此时只能用类加载器classLoader.getResourceAsStream(“../../1.properties”),此方法利用类加载器直接将资源加载到内存中,有更新延迟的问题。
classLoader.getResource(“../1.properties”).getPath(),直接返回资源的真实路径,没有更新延迟的问题。
- 当在非servlet下获取资源文件时,就没有ServletContext对象用了,此时只能用类加载器classLoader.getResourceAsStream(“../../1.properties”),此方法利用类加载器直接将资源加载到内存中,有更新延迟的问题。
- 由于相对路径默认相对的是java虚拟机启动的目录,所以我们直接写相对路径将会是相对于tomcat/bin目录,所以是拿不到资源的。为了解决这个问题ServletContext提供了:
(二)Request 域
- 1、生命周期:在service 方法调用前由服务器创建,传入service方法。整个请求结束,request生命结束。
- 2、作用范围:整个请求链(请求转发也存在)。
- 3、作用:在整个请求链中共享数据。
(三)Session 域
HttpSession 在服务器中,为浏览器创建独一无二的内存空间,在其中保存会话相关的信息。
- 1、生命周期:在第一次调用 request.getSession() 方法时,服务器会检查是否已经有对应的session,如果没有就在内存中创建一个session并返回。当一段时间内session没有被使用(默认为30分钟),则服务器会销毁该session。如果服务器非正常关闭(强行关闭),没有到期的session也会跟着销毁。如果调用session提供的invalidate(),可以立即销毁session。
- 2、作用范围:一次会话。
(四)PageContext 域
- 1、生命周期:当对JSP的请求时开始,当响应结束时销毁。
- 2、作用范围:整个JSP页面,是四大作用域中最小的一个。
- 3、作用:
- (1)获取其它八大隐式对象,可以认为是一个入口对象。
- (2)获取其所有域中的数据
- (3)跳转到其他资源,其身上提供了forward和include方法,简化重定向和转发的操作
六、EL表达式
E L(Expression Language)表达式是为了使JSP写起来更加简单,提供了在 JSP 中简化表达式的方法。EL强制要求使用域对象保存的变量或者结果。因此,在开发过程中会尽量不在JSP页面编写JAVA代码。语法:${变量或者表达式}
(一)强制从域对象获取变量或结果
//部分JSP页面的代码<% //定义一个变量,将该变量存储在page域当中 String name = "lee"; pageContext.setAttribute("name",name);%>//实际上,下面代码等同于pageContext.findAttribute("name");//意味着,EL表达式会在各个域对象当中寻找这个变量或结果${name}//因为,EL表达式是从域对象中获取数据的,因此可以指定范围的获取//范围有:pageScope页面范围、requestScope请求范围、sessionScope会话范围、applicationScope应用程序范围//例如:${pageScope.name}
(二)输出基本数据类型
//部分JSP页面的代码<% //这里有个Student的javabean类,封装着一些数据 ArrayList<Student> list = new ArrayList<>(); Student xiaoming = new Student(); xiaoming.setName("xiaoming"); list.add(xiaoming); //存储到域对象当中 pageContext.setAttribute("list",list); %>//输出list集合中的第一个对象的属性${list[0].name}//EL表达式不能进行遍历,需要借助JSP的JSTL标签
(三)EL表达式的操作符运算
//部分JSP页面的代码<%--1)算数表达式2)比较运算3)逻辑运算4)判空 null或空字符串--%>//1、${10+8}//2、${1>2}//3、${true||true}<%String one = null;String two = "";pageContext.setAttribute("one",one);pageContext.setAttribute("two",two);%>//4、${empty one}${empty two}
七、JSP标签
(一)动作标签
JSP动作是一系列可以调用内建于网络服务器中的功能的XML标签。利用JSP动作可以动态地插入文件、重用JavaBean组件、把用户重定向到另外的页面、为Java插件生成HTML代码。
语法:<jsp:name attribute="value" />
动作元素基本上都是预定义的函数,JSP规范定义了一系列的标准动作,它用JSP作为前缀,主要用到标准动作元素如下:
一些动作标签的介绍:
1、jsp:include
include动作标签用来动态包含静态和动态的文件。与通过taglib指令的静态包含不一样的是,动态包含,包含与被包含的jsp页面各自翻译成java源文件,再运行时合并在一起(动态包含)。动态包含可以传参,静态包含不能传参数。
语法:<jsp:include page="url" />
属性:
例如:
<!-- 将/otherJsp.jsp页面包含本JSP页面当中,设置为刷新被包含页面刷新缓冲区 --><jsp:include page="/otherJsp.jsp" flush="true" /><!-- 包含页面,并传递参数给被包含页面,被包含页面可以通过request对象来获取该参数 --><jsp:include page="/otherJsp.jsp" flush="true" > <jsp:param name="name1" value="value1"></jsp:param></jsp:include>
2、jsp:forward
将请求转发到另外一个页面。
语法:<jsp:forward page="URL" />
例如:
<!-- 转发到otherJsp.jsp页面 --><jsp:forward page="/otherJsp.jsp"/><!-- 带有参数的转发 --><jsp:forward page="otherJsp.jsp"> <jsp:param name="name1" value="value1"/></jsp:forward>
3、jsp:param
定义一个指定的参数
语法:<jsp:param name="name1" value="value1"/>
4、jsp:useBean
寻找或者实例化一个JavaBean到当前JSP页面。
语法:<jsp:useBean id="name" class="package+class" />
5、jsp:setProperty
用来设置已经实例化的Bean对象的属性。
语法:<jsp:setProperty name="name1" property="property1" />
6、jsp:getProperty
jsp:getProperty动作提取指定Bean属性的值。
语法:<jsp:getProperty name="name" property="property" />
例如
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Insert title here</title></head><body> <!-- 实例化JavaBeamDemo类,名称为demo1,并且设置属性name --> <jsp:useBean id="demo1" class="tag.JavaBeanDemo"> <jsp:setProperty name="demo1" property="name" vlaue="lee"/> </jsp:useBean> <!-- 设置demo1实例的id属性 --> <jsp:setProperty name="demo1" property="id" value="1"/> <!-- 获取demo1实例的属性 --> <jsp:getProperty name="demo1" property="name"/></body></html>//javaBean代码package tag;/** * Description: * 一个javabean实例 * 1、提供无参数的构造方法 * 2、类中属性都必须私有化 * 3、该类提供公开的getter和setter方法 * 4、boolean类型的getter方法的名称为isXXX() * * @author lee * */public class JavaBeanDemo { private int id; private String name; private String introduce; /** * Description: * 默认的构造方法 * * */ public void JavaBeanDemo(){} public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getIntroduce() { return introduce; } public void setIntroduce(String introduce) { this.introduce = introduce; }}
7、jsp:element、jsp:attribute、jsp:body动作标签
动态定义XML元素。
<!-- xml标签 --> <jsp:element name="first"> <!-- xml标签的属性 --> <jsp:attribute name="id">1</jsp:attribute> <!-- xml标签体内容 --> <jsp:body>lee</jsp:body> </jsp:element>
(二)JSTL标签
JSTL(java standard tag libarary java,标准标签库)是一个JSP标签集合,它封装了JSP应用的通用核心功能。JSTL分为以下几种:
- 核心标签库(c标签库)
- 国际化标签库(fmt标签库)
- EL函数库(fn标签库)
- xml标签库(x标签库)
- sql标签库(sql标签库)
1、使用JSTL标签步骤
(1)导入jstl支持的jar包
可以在这个网站中找到JSTL的jar包,然后在整个web项目中buildpath导入jar包。
(2)使用taglib指令导入指定的JSTL库
在JSP页面的前面输入taglib指令,例如:
//uri和prefix属性分别为JSTL标签库的tld配置文件中的<uri>,<short-name><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>//例如,c标签库的tld文件(部分代码)<?xml version="1.0" encoding="UTF-8" ?><taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1"> <!-- c标签库声明 --> <description>JSTL 1.1 core library</description> <display-name>JSTL core</display-name> <tlib-version>1.1</tlib-version> <!-- prefix属性的值 --> <short-name>c</short-name> <!-- uri --> <uri>http://java.sun.com/jsp/jstl/core</uri> <!-- 一个的标签声明 --> <tag> <description></description> <name>catch</name> <tag-class> org.apache.taglibs.standard.tag.common.core.CatchTag </tag-class> <body-content>JSP</body-content> <attribute> <description></description> <name>var</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag></taglib>
这些标签库的tld文件都在jstl的jar包里的META-INF文件夹中,当需要导入某个标签库时,知道寻找对应的tld文件获取其uri和short-name,就可以用tagib指令导入JSP页面使用了。
(3)使用标签
2、一些常用的核心标签库
(1)<c:out>
该标签用于输出一段文本到浏览器中。
有以下属性:
(2)<c:set>
该标签用于把某一个对象存在指定的域范围内,或者设置Web域中的java.util.Map类型的属性对象或JavaBean类型的属性对象的属性。
有以下属性:
(3)<c:if>
该标签可以构造简单的“if-then”结构的条件表达式
(4)<c:choose>
、<c:when>
、<c:otherwise>
标签用于指定多个条件选择的组合边界,它必须与和标签一起使用。使用,和三个标签,可以构造类似 “if-else if-else” 的复杂条件判断结构。
(5)<c:forEach>
该标签用于对一个集合对象中的元素进行循环迭代操作,或者按指定的次数重复迭代执行标签体中的内容。
关于varStatus属性的说明:
varStatus=“status”事实上定义了一个status名的对象作为varStatus的绑定值。该绑定值也就是status封装了当前遍历的状态。例如:
1、status.index可以看其遍历的index值
2、status.count表示当前遍历的个数
3、status.last和status.first都为boolean值,分别表示是否遍历到最后一个和最后一个元素
(6)<c:forTokens>
对带有相同符合格式内容进行分割输出。
(7)<c:redirect>
该标签用于将当前的访问请求转发或重定向到其他资源,它可以根据url属性所指定的地址,执行类似这个JSP标准标签的功能,将访问请求转发到其他资源;或执行response.sendRedirect()方法的功能,将访问请求重定向到其他资源。
3、常用标签库的使用实例
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Insert title here</title></head><body> <!-- 保存数据到指定域中 --> <c:set var="name1" value="value1" scope="request" ></c:set> <!-- 输出内容到浏览器中 --> <c:out value="${name1}" default="not find"></c:out><br> <!-- 当test属性的值为true时,就执行该标签体的内容 --> <c:if test="${true}"> 条件成立! </c:if><br> <!-- 复杂判断 --> <c:set var="test" value="77" scope="request"></c:set> <c:choose> <c:when test="${test<40}">条件1成立</c:when> <c:when test="${test>70}">条件2成立</c:when> <c:otherwise>否则</c:otherwise> </c:choose><br><br> <!-- 循环 --> <% //先定义了数组,并将它保存到pageContext域当中 String[] strs = {"1","2","3","4"}; pageContext.setAttribute("strs", strs); %> <c:forEach begin="0" end="3" step="1" items="${strs}" var="var" varStatus="status"> ${status.count} : ${var}<br> </c:forEach><br><br> <!-- 特殊循环 --> <c:forTokens items="1.2.3.4.5.6" delims="." var="item" varStatus="status"> ${status.index} : ${item}<br> </c:forTokens> <!-- 重定向 --> <%-- <c:redirect uri="/demo.jsp"> </c:redirect> --%></body></html>
(三)自定义标签
自定义标签是用户定义的JSP标签。
1、自定义标签的使用步骤
(1)创建一个java类,继承SimpleTagSupport类,重写doTag()方法,在该方法里面实现自定义的业务逻辑。
package tag;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.JspWriter;import javax.servlet.jsp.tagext.JspFragment;import javax.servlet.jsp.tagext.SimpleTagSupport;/** * Description: * 自定义标签类, * * @author lee * */public class TagDemo1 extends SimpleTagSupport{ /** * 重写toTag()方法,执行自定义内容 * * 输出标签内容。 * */ @Override public void doTag() throws JspException,IOException{ //获取标签体内容 JspFragment jspBody = this.getJspBody(); //获取out对象 JspWriter out = this.getJspContext().getOut(); //执行invoke方法,把表前提内容执行到指定的writer对象当中 //当该方法参数为null,则默认输出到浏览器当中 jspBody.invoke(out); }}
(2)编写标签库描述符tld文件。tld文件包含着该标签库的声明和标签的声明。并将该tld文件放在WEB-INF目录中。
该tld文件如下:
<!-- tld文件如何写,可以参考JSTL库的其他标签库的tld文件 --><?xml version="1.0" encoding="UTF-8" ?><taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1"> <!-- 标签库的声明 --> <!-- 标签库版本 --> <tlib-version>1.1</tlib-version> <!-- 标签库的名字和标签库的uri 当我们在JSP页面导入该标签库的时, taglib指令中的uri和prefix就是对应着下面的uri和short-name --> <short-name>custom</short-name> <uri>http://custom.cn</uri> <!-- 一个标签的声明 --> <tag> <!-- 自定义标签名 --> <name>show</name> <!-- 标签处理器类的包名+类名 --> <tag-class>tag.TagDemo1</tag-class> <!-- 标签体内容: 1、JSP:表示支持jsp标本表达式取值,即<%= %>。只能在传统标签用,简单 标签不支持! 2、empty:没有标签体 3、scriptless:标签体可以包含 el 表达式和 JSP 动作元素,但不能包含 JSP 的脚本元素tagdependent:表示标签体交由标签本身去解析处理。若指定 tagdependent,在标签体中的所有代码都会原封不动的交给标签处理器,而不是将执行结果传递给标签处理器 --> <body-content>JSP</body-content> </tag> <!-- 一个带有属性的标签的声明 --> <tag> <name>up</name> <tag-class>tag.TagDemo</tag-class> <!-- 标签属性声明 --> <attribute> <name>id</name> </attribute> </tag><!-- --> </taglib>
标签中描述属性的元素有:
(3)在JSP页面使用taglib指令导入该标签库,使用自定义标签。
例如导入上面声明的自定义标签库:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><!-- 导入自定义标签库 --><%@ taglib uri="http://custom.cn" prefix="custom" %><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>自定义标签的使用</title></head><body> <!-- 使用自定义标签 --> <custom:show> 标签体内容 </custom:show></body></html>
2、自定义标签案例
这里实现一个类似JSTL核心标签库里的<c:choose><c:when><c:otherwise>
功能的自定义标签。
三个自定义标签的类的:
(1)choose标签类
package tag;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.SimpleTagSupport;/** * Descr的iption: * 一个标签处理类,该标签处理类实现了类似JSTL核心标签库 * <c:choose>标签处理方法。 * * @author lee * */public class CustomChoose extends SimpleTagSupport{ /** * Description: * test代表着该标签子标签custom:when的test值。 * * */ private boolean test; /** * Description: * 返回test的值 * * @return test代表着该标签子标签custom:when的test值 * */ public boolean getTest(){ return this.test; } /** * Description: * 设置test的值 * * @param test代表着该标签子标签custom:when的test值 * */ public void setTest(boolean test){ this.test = test; } /** * Description: * 重写了SimpleTagSupport类的doTag方法 * 输出了标签体的内容。 * * */ @Override public void doTag() throws JspException, IOException { //调用JspFragment对象的invoke方法,默认想浏览器输出 this.getJspBody().invoke(null); }}
(2)when标签类
package tag;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.JspTag;import javax.servlet.jsp.tagext.SimpleTagSupport;/** * Description: * 一个标签处理类,该标签处理类实现了类似JSTL核心标签库 * <c:when>标签的处理方法 * * @author lee * */public class CustomWhen extends SimpleTagSupport{ /** * Description: * test是when标签的判断条件 * * */ private boolean test; /** * Description: * 设置test的值 * * @param test when标签的判断条件 * */ public void setTest(boolean test){ this.test = test; } /** * Description: * 重写了SimpleTagSupport类的doTag方法 * 获取该标签的属性test的值,为true就输出标签体内容, * 否则不输出 * * */ @Override public void doTag() throws JspException, IOException { //获取父标签choose CustomChoose customChoose = (CustomChoose)this.getParent(); //设置其test值 customChoose.setTest(test); if(test){ this.getJspBody().invoke(null); } }}
(3)otherwise标签类
package tag;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.SimpleTagSupport;import org.eclipse.jdt.internal.compiler.ast.ThrowStatement;/** * Description: * 一个标签处理类,该标签处理类实现了类似JSTL核心标签库的 * <c:otherwise>标签处理方法。 * * @author lee * */public class CustomOtherwise extends SimpleTagSupport{ /** * Description: * 重写了SimpleTagSupport类的doTag方法 * 获取其父标签<custom:choose>的标签体的test值, * test值为false输出其标签体内容,否则不输出 * * */ @Override public void doTag() throws JspException, IOException { //获取其父标签 CustomChoose customChoose = (CustomChoose)this.getParent(); //获取其test值 boolean test = customChoose.getTest(); if(!test){ this.getJspBody().invoke(null); } }}
(4)tld文件声明
<?xml version="1.0" encoding="UTF-8" ?><taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1"> <tlib-version>1.1</tlib-version> <short-name>custom</short-name> <uri>http://custom.cn</uri> <tag> <name>choose</name> <tag-class>tag.CustomChoose</tag-class> <body-content>scriptless</body-content> </tag> <tag> <name>when</name> <tag-class>tag.CustomWhen</tag-class> <body-content>scriptless</body-content> <attribute> <name>test</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> <tag> <name>otherwise</name> <tag-class>tag.CustomOtherwise</tag-class> <body-content>scriptless</body-content> </tag></taglib>
(5)使用标签
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><%@ taglib uri="http://custom.cn" prefix="custom" %><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Insert title here</title></head><body> <custom:choose> <custom:when test="true">条件1成立</custom:when> <custom:when test="false">条件2成立</custom:when> <custom:otherwise>条件3成立</custom:otherwise> </custom:choose></body></html>
- jsp基础
- jsp 基础
- JSP基础
- JSP基础
- JSP基础
- Jsp基础
- JSP基础!
- JSP基础
- JSP基础
- JSP基础
- JSP基础
- JSP基础
- JSP基础
- JSP基础
- JSP基础
- JSP基础
- jsp基础
- JSP基础
- printf 函数的输出条件
- 【教程】【PDF】Python2.7教程
- ZOJ-2724-Windows Message Queue
- 05_细节_常量知识小结
- Struts2 resultType返回类型
- JSP基础
- firewalld
- 向通用块层提交一个bio请求
- windows 下文件的高级操作
- 项目实训第四周(1)--问卷填写模块编码之需填写问卷列表与到期问卷列表
- 凸包——Andrew算法
- JS入门的小笔记
- Python学习笔记(4) -- (关键词:杨辉三角、生成器)
- Android内存优化(一)DVM和ART原理初探