EL
简介:
EL:全称Expression Language(表达式语言),是用来代替jsp页面中的java代码的一种语言。
为什么要有EL,传统的jsp页面有以下的弊端:
- 代码杂乱
- 要处理null
- 使用getAttribute时要进行频繁的类型转换
因为现在互联网前后端分离已经成为大势所趋,因此EL和JSTL其实对于后端程序员来说只需要了解即可,废话不多说,直接上代码。
先定义两个实体类,因为后面要使用它们的属性
package com.el_jstl.entity;
// 实体类
public class Address {
// 属性
private String id;
private String city;
// 构造器
public Address() {
}
public Address(String id, String city) {
this.id = id;
this.city = city;
}
// setter and getter
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
package com.el_jstl.entity;
// 实体类
public class UserBean {
// 属性
private String id;
private Address add;
// 构造器
public UserBean() {
}
public UserBean(String id, Address add) {
this.id = id;
this.add = add;
}
// setter and getter
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Address getAdd() {
return add;
}
public void setAdd(Address add) {
this.add = add;
}
}
后台servlet
package com.el_jstl.servlet;
import com.el_jstl.entity.Address;
import com.el_jstl.entity.UserBean;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* EL表达式语言
*/
@WebServlet("/ELServlet")
public class ELServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 创建UserBean对象
UserBean userBean = new UserBean();
// 给UserBean属性赋值
Address add = new Address();
add.setId("8312000");
add.setCity("西安");
userBean.setId("110");
userBean.setAdd(add);
// 创建数组
String[] arr = new String[]{"亚瑟","王昭君","刘邦"};
// 创建map
Map<String, String> map = new HashMap<>();
// map存值
map.put("userName","张三");
// 将上述对象放入request作用域中,跳转到前台
request.setAttribute("userBean",userBean);
request.setAttribute("arr",arr);
request.setAttribute("map",map);
request.getRequestDispatcher("el.jsp").forward(request,response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request,response);
}
}
前台EL
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL表达式</title>
</head>
<body>
<%--
EL表达式语言:
1."."运算符和"[""]"运算符
作用:访问对象属性,可以联级使用
格式:${作用域.对象.属性.属性}
${作用域.对象["属性"]["属性"]}
2.两者的区别:
[]运算符功能更加强大,当属性值中含有特殊符号"."、"_"时就只能使用[""]
--%>
<%--获取UserBean对象属性,使用"."--%>
${requestScope.userBean.id}<br/>
${requestScope.userBean.add.id}<br/>
<%--获取UserBean对象属性,使用[""]--%>
${requestScope["userBean"]["id"]}<br/>
${requestScope["userBean"]["add"]["city"]}<br/>
<%--
传统jsp代码弊端:
-代码杂乱
-要处理null
-获取attribute属性需要强制类型转换
EL表达式
-代码简单且与html代码不会产生杂乱现象
-不用处理null,当EL表达式是null时,输出为空("")
--%>
<%
String s1;
String s2 = "";
%>
结果为空字符串:${pageScope.s1}<br/>
<%---当EL表达式中的变量是未定义变量时,不会产生空指针异常而是空字符串 --%>
结果为空字符串:${pageScope.Xxx}<br/>
<%--empty,用于判断是否为空,如表达式为null或空字符串时,empty值为ture--%>
empty:${empty pageScope.s1}<br/>
empty:${empty pageScope.s2}<br/>
<%--使用[""]可以访问数组元素,而"."不可以访问数组--%>
${requestScope.arr[0]}<br/>
${requestScope.arr[1]}<br/>
${requestScope.arr[2]}<br/>
<%--使用[]可以获取map集合键值对--%>
${requestScope.map["userName"]}<br/>
<%--
EL隐式对象:
-page
-requset
-session
-appliction
当EL表达式不指定XxxScope时,默认寻找范围是page<request<session<appliction,当所有作用域中都不存在指定属性时返回空字符串
--%>
不存在属性:${Xxx}<br/>
<%--使用param和paramValue可以获取通过表单(param.jsp)或是超链接请求参数--%>
表单uname属性:${param.uname}<br/>
表单uage属性:${param.uage}<br/>
表单uhobbies属性(属性数组):${paramValues.uhobbies[0]}<br/>
表单uhobbies属性(属性数组):${paramValues.uhobbies[1]}<br/>
表单uhobbies属性(属性数组):${paramValues.uhobbies[2]}<br/>
<%--
EL隐式对象pageContext
-jsp可以通过pageContext对象获取其它jsp隐士对象
例如获取request对象使用:pageContext.getRequest()
-EL使用pageContext对象也可以获取jsp内置对象
语法:${pageContext.jsp内置对象名}
例如获取request对象使用:${pageContext.request}
--%>
</body>
</html>
JSTL
JSTL标签库是sun公司推出的(sun牛逼),它比EL表达式语言更加强大。要使用JSTL标签库需要两个jar包,可以去apache官网,更推荐去maven库下载,这两个jar分别为jstl-1.2.jar和standard-1.1.2.jar
并在jsp页面元素中引入标签库,使用:
<!--使用JSTL核心标签库首先要引入jar包 -->
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
直接上代码
后台servlet
package com.el_jstl.servlet;
import com.el_jstl.entity.Address;
import com.el_jstl.entity.UserBean;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* JSTL标签
*/
@WebServlet("/JSTLServlet")
public class JSTLServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 创建UserBean对象
UserBean userBean = new UserBean();
// 给UserBean属性赋值
Address add = new Address();
add.setId("8312000");
add.setCity("西安");
userBean.setId("110");
userBean.setAdd(add);
// 创建数组
String[] arr = new String[]{"亚瑟","王昭君","刘邦"};
// 创建map
Map<String, String> map = new HashMap<>();
// map存值
map.put("userName","张三");
// 将上述对象放入request作用域中,跳转到前台
request.setAttribute("userBean",userBean);
request.setAttribute("arr",arr);
request.setAttribute("map",map);
request.getRequestDispatcher("jstl.jsp").forward(request,response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request,response);
}
}
前台JSTL
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!--使用JSTL核心标签库首先要引入jar包 -->
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>JSTL标签</title>
</head>
<body>
<%--
c:set标签:
用法一:设置域对象属性
<c:set var="varName" value="value" scope={"page","requset","session","appliction"}></c:set>
其中var代表变量名,value代表要设置的变量值,scope代表设置作用域范围
特别的,使用<c:set>标签可以设置不存在的变量(相当于定义一个变量并初始化)
--%>
<%--设置request作用域对象(UserBean)的id属性--%>
<%
String s;
%>
设置域对象属性:<c:set var="s" value="xiaoqiang" scope="request"></c:set><br/>
${s}<br/>
设置域对象属性,注意与上面的区别,上面是变量,这个是对象的属性:<c:set target="${requestScope.userBean.add}" property="id" value="832000"></c:set><br/>
<%--
再次对上面进行讲解,这个极易出错,很多人给对象属性赋值时采用第一种方式,这是错误的,target属性必须使用EL表达式且必须联级到设置属性的前一级,因为property属性必须为一级,不能是联级的
--%>
${requestScope.userBean.add.id}<br/>
<%--
用法二:设置map集合或者JavaBean属性
<c:set value="value" target="target" property="propertyName"></c:set>
其中value代表要设置属性的值,target代表要设置属性的对象(map集合或是JavaBean对象),property代表要设置对象的属性名称(map集合即为key的名称)
--%>
设置map的userName属性:<c:set target="${map}" value="李四" property="userName"></c:set><br/>
${requestScope.map.userName}<br/>
<%--c:out标签:输出功能,不推荐使用,没有EL表达式方便--%>
<%--
c:remove:删除指定属性
格式:<c:remove var="varName" scope={"request",...}></c:remove>
--%>
删除s变量:<c:remove var="s" scope="request"></c:remove><br/>
${s}<br/>
<%--
c:if标签
格式:<c:if test="condition" var="varName" scpoe={"request".....}>
为true时执行代码.....
</c:if>
其中test属性值为真假条件,当test属性表达式为true时执行标签内部代码,注意test中是EL表达式而不是简单的表达式
--%>
<c:if test="${3<5}">
${requestScope.map.userName}<br/>
</c:if>
<%--
c:forEach:遍历集合或数组
格式:<c:forEach var="name" items="数组、集合名" begin="begin" end="end" step="step">
标签体内容
</c:forEach>
举例:String[] s = new String[]{...};
for(String ele : s)
其中c:forEach中的var就相当于foreach中的ele,items就相当于s,begin开始下标(适用于有索引下标的),end结束下标(适用于有索引下标的),step步长
--%>
循坏遍历:<c:forEach var="array" items="${requestScope.arr}"><br/>
${array}<br/>
</c:forEach>
</body>
</html>