本篇博客主要讲述JSP语法、EL技术和JSTL技术。
为什么sun推出 JSP技术?
Servlet 生成网页比较复杂,本身不支持HTML语法,html代码需要通过response输出流输出,JSP支持HTML语法,生成HTML方便。JSP技术与Servlet 技术区别和关系?
JSP和Servlet技术都是用来动态生成网页的,Servlet不支持HTML语法,生成网页麻烦,JSP支持HTML语法,生成网页方便,JSP运行是由服务器翻译成Servlet执行的。JSP 就是 Servlet。JSP运行原理是怎样的?
客户端访问编写JSP文件,服务器读取JSP文件,根据JSP生成Servlet ,Servlet编译运行 生成网页。
JSP脚本元素 <%! %> <%= %> <% %>JSP翻译Servlet 存放tomcat/work 目录
注: JSP翻译为Servlet,页面当前所有HTML 翻译为out.write 输出
代码示例:
demo1.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
JSP脚本元素
<%!
// JSP声明 定义成员变量、成员方法 、内部类
public static void m(){}
class A {}
%>
<%="abcd" %>
<%
// JSP 脚本代码块,嵌入任何java代码
String s = "abcdefg";
s = s.toUpperCase();
out.print(s);
%>
demo1_jsp.java:
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/7.0.42
* Generated at: 2016-09-03 12:18:11 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class demo1_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
// JSP声明 定义成员变量、成员方法 、内部类
public static void m(){}
class A {}
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map _jspx_dependants;
private javax.el.ExpressionFactory _el_expressionfactory;
private org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map getDependants() {
return _jspx_dependants;
}
public void _jspInit() {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
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 {
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 {
response.setContentType("text/html; charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\r\n");
out.write("\r\n");
out.write("\r\n");
out.write("\r\n");
out.write("\r\n");
out.write("Insert title here \r\n");
out.write("\r\n");
out.write("\r\n");
out.write("JSP脚本元素
\r\n");
out.write("\r\n");
out.write("\r\n");
out.write("\r\n");
out.print("abcd" );
out.write("\r\n");
out.write("\r\n");
// JSP 脚本代码块,嵌入任何java代码
String s = "abcdefg";
s = s.toUpperCase();
out.print(s);
out.write("\r\n");
out.write("\r\n");
out.write("");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
JSP支持三种注释
1、JSP注释 <%-- --%> 只存在JSP文件源码中,在JSP翻译Servlet时,这类注释消失了2、Java注释 /** */文档注释、/* */多行注释、// 单行注释
文档注释 /** */ 生成javadoc 主要用来注释 包、类、成员变量、成员方法 ------ 代码功能使用者3、HTML注释
* 在JSP翻译为Servlet时会被翻译 out.print 在生成HTML页面源代码中,该类注释也是存在的代码示例:
demo2.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
JSP三种注释
<%-- JSP注释 --%>
<%!
/** 文档注释 肯定用在 JSP声明中*/
public void printInfo(){}
%>
<%
/** 多行注释*/
// 单行注释 存放JSP 脚本代码块
%>
<%
String s = "abcd";
%>
demo2_jsp.java:
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/7.0.42
* Generated at: 2016-09-17 09:21:24 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class demo2_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
/** 文档注释 肯定用在 JSP声明中*/
public void printInfo(){}
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map _jspx_dependants;
private javax.el.ExpressionFactory _el_expressionfactory;
private org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map getDependants() {
return _jspx_dependants;
}
public void _jspInit() {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
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 {
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 {
response.setContentType("text/html; charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\r\n");
out.write("\r\n");
out.write("\r\n");
out.write("\r\n");
out.write("\r\n");
out.write("Insert title here \r\n");
out.write("\r\n");
out.write("\r\n");
out.write("JSP三种注释
\r\n");
out.write("\r\n");
out.write("\r\n");
out.write('\r');
out.write('\n');
/** 多行注释*/
// 单行注释 存放JSP 脚本代码块
out.write("\r\n");
out.write("\r\n");
out.write("\r\n");
String s = "abcd";
out.write("\r\n");
out.write("\r\n");
out.write("\r\n");
out.write("");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
结论:JSP注释在翻译阶段消失,Java注释在Servlet运行阶段消失,HTML注释不消失。
思考题:结论: HTML注释 无法阻止 JSP或者 Java代码执行的。
JSP指令又称为JSP Derective
功能:
用于指示JSP执行某些步骤语法:<%@ 指令名称 属性=值 属性=值 ... %>
分类:page指令
include指令taglib指令
page指令用来定义JSP文件的全局属性 <%@ page 属性=值 %>
在JSP页面中,只有import可以出现多次,其他属性都只能出现一次
1、language 只能为java7、通过contentType和pageEncoding 设置 JSP页面编码
pageEncoding 是 JSP文件源代码在硬盘上编码集,如果设置支持中文的编码集,那么服务器就能正确读取jsp中的中文,并将翻译好的中文字符读取进内存(注意内存中保存的不是字节)pageEncoding和contentType区别:
makeerror.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%--发生错误,想让用户看到友好页面 error.jsp--%>
<%@ page errorPage="/demo4/error.jsp" %>
Insert title here
<%
int d = 1/0;
%>
在错误友好页面中,可以通过设置isErrorPage属性,获得jsp内置对象exception,从而通过exception获得错误原因。
error.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%--当设置了当前页面是错误页面,则可以获得内置对象exception,从而获得错误信息 --%>
<%@page isErrorPage="true" %>
Insert title here
对不起,服务器正在升级,请稍后访问!
错误原因:<%=exception.getMessage() %>
注:在实际开发中,一般不使用上面讲解错误处理方式,不然在每个发生错误的页面都要设置errorPage,指示发生错误时往哪里跳,太麻烦!
错误页面 第二种处理方式:配置web.xml
500
/demo5/500.jsp
404
/demo5/404.jsp
好处:不仅可以处理500 ,还可以处理404
示例:
mkeerror.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
<%
// 制作 空指针异常
String s = null;
s.trim();
%>
500.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
对不起,服务器发生内部错误,请稍后访问!
404.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
对不起,你访问的资源不存在,网站将在3秒之后 自动跳转到主页面!
效果:
注:第二中处理错误页面的方式必须掌握!
page指令 代码示例:
<%@ page language="java" %>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page pageEncoding="gbk" %>
<%--如果编写 extends 属性,必须继承 Servlet实现类 ,这个属性一般不写--%>
<%--<%@ page extends="java.util.ArrayList" %>--%>
<%@page session="true" %>
<%@page import="java.util.List"%>
<%--通过 isELIgnored 控制 EL表达式是否解析 --%>
<%@ page isELIgnored="false" %>
Insert title here
Page指令
<%
session.setAttribute("name","lichunchun");
%>
<%
// JSP 在翻译Servlet时 默认导入
/*import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
*/
// 如果 在jsp中使用 以上三个包类 不需要导包
Cookie cookie ;
List list ; //通过 alt+/ 回车快速生成导包 语句
%>
<%
request.setAttribute("address","安徽合肥");
%>
${requestScope.address }
include指令 ,用来静态包含页面 ----- 将页面公共部分提取出来,通过include完成页面布局。
语法:<%@ include file="文件路径" %>
include包含的是目标页面的整个内容,所以被包含页面,不需要是一个完整HTML,只要编写HTML片段就可以了。
代码示例:
index.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
<%@ include file="/demo6/logo.jsp" %>
主页面其它内容
<%--包含页面必须存在的--%>
<%@ include file="/demo6/footer.jsp" %>
logo.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
这是系统LOGO
footer.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String s = "[email protected]";
%>
<%=s %>
静态include原理
* 被包含的jsp文件本身不会被单独翻译成一个Servlet文件,而是把它们翻译成Servlet拼接到index_jsp.java这个Servlet文件中,所以我们在apache/work目录下只能看到index_jsp.java这一个Servlet文件。
* 在 JSP翻译为Servlet时,完成包含动作,此时Servlet程序并没有执行,包含路径不能用变量、不能含有?拼接参数,目标文件必须存在
* 存在特殊案例:被包含页面存在错误,只要包含后 组合在一起的Servlet没有错误,就可以执行
taglib指令 ,用来在jsp页面引用标签库文件
* 定义标签作用为了简化 jsp页面开发uri ---- 定义标签 唯一命名空间
prefixt ---- 命名空间前缀引用jstl时,在导入的jstl.jar中 META-INF/c.tld
代码示例:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%--通过 taglib 指令 引用jstl ,必须导入jstl 的 jar包--%>
<%--在 javaee 5 libraries 存在 jstl-1.2.jar--%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
Insert title here
<%
request.setAttribute("a",10);
%>
a的值 大于8
什么是内置对象?
JSP翻译为Servlet代码时,有些对象是默认已经创建好的,这类对象可以直接在jsp中使用,称之为内置对象。JSP的九个内置对象分别是什么?
page、request、session、application、response、pageContext、out、config、exceptionrequest HttpServletRequest ---- 请求对象
response HttpServletResponse ---- 响应对象
session HttpSession ------- 会话对象
application ServletContext ------ web应用全局唯一对象
config ServletConfig ------ 初始化数据
page this (HttpServlet)
pageContext PageContext
exception Throwable (所有exception异常的父类) ----- 当页面是一个错误页面,用exception获得异常信息 ---- jsp页面设置了isErrorPage,才会有这个内置对象
out JspWriter
下面具体解释一下这里面的几个没有见过的内置对象:
page 代表当前jsp生成的Servlet对象
* page 是 Object类型,只能使用Object中方法 ---- 这个对象在开发中不建议使用Servlet 三种数据范围: request、session、servletcontext
JSP 四种数据范围: page、request、session、application
* JSP 在 Servlet 三种数据范围基础上,新添加page数据范围
* page数据范围存放数据,只在当前jsp内有效* 向page 范围保存数据,必须通过 pageContext对象 setAttribute方法
pageContext 是当前“页面上下文”对象,代表的是当前页面运行的一些属性。
pageContext 对象提供了对JSP页面所有的对象及命名空间的访问。1、向page范围存取数据
pageContext.setAttribute("name","page");2、查找各个域中的属性
findAttribute 方法 依次在 page 、request 、session 、 application 四个数据范围进行数据查找3、pageContext 用来 获得其它八个隐含对象
* pageContext封装八个隐含对象意义:框架编写,得到PageContext对象 相当于得到 JSP九个内置对象
* 通过pageContext对象获得其他八个隐含对象
out 功能向浏览器输出信息,是JspWriter类型,内部使用PrintWriter实现,拥有独立缓冲区。
out创建:out对象通过pageContext对象获得,而在创建pageContext对象时,需指定out缓冲区大小以及是否自动flush代码示例:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page isErrorPage="true" %>
<%--通过 buffer和autoFlush 设置out 对象缓冲区--%>
<%--<%@page buffer="1kb" autoFlush="false" %>--%>
Insert title here
JSP 九个内置对象
<%
// 非要使用page对象
HttpServlet httpServlet = (HttpServlet)page;
out.print(httpServlet.getServletContext().getRealPath("/"));
%>
<%
// 向四种数据范围保存数据
request.setAttribute("name","request");
session.setAttribute("name","session");
application.setAttribute("name","application");
// 向page 范围保存数据,必须通过 pageContext对象
pageContext.setAttribute("name","page");
%>
<%=request.getAttribute("name") %>
<%=session.getAttribute("name") %>
<%=application.getAttribute("name") %>
<%=pageContext.getAttribute("name") %>
<%
// 想在四个数据范围查询 指定名称数据
// 顺序按照 page -- request -- session -- application
Object value = pageContext.findAttribute("name");
%>
查找name属性 :<%=value %>
通过EL 取得数据
${sessionScope.name }
${name }
通过查看Servlet翻译成的java代码,观察9个内置JSP对象:
out 向浏览器输出内容,response.getWriter 向浏览器输出内容 , 区别?
实验:在demo9.jsp加入如下内容原因:JspWriter和response各自有独立的缓冲区,out中的内容会先刷新到response缓冲区中,然后一并输出到浏览器。
解惑:out 和 response.getWriter 区别
备注:out隐式对象的工作原理图
实验代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
<%
out.println("aaa");//此时aaa写到了out缓冲区中
out.flush();//out的内容从out缓冲区输出到response缓冲区中
response.getWriter().println("bbb");
out.print("ccc");
//这之后先调用out.flush刷到response.getWriter缓冲区
//然后调用response.getWriter.flush刷到浏览器
%>
exception对象是java.lang.Trowable类的实例 (使用前需要在jsp页面设置page指令 isErrorPage=“true”)
exception对象用来处理JSP文件在执行时所有发生的错误和异常exception对象可以和page指令一起使用,通过指定某一个页面为错误处理页面,对错误进行处理
<%@ page isErrorPage="true"%>的页面内使用。(最好还是用第二种配置web.xml的方式)
再温习一下这9个JSP内置对象:
page、request、session、application、response、out、config、pageContext、exception
JSP标签也称之为Jsp Action (JSP动作) 元素,它用于在Jsp页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护。注意,这些标签是默认存在的,不需要引入Jar包。
JSP指令和JSP标签 区分?jsp中六个动作标签
被包含页面不需要完整html,只需要编写html片段
代码示例:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
主页面其它内容
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
页面 LOGO信息
解惑:
jsp:include 和 @include 区别?
<%@ include%>:include指令,静态包含,在jsp翻译为Servlet时,执行包含动作,包含结果是目标页面翻译后的Servlet源代码,翻译为一个Servlet一起执行(包含的是Servlet源码)原理:include动态包含
总结:
*两种include用法的区别:
实验:
代码示例:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
Hello A
<%
// 看不到Hello A,因为在跳转之前,会清空response 缓冲区
// request.getRequestDispatcher("/demo11/b.jsp").forward(request,response);
%>
<%
request.setAttribute("name", "lichunchun");
%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
Hello B
<%=request.getAttribute("name") %>
<%=request.getParameter("school") %>
注:
EL 表达式语言,来自民间 ,Servlet2.4 之后 EL 被纳入官方规范。
EL主要功能:
1、EL 获得 JSP四个范围中保存数据 (访问JavaBean的属性)EL注意事项:
EL是从javaee1.4版本才被纳入规范,javaee1.3及以前版本,默认对EL不进行解析* 如果想javaee1.3以及之前版本解析 EL ------ 在JSP中加入page属性 <%@ page isELIgnored="false" %>
使用EL指定查找四个范围数据:
${pageScope.属性名称}
${requestScope.属性名称}
${sessionScope.属性名称}
${applicationScope.属性名}
如果不指定查找数据范围 ${属性名称} ---- 会调用pageContext.findAttribute方法在page、request、session、application四个域范围依次查找代码示例:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
Insert title here
<%
pageContext.setAttribute("city","合肥");
request.setAttribute("name","李春春");
session.setAttribute("school","中国科学技术大学");
application.setAttribute("pnum",100);
%>
${pageScope.city }
${requestScope.name }
${sessionScope.school }
${applicationScope.pnum }
省略指定范围, 默认调用pageContext.findAttribute() 在四个范围依次查找
${name }
${city }
EL找不到数据返回""空串、传统表达式方式找不到数据返回null
abc: <%=request.getAttribute("abc") %>
abc: ${abc }
EL表达式也可以很轻松获取JavaBean的属性,或获取数组、Collection、Map类型集合的数据
代码示例:
package ustc.lichunchun.domain;
public class Person {
private String name;
private int age;
private City city;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
}
package ustc.lichunchun.domain;
public class City {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@page import="ustc.lichunchun.domain.Person"%>
<%@page import="ustc.lichunchun.domain.City"%>
Insert title here
<%
Person person = new Person();
person.setName("李春春");
person.setAge(24);
City city = new City();
city.setName("合肥");
person.setCity(city);
pageContext.setAttribute("person", person);
%>
${pageScope.person.name }
${pageScope.person.age }
${pageScope.person["age"] }
${pageScope["person"]["age"] }
${pageScope.person.city.name }
${pageScope["person"]["city"]["name"] }
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@page import="java.util.List"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.Map"%>
<%@page import="java.util.HashMap"%>
Insert title here
<%
List list = new ArrayList();
list.add("abc");
list.add("bcd");
list.add("efg");
// 将list 保存page范围
pageContext.setAttribute("list",list);
%>
${pageScope.list }
取得list的第二个元素 :${pageScope.list[1] }
<%
Map map = new HashMap();
map.put("aaa","111");
map.put("bbb","222");
pageContext.setAttribute("map",map);
%>
取得 map 中 bbb对应 value : ${pageScope.map.bbb }、${pageScope.map["bbb"] }
通过上面的demo3.jsp代码,我们发现获得数组、List、Map时,有些情况使用 [ ] 获得属性值,那么问题来了:[ ] 可以使用特殊标识信息,但是. 不可以
例如:只能通过 [ ] 进行访问 ----- 注意:在使用[ ] 进行属性取值时,要加"" , 若不加"" 则认为是一个变量
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@page import="java.util.List"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.Map"%>
<%@page import="java.util.HashMap"%>
Insert title here
<%
List list = new ArrayList();
list.add("abc");
list.add("bcd");
list.add("efg");
// 将list 保存page范围
pageContext.setAttribute("list",list);
%>
${pageScope.list }
取得list的第二个元素 :${pageScope.list[1] }
<%
Map map = new HashMap();
map.put("aaa","111");
map.put("bbb","222");
pageContext.setAttribute("map",map);
%>
取得 map 中 bbb对应 value : ${pageScope.map.bbb }、${pageScope.map["bbb"] }
. 和 [] 区别
<%
pageContext.setAttribute("0","itcast");
pageContext.setAttribute("aa.bb","特殊标识信息");
%>
特殊字符0 属性值:${pageScope["0"] }
特殊字符 aa.bb 属性值 :${pageScope["aa.bb"] }
<%
String ds = "aa.bb";
pageContext.setAttribute("s",ds);
%>
特殊字符 aa.bb 属性值 :${pageScope[s] }
特殊字符 aa.bb 属性值 :${pageScope["s"] }
点我
结论:在使用EL进行取值时,如果含有特使字符属性,尽量使用[ ] , 否则都使用 . 就可以了!
结合JSTL的foreach标签,使用EL表达式也可以很轻松迭代各种类型的数组或集合,如迭代数组、迭代collection类型集合、迭代map类型集合,后面jstl标签c:foreach时我会提及。
在EL 执行运算时,运算语句必须写入 ${ }中
* 在EL 获得属性值 执行算术运算,自动类型转换 ---- 执行算术运算时,进行运算参数,必须都是数字empty运算符
1) 判断一个属性是否存在 , 通常empty运算符都是结合c:if 一起使用二元表达式:${user!=null?user.name:""} ----- 三元运算符
不能使用保留字存储属性,保留字有特殊意义
EL表达式保留关键字:
代码示例:
<%@page import="java.util.HashMap"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
Insert title here
EL 执行 运算
<%
pageContext.setAttribute("a", "10");
pageContext.setAttribute("b", "20");
pageContext.setAttribute("10", "30");
%>
${a+b }
<%--经典错误 :${"a"+"b" }--%>
${pageScope.a }
${pageScope["a"] }
${pageScope[a] }
${a }
${"a" }
empty运算符
${empty name }
根本不存在 name数据
<%
pageContext.setAttribute("list", new ArrayList());
pageContext.setAttribute("map", new HashMap());
%>
${empty list }
${empty map }
二元表达式
${(empty map)?"map中没有任何元素":"map不为空" }
<%
// 不能使用保留字 存储属性,保留字有特殊意义
pageContext.setAttribute("empty","111");
%>
<%--${pageContext["empty"] }--%>
EL表达式语言中定义了11个隐含对象,使用这些隐含对象可以很方便地获取web开发中的一些常见对象,并读取这些对象的数据。
语法:${隐式对象名称} :获得对象的引用
pageScope、requestScope、sessionScope、applicationScope 四个数据范围,用来取值
pageContext 当前jsp上下文 ----- ${pageContext.request.contextPath }${param.name} 等价于 request.getParameter("name")
${paramValues.hobby} 等价于 request.getParameterValues("hobby")必须掌握cookie隐含对象写法:
Cookie[] cookies = request.getCookies();
if(cookies==null){
out.println("cookie不存在!");
}else{
for(Cookie cookie : cookies){
if(cookie.getName().equals("address")){
out.println(cookie.getValue());
}
}
}
使用EL : ${cookie.address.value },太简单了!
注意:代码示例:
<%@page import="java.net.URLDecoder"%>
<%@page import="java.net.URLEncoder"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
用pageContext这个EL隐含对象,获得当前工程虚拟目录名称
<%=request.getContextPath()%>
<%=((HttpServletRequest)pageContext.getRequest()).getContextPath() %>
${pageContext.request.contextPath }
<%
Cookie c = new Cookie("address",URLEncoder.encode("合肥", "utf-8"));
c.setPath("/day08");
c.setMaxAge(60*60);
Cookie c1 = new Cookie("school","ustc");
c1.setPath("/day08");
c1.setMaxAge(60*60);
response.addCookie(c);
response.addCookie(c1);
%>
<%
Cookie[] cookies = request.getCookies();
if(cookies==null){
out.println("cookie不存在!");
}else{
for(Cookie cookie : cookies){
if(cookie.getName().equals("address")){
out.println(URLDecoder.decode(cookie.getValue(), "utf-8"));
}
if(cookie.getName().equals("school")){
out.println(cookie.getValue());
}
}
}
%>
${cookie.school.name }
${cookie.school.value }
为了简化在JSP页面操作字符串,JSTL中提供了一套EL自定义函数,这些函数包含了JSP页面制作者经常要用到的字符串操作。例如,fn:toLowerCase将字符串中的字符变为小写,fn:indexOf返回一个指定字符串在另一个字符串中第一次出现的索引位置。
JSTL中提供的EL自定义函数必须在EL表达式中使用,例如,${fn:toUpperCase("www.it315.org")}。步骤:
第一步:编写java类,提供static方法sun在jstl中提供一套EL函数库,这套函数库在导入jstl的jar包后,可以直接使用
1) 导入jstl.jar代码示例:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
Insert title here
<%
pageContext.setAttribute("msg","asdcasdaSGFDSFGSFGA");
// 将 msg转换为大写输出
%>
${msg }
${fn:toUpperCase(msg) }
${fn:toLowerCase(msg) }
${fn:split('blog.csdn.net','.')[1] }
<%
pageContext.setAttribute("arr",new String[]{"aa","bb","cc"});
%>
${fn:join(arr,'-') }
<%--${fn:escapeXml('主页') } --%>
在外包项目中,通常 jsp内部是不允许定义脚本元素 <%%>的 ----- 必须用标签库和表达式语言,实现<%%> 代码效果。
使用jstl步骤:
1、去官网上下载jstl的jar 1.0 1.1 1.2
1.1和1.2 基本一样 Servlet2.4(javaee1.4 ) 以后提出的,1.0 在 javaee1.3 之前提出的。2、jar包导入
jstl1.1中有两个jar包:jstl.jar、standard.jar ----- jstl.jar接口API、standard.jar代码实现,将两个jar包复制工程/WebRoot/WEB-INF/lib 目录中。3、在jsp页面内 通过taglib指令,引入jstl 标签库对应uri
JSTL分为五类:core核心标签、fmt国际化标签、sql数据库标签、xml操作xml标签、fn是EL函数库
因为数据库操作和xml操作,都将代码编写Servlet中,所以sql标签库和xml标签库不学习了。每个标签库在jar/META-INF/ 对应一个tld文件,也即标签库的定义文件,例如:c.tld 是jstl1.1版本的、c-1_0.tld 是 jstl1.0 版本标签库
注意区分taglib导包版本:
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 导入1.1* /jstl/demo.jsp(15,0) According to TLD or attribute directive in tag file, attribute test does not accept any expressions
代码示例:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
Insert title here
<%
pageContext.setAttribute("a", 10);
%>
a>8
JSTL核心标签库包含了一组用于实现WEB应用中的通用操作的标签,JSP规范为核心标签库建议的前缀名为c。
1、c:out 用于将内容输出到页面上 ------- 打印常量、输出EL值、提供default默认值、HTML转义输出功能
2、c:set 用于设置一个变量或者属性 ---- 向四个数据范围保存一个数据、对四个数据范围内一个已经存在的Map或者JavaBean对象修改其属性值常用:c:set、c:if、c:forEach、c:url进行中文url编码、c:redirect
代码示例:
out.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
Insert title here
<%
pageContext.setAttribute("name", "lichunchun");
%>
${name }
${(empty age)?"age不存在":age }
set.jsp:
<%@page import="ustc.lichunchun.domain.Person"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
Insert title here
<%
pageContext.setAttribute("m", 10);
request.setAttribute("n", 20);
// 都可用c:set取代
%>
${m } ${n }
<%
Person p = new Person();
p.setName("lichunchun");
pageContext.setAttribute("p", p);
%>
${p.name }
remove.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
Insert title here
<%
request.setAttribute("name", "lichunchun");
%>
${name }
<%--等价于 request.removeAttribute("name")--%>
name被移除后 : ${name }
catch.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
Insert title here
<%
try{
int d=1/0;
}catch(Exception e) {
out.print("异常被捕获了!");
}
%>
<%
int d2 = 1/0;
%>
异常信息:${e2.message }
if.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
Insert title here
<%
int m = 10;
if(m >8){
out.print("m的值大于8");
}else{
out.print("m的值不大于8");
}
%>
n的值大于8
n的值不大于8
${result }
choose.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
Insert title here
星期一
星期二
星期三
只能输入 1 2 3 ,输入数字无效的!
foreach.jsp:
<%@page import="java.util.Map"%>
<%@page import="java.util.HashMap"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
Insert title here
第${status.index }次循环 :
${i }
${i }
${i }
${result }
<%
//3、遍历map
Map map = new HashMap();
map.put("abcd","1234");
map.put("defg","5678");
pageContext.setAttribute("map", map);
%>
${entry.key } : ${entry.value }
<%
//2、遍历List
List list = new ArrayList();
list.add("aaa");
list.add("bbb");
pageContext.setAttribute("list", list);
%>
${element }
<%
//1、通过c:forEach遍历一个数组
pageContext.setAttribute("arr", new int[]{1,2,3,4,5});
%>
${i }
StringTokenizer.java:
package ustc.lichunchun.test;
import java.util.StringTokenizer;
public class StringCutter {
public static void main(String[] args) {
// 切割字符串 三种
String url = "mail.ustc.edu.cn?username=computer&password=20161019";
// 第一种 indexOf 结合 substring --- 目标username 是?
int index1 = url.indexOf("username=");
int index2 = url.indexOf("&");
System.out.println(url.substring(index1+"username=".length(), index2));
// 第二种 split
String[] arr = url.split("=|&");
System.out.println(arr[1]);
// 第三种 StringTokenizer
StringTokenizer stringTokenizer = new StringTokenizer(url, "=&");
int i = 0;
while(stringTokenizer.hasMoreElements()){
i++;
String str = stringTokenizer.nextToken();
if(i == 2){
System.out.println(str);
}
}
}
}
forTokens.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
Insert title here
<%--对 s内容 按照 , 进行分割 ,将分割后内容保存 e中--%>
${e }
import.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
Insert title here
AAAA
BBBB
CCCC
DDDD
${content }
EEEE
url.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
Insert title here
李春春
主页
redirect.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
// 重定向主页
// response.sendRedirect("/day08/index.jsp");
%>
1、JSP 和Servlet关系
2、JSP运行原理