JSP三大指令(知道就可以!)
4.Jsp三大指令
1.JSP指令概述
JSP指令的格式:<%@指令名 attr1=”” attr2=”” %>,一般都会把JSP指令放到JSP文件的最上方,但这不是必须的
JSP中有三大指令:page、include、taglib最为常用,也最为复杂的就是page指令了
2.page指令
- pageEncoding:它指定了当前jsp页面编码
- contentType:它表示添加了一个响应头:content-type!等同于response.setContentType(“text/html;charset=utf-8”)
- import:只有它可以出现多次
errorpage和isErrorPage
①.errorpage:当前页面如果抛出异常,那么要转发到哪一个页面,由errorpage决定
②.isErrorPage:它指定当前页面是错误的页面,当该属性为true时,九大内置中只有Exception才能用 500错误
- language:指定当前jsp编译后的语言类型:java
- isThreadSafe:当前jsp是否存在并发访问
- session:当前页面是否支持session,如果为false,表示当前页面没有session这个内置对象
- page指令的pageEncoding和contentType(重点)
pageEncoding指定当前JSP页面的编码!这个编码是给服务器看的,服务器需要知道当前JSP使用的编码,不然服务器无法正确把JSP编译成java文件。所以这个编码只需要与真实的页面编码一致即可!在MyEclipse中,在JSP文件上点击右键,选择属性就可以看到当前JSP页面的编码了
contentType属性与response.setContentType()方法的作用相同!它会完成两项工作,一是设置响应字符流的编码,二是设置content-type响应头。例如:<%@ contentType=”text/html;charset=utf-8”%>,它会使“真身”中出现response.setContentType(“text/html;charset=utf-8”)
无论是page指令的pageEncoding还是contentType,它们的默认值都是ISO-8859-1,我们知道ISO-8859-1是无法显示中文的,所以JSP页面中存在中文的话,一定要设置这两个属性
- 其实pageEncoding和contentType这两个属性的关系很“暧昧”:
当设置了pageEncoding,而没设置contentType时: contentType的默认值为pageEncoding;
当设置了contentType,而没设置pageEncoding时: pageEncoding的默认值与contentType;
也就是说,当pageEncoding和contentType只出现一个时,那么另一个的值与出现的值相同。如果两个都不出现,那么两个属性的值都是ISO-8859-1。所以通过我们至少设置它们两个其中一个!
3.include指令
- include指令表示静态包含!即目的是把多个JSP合并成一个JSP文件
- include指令只有一个属性:file,指定要包含的页面,例如:<%@include file=”b.jsp”%>
- 静态包含:当hel.jsp页面包含了lo.jsp页面后,在编译hel.jsp页面时,需要把hel.jsp和lo.jsp页面合并成一个文件,然后再编译成Servlet(Java文件)。
很明显,在ol.jsp中在使用username变量,而这个变量在hel.jsp中定义的,所以只有这两个JSP文件合并后才能使用。通过include指定完成对它们的合并!
4.tablib指令
在JSP页面中使用第三方的标签库时,需要使用taglib指令来“导包”。
例如:<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
其中prefix表示标签的前缀,这个名称可以随便起。uri是由第三方标签库定义的,所以你需要知道第三方定义的uri
5.JSP九大内置对象[重点]
①out:jsp的输出流,用来向客户端响应
②page:当前jsp对象,它的引用类型是Object,即真身中有如下代码:object page=this;
③config(servletConfig):对应"真身"中的servletConfig
④ pageCotext:页面上下文对象,它是最后一个没讲的域[一个顶九个]
⑤request:即HttpServletRequest类的对象
⑥response:即HttpServletResponse类对象
⑦session:即HttpSession类对象
⑧application(servletContext):即ServletContext类的对象
⑨exception(throwable):只有在错误页面才会出现
1.在这9个对象中有很多的极少会被使用到的,例如:config、page、exception
2.在这9个对象中有两个对象不是所有jsp页面都可以使用:exception、session
3.在这9个对象中很多以前我们已经学过:out、request、response、applicaiton、session、config
6.pageCotext[掌握]
在JavaWeb中一共四个域对象,其中Servlet中可以使用的是request、session、application三个对象,而在JSP中可以使用pageContext、request、session、application四个域对象。
pageContext 对象是PageContext类型,它的主要功能有:①域对象功能;②代理其它域对象功能;③获取其他内置对象;
1.域对象功能:
- pageContext也是域对象,它的范围是当前页面。它的范围也是四个域对象中最小的!
void setAttribute(String name, Object value);
Object getAttrbiute(String name, Object value);
void removeAttribute(String name, Object value);
2.代理其它域对象功能
还可以使用pageContext来代理其它3个域对象的功能,也就是说可以使用pageContext向request、session、application对象中存取数据,例如:
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范围的优先级最高!
3.获取其他内置对象
一个pageContext对象等于所有内置对象,即1个当9个。这是因为可以使用pageContext对象获取其它8个内置对象:
JSP 动作标签
5.JSP 动作标签
1.inculde 和 taglib指令
- 1.inculde:静态包含 与RequestDispatcher的include方法的功能相似[区别]
<%@include %>它是在jsp编译成java文件时完成的!他们共同生成一个java( 就是一个servlet)文件,然后再生成一个class
RequestDispatcher的incilude()是一个方法,包含和被包含的两个servlet,即两个.class!他们只是把相应的内容在运行时合并了
作用:把页面分解了,使用包含的方法组合在一起,这样一个页面中不变的部分,就是一个独立的jsp,而我们只需要处理变化的页面
- taglib:导入便签库
<%@ taglib prefix=“pre” uri="/struts-tags"%>
hel.jsp
<%@ 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=UTF-8"> <title>Insert title here</title> </head> <body> <% String name="xiaozhi"; %> <%@include file="lo.jsp" %> </body> </html>
lo.jsp
<% out.println(name); %>
2.Jsp的动作标签
- 这些jsp的动作标签,与html提供的标签有本质的区别。
- 动作标签是由tomcat(服务器)来解释执行!它与java代码一样,都是在服务器端执行的!
- <jsp:forward>: 转发!它与RequestDispatcher的forward方法是一样的,一个是在Servlet中使用,一个是在jsp中使用!
- <jsp:include>:包含:它与RequestDispatcher的include方法是一样的,一个是在Servlet中使用,一个是在jsp中使用!
- <%@include>和<jsp:include>有什么不同!前面的是合并,后面的相当于一个调用
- <jsp:param>:它用来作为forward和include的子标签!用来给转发或包含的页面传递参数!
a.jsp
<%@ 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=UTF-8"> <title>Insert title here</title> </head> <body> a.jsp <!-- 动态包含 --> <jsp:include page="b.jsp"/> <!-- 请求转发:留头不留体 --> <jsp:include page="b.jsp"> </body> </html>
b.jsp
///
<%@ 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=UTF-8"> <title>Insert title here</title> </head> <body> b.jsp </body> </html>
<body> a.jsp <!-- 动态包含 --> <jsp:include page="b.jsp"> <jsp:param name="username" value="xiaozhi"/> <jsp:param name="password" value="123"/> </jsp:include> </body>
<body> b.jsp <% String username=request.getParameter("username"); String password=request.getParameter("password"); out.println(username+""+password); %> </body>
6.JavaBean[掌握]
1.JavaBean的规范:
①必须要有一个默认无惨构造器
② 提供get/set方法,如果只有get方法,那么这个属性是只读属性;如果只提供了setter方法,这样的属性叫只写属性
③ 一般对于具有get/set方法的成员变量称为属性
- 注意:
其实就算一个属性没有对应的成员变量,只有get/set方法也是可以的!属性名称就是get/set方法去除get/set再首字母小写
方法名称满足一定的规范,那么它就是属性!boolean类型的属性,它的读方法可以是is开头,也可以是get开头!
public class Person { private String name; private Integer age; private String gender; public Person() { super(); // TODO Auto-generated constructor stub } public String getId(){ return "fasdgr"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } }
7.内省 [了解]→依赖反射
内省 → Bean信息 → 属性的描述符 → 属性的get/set对应的Method → 反射
8.commons-beanutils [掌握] → 依赖内省
提到内省,不能不提commons-beanutils这个工具。它底层使用了内省,对内省进行了大量的简化!
- 使用beanutils需要的jar包:
commons-beanutils.jar;
commons-logging.jar;
①获取JavaBean属性
@Test public void fun1()throws Exception{ String className="com.itheima.domin.Person"; Class clazz=Class.forName(className); Object bean=clazz.newInstance(); //设置JavaBean属性 BeanUtils.setProperty(bean,"name", "张三"); BeanUtils.setProperty(bean, "age", "23"); BeanUtils.setProperty(bean, "gender", "男"); //读取JavaBean的属性 String age=BeanUtils.getProperty(bean, "name"); System.out.println(age); System.out.println(bean); }
②把map中的属性封装到一个bean中
//Map{"username":"admin","password":"123"} //我们要把map的数据封装到一个JavaBean中,要求map的key和bean的属性名相同 @Test public void fun2()throws Exception{ Map<String,Object>map=new HashMap<String, Object>(); map.put("username", "admin"); map.put("password", "123"); User user=new User(); BeanUtils.populate(user, map); System.out.println(user); }
3.重点
CommonUtils
public class CommonUtils { //生成不重复的32位长的大写字符串 public static String uuid(){ return UUID.randomUUID().toString().replace("-", "").toUpperCase(); } //把map转换成指定类型的JavaBean对象 public static <T>T toBean(Map map,Class<T>clazz){ try { //1.创建指定类型的JavaBean对象 T bean=clazz.newInstance(); //2.把数据封装到JavaBean中 BeanUtils.populate(bean, map); //3.返回JavaBean对象 return bean; } catch (Exception e) { throw new RuntimeException(e); } } }
Test
@Test public void fun3(){ Map<String,Object>map=new HashMap<String, Object>(); map.put("username", "admin"); map.put("password", "123"); User user=CommonUtils.toBean(map, User.class); System.out.println(user); }
EL入门
9.EL入门
1.EL概述
1.1EL的作用
jsp2.0开始,不让再使用java脚本,而是使用el表达式和动态标签来替代java脚本!
EL替代的是<%= … %>,也就是说,EL只能做输出!
1.2EL的格式
格式:${…} 例如:${1 + 2}
1.3关闭EL
如果希望整个JSP忽略EL表达式,需要在page指令中指定isELIgnored=”true”
如果希望忽略某个EL表达式,可以在EL表达式之前添加“\”,例如:${1 + 2}
1.4EL运算符
1.5 EL不显示null
当EL表达式的值为null时,会在页面上显示空白,即什么都不显示。
2.EL表达式格式
- 操作List和数组:${list[0]}、${arr[0]};
- 操作bean的属性:${person.name}、${person[‘name’]},对应person.getName()方法;
- 操作Map的值:${map.key}、${map[‘key’]},对应map.get(key)。
3.EL内置对象
- EL一共11个内置对象,无需创建即可以使用。这11个内置对象中有10个是Map类型的,最后一个是pageContext对象。
pageScope、requestScope、sessionScope、applicationScope
param、paramValues
header、headerValues
initParam、cookie、pageContext
4.EL表达式来读取四大域[常用]
- ${xxx},全域查找名为xxx的属性,如果不存在,输出空字符串,而不是null。
- $ { pageScope.xxx}、$ {requestScope.xxx}、${sessionScope.xxx}、
${applicationScope.xxx},指定域获取属性!
<body> <% pageContext.setAttribute("xxx", "pageContext_xxx"); request.setAttribute("xxx", "request_xxx"); session.setAttribute("xxx", "session_xxx"); application.setAttribute("xxx", "application_xxx"); %> ${xxx }</br> ${pageScope.xxx}</br> ${requestScope.xxx}</br> ${sessionScope.xxx}</br> ${applicationScope.xxx}</br> </body>
javaBean导航[重要]
<% Address address = new Address(); address.setCity("北京"); address.setStreet("西三旗"); Employee emp = new Employee(); emp.setName("李小四"); emp.setSalary(123456); emp.setAddress(address); request.setAttribute("emp", emp); %>
<h3>使用el获取request域的emp</h3> ${requestScope.emp.address.street } <!-- request.getAttribute("emp").getAddress().getStreet() --><br/>
5.pageContext
- pageContext:pageContext是PageContext类型!可以使用pageContext对象调用getXXX()方法,例如pageContext.getRequest(),可以${pageContext.request}。也就是读取JavaBean属性!!!
- pageContext:它是PageContext类型!${pageContext.request.contextPath} [重点]:获取当前的项目名
- $ {pageContext.request.contextPath}样是通过 get方法去取的,先pageContext.getRequest()得到HttpServletRequest对象,再调用 HttpServletRequest的getContextPath方法
6.其他的六个内置对象
1.请求参数相关内置对象
- param和paramValues这两个内置对象是用来获取请求参数的。
param:Map<String,String>类型,param对象可以用来获取参数,与request.getParameter()方法相同。
注意,在使用EL获取参数时,如果参数不存在,返回的是空字符串,而不是null。这一点与使用request.getParameter()方法是不同的
- paramValues:paramValues是Map<String, String[]>类型,当一个参数名,对应多个参数值时可以使用它。
2.请求头相关内置对象
- header和headerValues是与请求头相关的内置对象:
- headerValues:headerValues是Map<String,String[]>类型。当一个请求头名称,对应多个值时,使用该对象,这里就不在赘述
3.应用初始化参数相关内置对象
- initParam:initParam是Map<String,String>类型。它对应web.xml文件中的<context-param>参数。
4.Cookie相关内置对象
- cookie:cookie是Map<String,Cookie>类型,其中key是Cookie的名字,而值是Cookie对象本身。
EL函数库
10.EL函数库 [了解]
1 什么EL函数库
- EL函数库是由第三方对EL的扩展,我们现在学习的EL函数库是由JSTL添加的
- EL函数库就是定义一些有返回值的静态方法。然后通过EL语言来调用它们!当然,不只是JSTL可以定义EL函数库,我们也可以自定义EL函数库
- EL函数库中包含了很多对字符串的操作方法,以及对集合对象的操作。例如:${fn:length(“abc”)}会输出3,即字符串的长度。
2.导入函数库
- 因为是第三方的东西,所以需要导入。导入需要使用taglib指令!
<%@ taglib prefix=“fn” uri=“http://java.sun.com/jsp/jstl/functions” %>
3.EL函数库介绍
- 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> -->