目录
JSP三大指令
page 最复杂
include 静态包含
taglib 导入标签库
page
pageEncoding和contentType:
- pageEncoding:它指定当前jsp页面的编码,只要不说谎,就不会有乱码!在服务器要把jsp编译成.java时需要使用pageEncoding!
- contentType:它表示添加一个响应头:Content-Type!等同于response.setContentType(“text/html;charset=utf-8”);
- 如果两个属性只提供一个,那么另一个的默认值为设置那一个。
如果两个属性都没有设置,那么默认为iso
- 如果两个属性只提供一个,那么另一个的默认值为设置那一个。
- import:导包,可以出现多次
- errorPage和isErrorPage
errorPage:当前页面如果抛出异常,那么要转发到哪一个页面,由errorPage来指定
isErrorPage:它指定当前页面是否为处理错误的页面。当该属性为true时,这个页面会设置状态码为500,而且这个页面可以使用9大内置对象中的exception。(不标识该页面时,转发后状态码为200 ok)
<error-page>
<error-code>404</error-code>
<location>/error/errorPage.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error/errorPage.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.RuntimeException</exception-type>
<location>/index.jsp</location>
</error-page>
基本不使用:
autoFlush和buffer
autoFlush:指定jsp的输出流缓冲区满时,是否自动刷新!默认为true,如果为false,那么在缓冲区满时抛出异常
buffer:指定缓冲区大小,默认为8kb,通常不需要修改
isELIgnored:是否忽略el表达式,默认值为false,不忽略,即支持
language:指定当前jsp编译后的语言类型,默认值为java。
info:信息
isThreadSafe:当前的jsp是否支持并发访问
session:当前页面是否支持session,如果为false,那么当前页面就没有session这个内置对象
extends:让jsp生成的servlet去继承该属性指定的类
include
include:静态包含
- 与RequestDispatcher的include()方法的功能相似
<%@include%>
它是在jsp编译成java文件时完成的,他们共同生成一个java(就是一个servlet)文件,然后再生成一个class;- RequestDispatcher的include()是一个方法,包含和被包含的是两个servlet,即两个.class。他们只是把响应的内容在运行时合并了
- 作用:把页面分解了,使用包含的方式组合在一起,这样一个页面中不变的部分,就是一个独立jsp,而我们只需要处理变化的页面。
taglib
taglib:导入标签库
两个属性:
- prefix:指定标签库在本页面中的前缀。
<s:text>
- uri: 指定标签库的位置。
<%@taglib prefix="s" uri="/struts-tags"%>
九个内置对象
out
:jsp的输出流,用来向客户端响应page
:当前jsp对象。它的引用类型是Object,即真身中有如下代码:Object page = this;config
:它对应真身中的ServletConfig对象!pageContext
:一个顶9个!request
:HttpServletEequestresponse
:HttpServletResponseexception
:Throwablesession
:HttpSessionapplication
:ServletContext
pageContext对象
在JavaWeb中一共四个域对象,其中Servlet中可以使用的是request、session、application三个对象,而在JSP中可以使用pageContext、request、session、application四个域对象。
pageContext 对象是PageContext类型,它的主要功能有:
- 域对象功能:
getAttribute(name,value)
、setAttribute(name,value)
、removeAttribute(name,value)
- 代理其它域对象功能
pageContext.setAttribute("x", "X");
pageContext.setAttribute("x", "XX", PageContext.REQUEST_SCOPE);
pageContext.setAttribute("x", "XXX", PageContext.SESSION_SCOPE);
pageContext.setAttribute("x", "XXXX", PageContext.APPLICATION_SCOPE);
void setAttribute(String name, Object value, int scope)
:在指定范围中添加数据;
Object getAttribute(String name, int scope)
:获取指定范围的数据;
void removeAttribute(String name, int scope)
:移除指定范围的数据;
Object findAttribute(String name)
:依次在page、request、session、application范围查找名称为name的数据,如果找到就停止查找。这说明在这个范围内有相同名称的数据,那么page范围的优先级最高!
- 获取其他内置对象
一个pageContext对象等于所有内置对象,即1个当9个。这是因为可以使用pageContext对象获取其它8个内置对象:
JspWriter getOut():获取out内置对象;
ServletConfig getServletConfig():获取config内置对象;
Object getPage():获取page内置对象;
ServletRequest getRequest():获取request内置对象;
ServletResponse getResponse():获取response内置对象;
HttpSession getSession():获取session内置对象;
ServletContext getServletContext():获取application内置对象;
Exception getException():获取exception内置对象;
JSP动作标签
动作标签的作用是用来简化Java脚本的。JSP动作标签是JavaWeb内置的动作标签,它们是已经定义好的动作标签,我们可以拿来直接使用。
- jsp的动作标签与html提供的标签的区别:动作标签是由tomcat(服务器)来解释执行,它与java代码一样,都是在服务器端执行的;html由浏览器来执行。
<jsp:forward>
:转发:它与RequestDispatcher的forward方法是一样的,一个是在Servlet中使用,一个是在jsp中使用
<jsp:include>
:包含:它与RequestDispatcher的include方法是一样的,一个是在Servlet中使用,一个是在jsp中使用<%@include>
和<jsp:include>
有什么不同:<%@include>
是静态包含,只生成一个.java文件;<jsp:include>
是动态包含,实际只是调用了另一个servlet,生成两个.java文件<jsp:param>
:作为forward和include的子标签,用来给转发或包含的页面传递参数
a.jsp
<jsp:forward page="b.jsp">
<jsp:param value="zhangsan" name="username">
<jsp:param value="123" name="password">
</jsp:forward>
b.jsp
<%
String username=request.getParameter("username");
String username=request.getParameter("password");
out.print(username+","+password);
%>
JavaBean
规范:
- 必须为成员提供get/set方法(两者只提供一个也是可以的),对于具有get/set方法的成员变量称之为属性;
- 必须要有默认无参构造器。
- 还可以没有成员,只有get/set方法。属性名称由get/set方法来决定。
- 如果属性类型为boolean类型,那么读方法的格式可以是get或is。例如名为abc的boolean类型的属性,它的读方法可以是getAbc(),也可以是isAbc();
//该例中User类有一个成员变量:username(而非hello)。也就是说成员变量的名称取决于get/set方法名。
public class User {
private String hello;
public String getUsername() {
return hello;
}
public void setUsername(String username) {
this.hello = username;
}
}
内省(了解)
内省的目标是得到JavaBean属性的读、写方法的反射对象,通过反射对JavaBean属性进行操作。内省依赖于反射。
演示:把Map数据封装到User
BeanInfo beanInfo = Introspector.getBeanInfo(User.class);//1.获取BeanInfo实例
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();//2.得到所有属性描述符对象
User user = new User();
for(PropertyDescriptor pd : pds) {
String name = pd.getName();//获取javabean属性名
String value = map.get(name);//获取属性名对应值
if(value != null) {
Method writeMethod = pd.getWriteMethod();//3.获取写方法
writeMethod.invoke(user, value);//4.把Map的值写入User对象对应的属性中
}
}
实际开发中,使用commons-beanutils这个工具。这个工具依赖于内省。
User user = new User();
//这里少赋值则为null,多赋值则不存入。都不会抛异常。
BeanUtils.setProperty(user, "username", "admin");
BeanUtils.setProperty(user, "password", "admin123");
System.out.println(user);
对于上面map的例子,则可以变为:
Use user=new User();
BeanUtils.populate(user,map);//要求map的key与bean的属性名相同
这里可以写一个自己的方法:
public static <T> T toBean(Map map,Class<T> clazz){
try{
T bean=clazz.newInstance();
BeanUtils.populate(bean,map);
return bean;
}
catch(Exception e){
throw new RuntimeException(e);
}
}
则可以迅速存储表单数据:
request.getParameterMap();
User user=CommonUtils.toBean(map,User.class);
jsp中与JavaBean相关的标签
<jsp:useBean>
:创建JavaBean对象;
<jsp:useBean id=“user1” class=“cn.itcast.domain.User” scope=“session”/> 在session域中查找名为user1的bean,如果不存在,创建之<jsp:setProperty>
:设置JavaBean属性;
<jsp:setProperty property=“username” name=“user1” value=“admin”/> 设置名为user1的javabean的username属性值为admin<jsp:getProperty>
:获取JavaBean属性;
<jsp:getProperty property=“username” name=“user1”/> 获取名为user1的javabean的username属性值
EL表达式
EL(Expression Language)是一门表达式语言,它对应<%=…%>
,也就是说EL只能做输出。格式${...}
。
- 当EL表达式的值为null时,会在页面上显示空白,即什么都不显示。
- 全域查找(最常用):
${xxx}
${pageScope.xxx}
、${requestScope.xxx}
、${sessionScope.xxx}
、${applicationScope.xxx}
,从指定域获取属性${requestScope.emp.address.street}
获取属性
11个内置对象
11个内置对象:pageScope requestScope sessionScope param paramValues header headerValues initParam cookie pageContext
域相关内置对象:
pageScope:${pageScope.name}
等同与pageContext.getAttribute(“name”);
requestScope:${requestScope.name}
等同与request.getAttribute(“name”);
sessionScoep: ${sessionScope.name}
等同与session.getAttribute(“name”);
applicationScope:${applicationScope.name}
等同与application.getAttribute(“name”);
请求参数相关内置对象:
- param:是一个Map,适用于单值的参数
- paramValues:是一个Map,value是多个参数值,适用于多值的参数
- header:是一个Map,适用于单值请求头
- headerValues:是一个Map,value是多个头值,适用于多值请求头
应用初始化参数相关内置对象
initParam:initParam是Map<String,String>类型。它对应web.xml文件中的参数。
Cookie相关内置对象
cookie:cookie是Map<String,Cookie>类型,其中key是Cookie的名字,而值是Cookie对象本身。
pageContext对象
pageContext:pageContext是PageContext类型。可以使用pageContext对象调用getXXX()方法,例如pageContext.getRequest(),可以${pageContext.request}。也就是读取JavaBean属性
EL函数库
是由JSTL提供的。
- 导入标签库:<%@ tablib prefix=“fn” uri=“http://java.sun.com/jsp/jstl/functions”%>
String toUpperCase(String input):把参数转换成大写
String toLowerCase(String input):把参数转换成小写
int indexOf(String input, String substring):从大串,输出小串的位置!
boolean contains(String input, String substring):查看大串中是否包含小串
boolean containsIgnoreCase(String input, String substring):忽略大小写的,是否包含
boolean startsWith(String input, String substring):是否以小串为前缀
boolean endsWith(String input, String substring):是否以小串为后缀
String substring(String input, int beginIndex, int endIndex):截取子串
String substringAfter(String input, String substring):获取大串中,小串所在位置后面的字符串
substringBefore(String input, String substring):获取大串中,小串所在位置前面的字符串
String escapeXml(String input):把input中“<”、">"、"&"、"’"、""",进行转义
String trim(String input):去除前后空格
String replace(String input, String substringBefore, String substringAfter):替换
String[] split(String input, String delimiters):分割字符串,得到字符串数组
int length(Object obj):可以获取字符串、数组、各种集合的长度
String join(String array[], String separator):用字符串连接数组中的元素形成字符串
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
…
String[] strs = {"a", "b","c"};
List list = new ArrayList();
list.add("a");
pageContext.setAttribute("arr", strs);
pageContext.setAttribute("list", list);
%>
${fn:length(arr) }<br/><!--3-->
${fn:length(list) }<br/><!--1-->
${fn:toLowerCase("Hello") }<br/> <!-- hello -->
${fn:toUpperCase("Hello") }<br/> <!-- HELLO -->
${fn:contains("abc", "a")}<br/><!-- true -->
${fn:containsIgnoreCase("abc", "Ab")}<br/><!-- true -->
${fn:contains(arr, "a")}<br/><!-- true -->
${fn:containsIgnoreCase(list, "A")}<br/><!-- true -->
${fn:endsWith("Hello.java", ".java")}<br/><!-- true -->
${fn:startsWith("Hello.java", "Hell")}<br/><!-- true -->
${fn:indexOf("Hello-World", "-")}<br/><!-- 5 -->
${fn:join(arr, ";")}<br/><!-- a;b;c -->
${fn:replace("Hello-World", "-", "+")}<br/><!-- Hello+World -->
${fn:join(fn:split("a;b;c;", ";"), "-")}<br/><!-- a-b-c -->
${fn:substring("0123456789", 6, 9)}<br/><!-- 678 -->
${fn:substring("0123456789", 5, -1)}<br/><!-- 56789 -->
${fn:substringAfter("Hello-World", "-")}<br/><!-- World -->
${fn:substringBefore("Hello-World", "-")}<br/><!-- Hello -->
${fn:trim(" a b c ")}<br/><!-- a b c -->
${fn:escapeXml("<html></html>")}<br/> <!-- <html></html> -->
自定义函数库
- 写一个java类,类中可以定义0~N个方法,但必须是static,而且有返回值的!
- 在WEB-INF目录下创建一个tld文件
<function>
<name>fun</name>
<function-class>cn.itcast.fn.MyFunction</function-class>
<function-signature>java.lang.String fun()</function-signature>
</function>
- 在jsp页面中导入标签库
在fn文件夹下创建jsp文件,并导入:
<%@ taglib prefix="it" uri="/WEB-INF/tlds/itcast.tld" %>
- 在jsp页面中使用自定义的函数:${it:fun() }
JSTL标签库
是对EL表达式的扩展(也就是说JSTL依赖于EL)。JSTL是标签语言。
- 使用:
导入jar包 jstl.jar:把项目发布到Tomcat时,MyEclipse会自动在lib目录下存放jstl的jar包;如果使用的不是MyEclipse需要自己导入包
在页面添加:<%@taglib prefix="c" uri=“http://java.sun.com/jsp/jstl/core” %>
- 四大库:
core:核心标签库,重点;
fmt:格式化标签库,只需要学习两个标签即可;
sql:数据库标签库,过时了;
xml:xml标签库,过时了。
c:out
<c:out>
:输出
value:可以是字符串常量,也可以是EL表达式
default:当要输出的内容为null时,会输出default指定的值
escapeXml:默认值为true,表示转义
举例 | 作用 |
---|---|
<c:out value=”aaa”/> | 输出aaa字符串常量 |
<c:out value=”${aaa}”/> | 与${aaa}相同 |
<c:out value=”${aaa}” default=”xxx”/> | 当${aaa}不存在时,输出xxx字符串 |
<%request.setAttribute(“a”,“”);%><c:out value="${a }" default=“xxx” escapeXml=“false” /> | 当escapeXml为false,不会转换“<”、“>”。这可能会受到JavaScript攻击。 |
c:set
<c:set>
:设置(创建域的属性)
var:变量名
value:变量值,可以是EL表达式
scope:域,默认为page,可选值:page、request、session、application
举例 | 作用 |
---|---|
<c:set var=”a” value=”hello”/> | 在pageContext中添加name为a,value为hello的数据。 |
<c:set var=”a” value=”hello” scope=”session”/> | 在session中添加name为a,value为hello的数据。 |
c:remove
<c:remove>
:移除
var:变量名
scope:如果不给出scope,表示删除所有域中的该名称的变量;如果指定了域,那么只删除该域的变量。
删除所有域中name为a的数据
<%
pageContext.setAttribute("a", "pageContext");
request.setAttribute("a", "session");
session.setAttribute("a", "session");
application.setAttribute("a", "application");
%>
<c:remove var="a"/>
<c:out value="${a }" default="none"/>
删除pageContext中name为a的数据
<c:remove var="a" scope=”page”/>
url
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%3F%ED%2C%3F
var
:指定变量名,一旦添加了这个属性,那么url标签就不会再输出到页面,而是把生成url保存到域中。scope
:它与var一起使用,用来保存url。
在这里,c:url标签在服务器端处理,
到达浏览器的时候已经是地址了
<a href="<c:url value='/index.jsp'>">回到主页</a>
if/choose
if
:对应java中的if语句
<c:if test="布尔类型">...</c:if>
,当test为真时,执行标签体内容
choose
:它对应java中的if/else if/ … /else
<c:choose>
<c:when test="">...</c:when>
<c:when test="">...</c:when>
<c:when test="">...</c:when>
...
<c:otherwise> ...</c:otherwise>
</c:choose>
等同于
if(...) {
} else if( ....) {
} else if( ....) {
} else if( ....) {
} ...
else { ...}
forEach
forEach
它用来循环遍历数组、集合;还可以用来计数方式来循环
用来输出数组、集合:
<c:forEach items="${strs }" var="str">
${str }<br/>
</c:forEach>
等同于:
for(String str : strs) {
...
}
属性:
- items:遍历对象,数组或集合
- var:每个元素
计数方式:
<c:forEach var="i" begin="1" end="10">
${i}
</c:forEach>
等同于:
for(int i = 1; i <= 10; i++) {
...
}
属性:
- var:循环变量
- begin:设置循环变量从几开始。
- end:设置循环变量到几结束。
- step:设置步长。等同与java中的i++,或i+=2。step默认为1
循环状态:使用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>