说明:主要是一些练习加强对EL表达式的理解---至少有一种等价形式或两到三种
练习1:输出的比较
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %> <%@ page import="java.util.Date" %> <%@ page import="java.text.SimpleDateFormat" %> <html> <head> <title>Title</title> </head> <body> <% //方式1:输出 //需求:输出当前系统时间 //(1)创建SimpleDateFormat对象 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ; //(2)格式化日期对象 String curDate = sdf.format(new Date()) ; out.write("当前系统时间为:"+curDate) ; out.write("<br/>"); out.write("hello") ; out.write("<br/>"); request.setAttribute("curDate",curDate); //或者out.print("内容") ; %> <br/> <%--方式2输出--%> <%=curDate%> <%--方式3输出(数据必须保存在域对象中才能取出----对于多个域中相同的变量也可以指定具体的域对象获取!)--%> <br/> ${curDate} <br/> <%--等价于:从本域中取出对象的形式(这里没有跨域取数据!!!)--%> <%=pageContext.getRequest().getAttribute("curDate")%> </body> </html>
(1)初涉:对于<% Java代码%>这种形式的输出展示到浏览器是以out.write()形式的输出
(2)进阶:对于<%=%>这种形式的输出展示到浏览器只有变量在其前面定义才可以获取到,不需要把数据存储到域对象中
说明:如果这种形式想获取域中的数据怎么办?--<%=request.getAttribute("name")%>
小结:获取域中数据和获取此JSP中的数据方式不一样!
(3)终涉:${}这种形式的输出展示到浏览器数据必须存储到域对象中才能获取到,否则免谈!!!
补充:EL内置对象中没有request的内置对象,但有requestScope的内置对象(保存的是数据,而不是request本身)
引申:如果想要使用request对象的方法,必须通过pageContext.request的形式获取此对象;一般常用来获取上下文路径。
开发中:Servlet进行业务逻辑的处理,携带域对象的数据,进行请求转发到JSP,JSP从域对象中取出数据然后在前台展示!
练习2:获取域中的数据(普通字符串)
<body> <% //前提:如果要使用EL表达式去输出变量,那么这些变量必须使用域对象进行保存-->然后EL表达式从域对象中获取数据 /* 既然可以将数据保存到域对象中,然后EL表达式直接输出当前变量 EL表达式:${name}---->相当于从pageContext.getAttribute("name") ; */ String name="Hello EL"; //将当前name变量保存到其他域对象中(字母大写表示的是常量字段,代表的是相应域对象的数字) pageContext.setAttribute("name", name) ;<%-- 将数据保存到page域中,只能在此JSP页面传递--%> pageContext.setAttribute("name", name, PageContext.REQUEST_SCOPE) ;<!--将数据保存到request域中,随请求转发携带过去--> pageContext.setAttribute("name", name, PageContext.APPLICATION_SCOPE) ;<%--保存到全局域中,所有的JSP页面共享--%> pageContext.setAttribute("name", name, PageContext.SESSION_SCOPE) ;<%--保存在会话域中,浏览器和服务器的一次会话共享--%> %> <%--实用jsp的表达式 --%> <%=pageContext.getAttribute("name")%><br/><%---没有指定从哪个域对象中获取数据,会从小到大搜索!-%> EL表达式:${name} </body>
说明1:通过pageContext将数据保存到EL四大内置域的对象中。
说明2:对于保存在域中的数据,EL直接拿来使用!
补充(大小写的问题):pageContext是PageContext类的实例
思考:底层是是通过findAttribute()来寻找的,回头补充!
练习3:获取普通字符串、对象中的数据、数组中的数据(对象)、单列集合、双列集合、嵌套
(1)普通对象(一般是JavaBean)中的数据
<body> <% //(1)创建一个Student对象 User user = new User(); user.setUsername("Tony"); user.setPassword("123456"); //(2)将user对象存储到page域对象中(默认指定,不需要自己再指定范围) pageContext.setAttribute("student", user) ; %> <br/> <!--EL表达式获取对象中的数据--> <!--等价形式:page域对象.getParmater("student")得到对象--> ${student}<br/> ${student.username}----${student.password } <hr/> </body>
(2)数组中的对象
<body> <% //(1)创建一个Student对象 User user1 = new User("Tony","123456"); User user2 = new User("Jane","123456"); User user3 = new User("kangkang", "wzj110"); //(2)创建一个数组保存数据 User[] users = new User[3]; users[0]=user1; users[1]=user2; users[2]=user3; //(3)将users对象存储到page域对象中(默认指定,不需要自己再指定范围) pageContext.setAttribute("users",users); %> <br/> <!--EL表达式获取数组对象中的数据--> <!--等价形式:page域对象.getParmater("student")得到对象--> ${users[0].username}---${users[0].password}<br> ${users[1].username}---${users[1].password}<br> ${users[2].username}---${users[2].password}<br> <hr/> </body>
说明:数组与索引挂着钩,所以必须通过索引才能进一步获取里面存储的对象(数据),一层一层拨开你的心!
(3)单列集合
<body> <% //(1)创建一个Student对象 User user1 = new User("Tony","123456"); User user2 = new User("Jane","123456"); User user3 = new User("kangkang", "wzj110"); //(2)创建一个数组保存数据 ArrayList<User> users = new ArrayList<>(); users.add(user1); users.add(user2); users.add(user3); //(3)将users对象存储到page域对象中(默认指定,不需要自己再指定范围) pageContext.setAttribute("users",users); %> <br/> <!--EL表达式获取数组对象中的数据--> <!--等价形式:page域对象.getParmater("student")得到对象--> ${users[0].username}---${users[0].password}<br> ${users[1].username}---${users[1].password}<br> ${users[2].username}---${users[2].password}<br> <hr/> </body>
说明:与数组对象的获取方式一致,唯一区别就是一个是定容,一个可以自动扩容!
(4)双列集合
<body> <% //(1)创建一个Student对象 User user1 = new User("Tony","123456"); User user2 = new User("Jane","123456"); User user3 = new User("kangkang", "wzj110"); //(2)创建一个HashMap集合保存数据(每个学生加上编号!) HashMap<String, User> map = new HashMap<>(); map.put("s001",user1); map.put("s002",user1); map.put("s003",user1); //(3)将users对象存储到page域对象中(默认指定,不需要自己再指定范围) pageContext.setAttribute("map",map); %> <br/> <!--EL表达式获取数组对象中的数据--> <!--方式1:通过键获取对应的值--> ${map['s001'].username } - ${map['s001'].password }<br/> ${map['s002'].username } - ${map['s002'].password }<br/> ${map['s003'].username } - ${map['s003'].password } <hr/> <!--方式2:通过".键"的方式获取值--> ${map.s001.username } - ${map.s002.password }<br/> </body>
原理:获取的map对象是键值对的集合,map有一个方法:get("key")--->String value--->getUsername() 、getPassword()
小结:获取复杂数据
(1)获取数组中的数据
${域中的名称[index]}
(2)获取list中的数据
${域中的名称[index]}
(3)获取map中的数据
${域中的名称.键名}
练习4:判断一个对象是否为空
回顾:EL表达式支持的运算符(运算符的目的也是计算结果的)
(1)算术运算符---加减乘除(2)比较运算符---大于、小于、不等于、大于等于之类的
(3)逻辑运算符---支持"双与"或"双或"或非
(4)重要: 判空条件( 做一些逻辑处理 )
1)空值 ==null---${name==null}
2)空字符串 ==""-----${name==“”}
(5)判空条件的等价形式(empty)
${empty 获取的变量}--------等价于${name==“”}&&${name==null}----说明:是空字符串或null值返回的都是true
补充:null值对于容器的一种等价说法------判断一个容器的长度为0!
注意:结果出现"null"(null的字符串的形式)的形式
代码:
<body> <% ArrayList<Object> list = new ArrayList<>(); pageContext.setAttribute("list",list); String name=""; %> ${empty list}<br> <!--true--> ${empty name} <!--true--> </body>
补充:利用传统的<%=%>来获取传递的域中的数据,但是如果获取不到就会以null值展示(用户体验不好),因此可以利用三元运算符来替代,如果为null就给予一个空串来解决;但是代码太多也不方便,利用EL表达式获取,如果没有获取到直接以""空串展示了