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之外)