JSTL标签库
1.什么是JSTL
JSTL是apache对EL表达式的拓展(也就是说JSTL依赖EL),JSTL是标签语言!JSTL标签使用以来非常方便,
它与JSP动作标签一样,只不过它不是JSP内置标签,需要我们自己导入jar包,以及指定标签库
1.jstl的概述:
*apache的东西,依赖el
*需要导入jar包和标签库
*四大库
>core:核心库,重点
>fmt:格式化:日期、数字
>sql:过时
>xml:过时
2.导入标签库
*jar包中
*在jsp页面中:<%@taglib prefix="前缀" uri="路径" %>
---------------------
core-->c标签!
1.out和set
*<c:out value="aaa"/>
*<c:out value="${aaa}"/>
*<c:out value="${aaa}" default="xxx"/>
*<% request.setAttributr("a","<script>alert('hello');</script>")%>
<c:out value="${a}" default="xxx" escapeXml="false" /> 默认escapeXml为true
<c:out>:输出
>value:可以是字符串常量,也可以是el表达式
>default:当腰输出的内容为null时,会输出default指定的值
>escapeXml:默认为true,表示转义!
<c:set>:设置(创建域的属性)
>var:变量名
>value:变量值,可以是el表达式
>scope:域,默认为page,可选值:page/request/session/application
2.remove
*<remove>:删除域变量
>var:变量名
>scope:如果不给出scope,表示删除所有域中的该名称的变量,如果指定了域,只删除该域中的变量
3.url
*value:指定一个路径!它会在路径前面自动添加项目名
<><c:url value="/index.jsp"/>,它会输出/day13_1/index.jsp
*子标签:<c:param>,用来给url后面添加参数,例如:
<c:url value="/index.jsp">
<c:param name="username" value="张三"/> <!-- 它可以为参数做URL编码 -->
</c:url>
结果为:/day13_1/index.jsp?username=?%ED%2C%F
*var:指定变量名,一旦添加了这个属性,那么url标签就不会再输出到页面,而是将生成的URL保存到指定的域中
*scope 它与var一起使用,用来保存url
4.if
对应java中的if语句
*<c:if test="布尔类型">...</c:if>当test为真时,执行标签体语句
5.choose
它对应java中的if/else else if/.... /else
*例如:
<c:choose>
<c:when test="">...</c:when>
<c:when test="">...</c:when>
...
<c:otherwise>...</c:otherwise>
</c:choose>
等同于
if(...){
}else if(...){
}else if(...){
}...
else{...}
6.forEach
它用来循环遍历数组、集合!
它还可以用来计数方式来循环!
计数方式:
for(int i=0;i<10;i++){
...
}
<c:forEach var="i" begin="1" end="10">
${i}
</c:forEach>
for(int i=0;i<10;i+=2){
...
}
属性:
*var:循环变量
*begin:设置循环变量从几开始
*end:设置循环变量到几结束
*step:设置步长,等用于java中的i++或者i+=2.step默认为1
----------
用来输出数组和集合(注意items中有没有空格)
<c:forEach items="${strs}" var="str">
${str}<br/>
</c:forEach>
等同于
forEach(String str:strs){
...
}
属性:
*item:指定要遍历谁,它可以是一个数组或者一个集合
*var:把数组或集合中的每个元素赋值个var指定的变量
--------------------
循环状态
可以使用varStatus来创建循环状态变量!
循环状态变量有如下属性:
*count:循环元素的个数
*index:循环元素的下标
*first:是否为第一个元素
*last:是否为最后一个元素
*current:当前元素
<c:forEach items="${list }" var="ele" varStatus="vs">
${vs.index} ${vs.count} ${vs.first} ${vs.last} ${vs.current} <br/>
</c:forEach>
============================
fmt库
它是格式化库
<fmt:formatDate value="" pattern=""/>
属性:
value:指定一个Date类型的变量
pattern:用来指定输出的模板!例如:yyyy-MM-dd HH:mm:ss
<fmt:formatDate value="${request.date}" pattern="yyyy-MM-dd HH:mm:ss"/>
----------------
<fmt:formatNumber value="${num1}" pattern="0.00" />
保留两位小数,允许四舍五入,小数点后前后位不够补0
<fmt:formatNumber value="${requestScope.num1}" pattern="#.##" />
保留两位小数,允许四舍五入,小数点后前后位不够不补位
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page </title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <% /** request.setAttribute("code","<script>alert('hello');</script>"); */ %> <c:set var="code" value="<script>alert('hello');</script>" scope="session" /> <!-- 这样不安全 ${code } --> <c:out value="${code} "/><br/> <!-- 输出,jstl默认转义敏感字 ,escapeXml属性默认为true--> <c:url value="/AServlet" /><br/> ${pageContext.request.contextPath }/AServlet<br/> <a href="<c:url value='/index.jsp'/>">点击这里回到主页</a> <br/> <c:url value="/index.jsp"> <c:param name="username" value="guozhen" /> <c:param name="password" value="果真"/> </c:url> <hr/> <c:if test="${empty param.name }"> 您没有给出名为name的参数 </c:if> <hr/> <c:choose> <c:when test="${empty param.name }"> 您没有给出名为name的参数 </c:when> <c:otherwise> 谁让你给出名为name的参数的?${param.name } </c:otherwise> </c:choose> <br/> <c:forEach var="i" begin="1" end="10" step="2"> ${i }<br/> </c:forEach> <% String[] strs={"one","two"}; request.setAttribute("strs",strs); %> <c:forEach items="${requestScope.strs }" var="str"> ${str }<br/> </c:forEach> <hr/> <br/> <% ArrayList<String> list=new ArrayList<String>(); list.add("一"); list.add("二"); list.add("三"); request.setAttribute("list", list); %> <c:forEach items="${list }" var="ele" varStatus="vs"> ${ele } ${vs.index } ${vs.count } ${vs.first } ${vs.last } ${vs.current } <br/> </c:forEach> <hr><br/> <% Date date=new Date(); request.setAttribute("date", date); %> <fmt:formatDate value="${requestScope.date }" pattern="yyyy-MM-dd HH:mm:ss"/> <hr><br/> <% request.setAttribute("num1",3.1415926); %> <fmt:formatNumber value="${requestScope.num1 }" pattern="00.000"/><!-- 能四舍五入,长度和模板一致,若前面不足补0,后面也是 --><br/> <fmt:formatNumber value="${requestScope.num1 }" pattern="##.###" /><!-- 和前面的基本一样,区别在于不补位 --> </body> </html>
自定义标签
1.步骤
*标签处理类(标签也是一个对象,那么久需要先有类!)
*tld文件,它是一个xml
*页面中使用<%@taglib%>来指定tld文件的位置
2。标签处理类
SimpleTag接口
*void doTag():每次执行标签时都会调用这个方法:
*JspTag getParent(): (非生命周期方法)
*void setParent(JspTag)
*void setJspBody(JspFragment):设置标签体
*void setJspContext(JspContext) 设置jsp上下文对象,他儿子是PageContext
其中doTag()会在其他三个方法之后被tomcat调用
tld文件一般都放到WEB-INF之下,这样保证客户端访问不到!
<tag>
<name>myTag1</name>指定当前标签的名称
<tag-class>cn.tag.myTag1</tag-class>
<body-content>empty</body-content>
</tag>
3.导标签库
<%@ taglib prefix="it" uri="/WEB-INF/tlds/itcast-tag.tld" %>其实就是为标签库指定tld文件的位置
继承SimpleTagSupport
继承SimpleTagSupport要比实现SimpleTag接口,方便太多了,它自己保存了body和pageContext等对象,重写了必要方法。现在你只需要重写doTag方法即可。
public class HelloTag extends SimpleTagSupport {
public void doTag() throws JspException,IOException{
this.getJspContext().getOut().write("<p>Hello SimpleTag!</p>")
}
}
进阶:
*empty:无标签体
*JSP:jsp2.0已经不再支持这个类型了!表示标签体内容:可以是java脚本,可以是标签可以是el表达式
*scriptless:只能是EL表达式,也可以是其他的标签
*tagdependent:标签体内容不会被执行而是直接赋值tag处理类
不执行标签下面的内容的标签:就是执行完这个标签内容之后,不再执行后面的页面的内容
*如果希望在执行了自定义标签后,不再执行JSP页面下面的东西,那么就需要在doTag()中使用skipPageException,tomcat得到本异常后,它会跳过本页面的其他内容
标签属性
步骤:
1.给你的标签处理类添加属性!
为标签处理类添加属性,属性至少有一个setXxx方法,在doTag中使用属性
2.在tld文件中对属性进行部署(配置)
<attribute>
<name>test</name>
<required>true</required> <!-- 必须的 -->
<rtexprvalue>true</rtexprvalue> <!-- runtime expretion 这个属性赋值可以是el表达式吗? -->
</attribute>
package cn.itcast.tag; import java.io.IOException; import javax.servlet.jsp.JspContext; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.JspFragment; import javax.servlet.jsp.tagext.JspTag; import javax.servlet.jsp.tagext.SimpleTag; public class MyTag1 implements SimpleTag{ private PageContext pageContext; private JspFragment body; /** * 所有的setXXX方法都会在doTag()方法之前被tomcat调用 * 所以在doTag()中就可以使用tomcat传递过来的对象了 */ public void doTag() throws JspException, IOException { pageContext.getOut().print("hello tag"); } public JspTag getParent() { // TODO Auto-generated method stub return null; } public void setJspBody(JspFragment body) { this.body=body; } public void setJspContext(JspContext pageContext) { this.pageContext=(PageContext) pageContext; } public void setParent(JspTag arg0) { // TODO Auto-generated method stub } } package cn.itcast.tag; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; /** * SimpleTagSupport它实现了SimpleTag接口。 * 它已经把所有的tomcat传递的数据都保存起来了!而且还提供了get方法供子类调用 * @author Administrator * */ public class MyTag2 extends SimpleTagSupport{ @Override public void doTag() throws JspException, IOException { this.getJspContext().getOut().print("再hello 一次tag!"); } } package cn.itcast.tag; import java.io.IOException; import java.io.Writer; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; public class MyTag3 extends SimpleTagSupport{ @Override public void doTag() throws JspException, IOException { Writer out=this.getJspContext().getOut();//获取当前jsp页面的输出流 out.write("*******************<br/>"); this.getJspBody().invoke(out);//执行标签体内容,把结果写到指定的流中,即页面上 out.write("<br/>*******************"); } } package cn.itcast.tag; import java.io.IOException; import java.io.Writer; import javax.servlet.jsp.JspException; import javax.servlet.jsp.SkipPageException; import javax.servlet.jsp.tagext.SimpleTagSupport; public class MyTag4 extends SimpleTagSupport{ @Override public void doTag() throws JspException, IOException { Writer out=this.getJspContext().getOut(); out.write("只能执行我!后面的而不执行"); throw new SkipPageException(); } } package cn.itcast.tag; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; /** * 有属性的标签 * @author Administrator * */ public class MyTag5 extends SimpleTagSupport{ private boolean test; @Override public void doTag() throws JspException, IOException { /** * 执行标签体 */ if(test){ this.getJspBody().invoke(null);//如果传递的输出流为null,表示使用的就是当前页面的out } } /** * 这个方法会由tomcat来调用,并且在doTag()之前 * @param test */ public void setTest(boolean test) { this.test = test; } } <?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.0</tlib-version> <short-name>itcast</short-name> <uri>http://www.itcast.cn/tags/1.0</uri> <tag> <name>mtTag1</name> <tag-class>cn.itcast.tag.MyTag1</tag-class> <body-content>empty</body-content> </tag> <tag> <name>mtTag2</name> <tag-class>cn.itcast.tag.MyTag2</tag-class> <body-content>empty</body-content> </tag> <tag> <name>mtTag3</name> <tag-class>cn.itcast.tag.MyTag3</tag-class> <body-content>scriptless</body-content> </tag> <tag> <name>mtTag4</name> <tag-class>cn.itcast.tag.MyTag4</tag-class> <body-content>empty</body-content> </tag> <tag> <name>mtTag5</name> <tag-class>cn.itcast.tag.MyTag5</tag-class> <body-content>scriptless</body-content> <attribute> <name>test</name> <required>true</required> <!-- 必须的 --> <rtexprvalue>true</rtexprvalue> <!-- runtime expretion 这个属性赋值可以是el表达式吗? --> </attribute> </tag> </taglib> <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="it" uri="/WEB-INF/tlds/itcast-tag.tld" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <it:mtTag5 test="${empty param.xxx }"> <h1><it:mtTag4 /></h1> </it:mtTag5> <h1><it:mtTag1></it:mtTag1></h1> <h2><it:mtTag2 /></h2><hr> <% request.setAttribute("xxx", "zhangSan"); %> <it:mtTag3 >${xxx }</it:mtTag3><br/> <it:mtTag3>我是张三的大哥</it:mtTag3><br/> <it:mtTag4 /> </body> </html>
====================================
MVC
它不是java独有,所有的B/S结构项目都在使用它!
M--model 模型(自己写代码)
V-- View 视图(jsp)
C-- Controller控制器(Servlet)
===================================
JavaWeb三层框架
web层-->与web相关的内容(Servlet,JSP,Servlet相关的api:request、response。。。)
业务层-->业务对象(Service)
数据层-->操作数据库(DAO Data Access Object)(所有对数据库的操作,不能跳出DAO之外)