JavaWeb-EL表达式、JSTL标签

目录

1 EL表达式概述

2 JSTL标签

3 改造oa项目


1 EL表达式概述

EL表达式作用:

  • EL表达式可以代替JSP中的java代码,让JSP文件中的程序看起来更加美观和整洁。
  • JSP夹杂着各种java代码,例如<%java代码%>,等等,导致JSP混乱后期不好维护
  • EL表达式算是JSP语法的一部分,EL表达式归属于JSP
  • EL表达式出现在JSP中主要是:从某个域中取数据,然后转换成字符串,然后输出到浏览器,这就是EL表达式的三大功效

EL表达式三大功效:

  • 第一功效:从某个域中取数据,四个域:pageContext;request;session;application
  • 第二功效:将取出的数据转成字符串,会自动调用java对象的toString方法转为字符串
  • 第三功效:将字符串输出到浏览器,这个这个一样:<%=%>

EL表达式基本语法:

  • ${域中的name,不加双引号}
<%--向域中存数据--%>
<%request.setAttribute("username","zhangsan");%>
<%--使用java代码从域中取数据--%>
<%=request.getAttribute("username")%>
<%--使用EL表达式取数据--%>
${username}

以上代码我们可以发现使用EL表达式和java代码作用一样但表达更方便简洁

<%
    //创建一个对象
    User user = new User("jack","123",30);
    //存取域中
    request.setAttribute("userObj",user);
%>
<%--使用EL表达式取出user数据--%>
${userObj}
<br>
<%--如果想输出对象的属性值,怎么办--%>
${userObj.username}<br>
${userObj.password}<br>
${userObj.age}<br>
${userObj.email}<br>

通过上方代码我们发现,不仅可以使用域的name输出,还可以输出属性值,不过需要注意的是:输出属性值的前提是必须要有get方法,底层调用的就是get方法,但不一定需要这个属性,就像上面的调用的email一样,我只是写了getEmail方法,并没有定义这个属性,但依然可以正常执行。但如果没有get方法就会出500错误。但经过测试我们发现,get方法不遵守驼峰命名也是可以正常访问的,但是你不遵守驼峰命名你还是java攻城狮吗???

那么问题来了,一共有四个域,假如四个域有相同的name,取出的是什么?

经过测试我们发现,优先取出域小的中的数据pageContext<request<session<application

但问题又来了,我就是想取出每一个域中的数据怎么办,EL表达式中有四个隐含的隐式的范围:

  • pageScope对应的是pageContext范围
  • requestScope对应的是request范围
  • sessionScope对应的是session范围
  • applicationScope对应的是application范围
${pageScope.data}<br>
${requestScope.data}<br>
${sessionScope.data}<br>
${applicationScope.data}<br>

假如我name写错了会怎样:

<%
    request.setAttribute("username","jack");
%>

<%=request.getAttribute("username")%>
${username}
<br>
java代码写错name:<%=request.getAttribute("usernam")%>
EL表达式写错name:${usernam}

我们发现EL表达式写错什么都不会输出,而java代码写错会输出null,EL表达式实际上运行的时候还是要翻译成java代码的:

<%=request.getAttribute("username") == null ? "":request.getAttribute("username")%>

EL表达式还有一种写法:${requestScope["name"]}

这种写法什么时候用呢,比如某些人闲的没事将name其名为“user.name”,这时使用传统的“.”就会出错,将它放在中括号里的分号里避免出错,不过这种事情一般不会发生,所以基本上都是传统方法。

EL表达式获取Map集合中的元素:通过key来获取

    //map集合
    Map<String,String> map = new HashMap<>();
    map.put("username","马邦德");
    map.put("password","123456");
    request.setAttribute("map",map);

    User user = new User();
    user.setUsername("张麻子");
    Map<String, User> userMap = new HashMap<>();
    userMap.put("user",user);
    request.setAttribute("userMap",userMap);
<%--取出Map集合数据--%>
${map.username}<br>
${userMap.user}<br>
${userMap.user.username}<br>

EL表达式获取数组中的元素:通过下标获取,注意下标溢出就不输出任何东西

    //数组
    String[] s = {"jack","rose","xiaoli"};
    request.setAttribute("s",s);
<%--取出数组的数据--%>
${s}<br>
${s[0]}<br>
${s[1]}<br>
${s[2]}<br>
${s[10]}<br>

EL表达式获取list集合中的元素:可通过下标获取,和数组类似

    //list集合
    List<String> list = new ArrayList<>();
    list.add("拟好");
    list.add("王德发");
    request.setAttribute("list",list);
<%--取出list集合数据--%>
${list}<br>
${list[0]}<br>
${list[1]}<br>
${list[10]}<br>

page指令有个属性可以使EL表达式失效<%@page isELIgnored="false" %>,true为失效,false为不失效,假如只想某一个失效可以在EL表达式前面加上一个斜杠——“\”

通过EL表达式获取应用的根:${pageContext.request.contextPath},为什么不直接使用request来获取,因为EL表达式中没有request这个对象。

EL表达式其它隐式对象:

  • param
  • paramValues
  • initParam

param可以代替request.getParameter("username")取出前端数据,格式为:${param.username}但这只能取出一个数据,也就是说当数据有多个只能取出第一个数据。paramValues可以解决这个问题,格式为:{paramValues.username[0]},但是目前也只能根据下标一次取一个。initParam可以代替application.getInitParameter("pageSize")取出应用域数据,格式为${initParam.pageSize}应用域的数据在web.xml文件存储方式如下:

    <!--servlet上下文初始化参数-->
    <context-param>
        <param-name>pageSize</param-name>
        <param-value>20</param-value>
    </context-param>

关于EL表达式的运算符

  • “+”:只能运算数字,不能连接字符串,连接字符串就会报错
  • “==”:会自动调用equal方法,比较的就是你长得样子,而不是内存地址
  • “eq”:作用与“==”一样
  • “!、not”:取反
  • “empty”:判断是否为空,如果是空就返回true

了解一下EL表达式运算符即可,EL表达式重点在于输出内容

2 JSTL标签

什么是JSTL标签库?

  • Java Standard Tag Lib(Java标准的标签库)
  • JSTL标签库通常结合EL表达式一起使用,目的是让JSP中的java代码消失。
  • 标签是在JSP中写的,但实际上最终还是要执行对应的java程序(java程序在jar包中)

使用JSTL标签库的步骤:

第一步:引入JSTL标签库对应的jar包:

  • jakarta.servlet.jsp.jstl-2.0.0.jar、jakarta.servlet.jsp.jstl-api-2.0.0.jar
  • 在IDEA怎么引入:在WEB——INF目录下新建lib目录,然后jar包拷贝到lib中,然后将其“Add Lib”一定要和MySQL数据库的驱动一样,都是放在那个目录。什么时候需要放到lib下呢?如果这个jar是tomcat没有的就需要。

第二步:在JSP中引入要是用的标签库(使用taglib指令引入标签库)

  • <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  • 这个是核心标签库,prefix随便起名字,一般起为c

第三步:在需要使用标签的位置使用即可,表面使用的标签,底层实际上还是java程序

JSTL标签原理:

  • <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  • 以上uri后面的路径实际上指向了一个xxx.tld文件,tld文件中描述了“标签”和“java类”之间的关系
  • 以上核心标签库对应的tld文件是:c.tld文件,它在哪:
  • 在Jakarta.servlet.jsp.jstl=2.0.0.0.jar里面META-INF目录下

源码解析如下:

    <description>
        这里是对标签的描述
    </description>
    <name>forEach</name>标签的名字
<tag-class>org.apache.taglibs.standard.tag.rt.core.ForEachTag</tag-class>标签对应的java类
    <tei-class>org.apache.taglibs.standard.tei.ForEachTEI</tei-class>
    <body-content>JSP</body-content>标签中可以出现的内容,如果是JSP,就表示标签中可以写JSP
    <attribute>
        <description>
            对这个属性的描述
        </description>
	<name>items</name>属性名
	<required>false</required>false表示属性可有可无,true表示属性必须有
	<rtexprvalue>true</rtexprvalue>true表示支持EL表达式,false不支持
	<type>java.lang.Object</type>
        <deferred-value>
	    <type>java.lang.Object</type>
        </deferred-value>
    </attribute>
    <attribute>

案例:

forEach标签:

我写一个学生类,并创建三个对象附上属性值,并放入到list集合,再将集合放到request域中,使用JSTL标签和EL表达式取出这里面的数据:

<c:forEach items="${Stulist}" var="s">
    name:${s.name},age:${s.age}<br>
</c:forEach>

上面这些代码就可以取出,其中forEach是一个标签,这个标签的作用就类似于for循环,item是这个标签的属性,这个属性里面装入集合,可以用EL表达式拿到存在域中的集合,然后var属性表示集合中的每一个元素,就类似于加强for循环中的那个元素。

<c:forEach items="${Stulist}" var="s" varStatus="stuStatus">
    编号:${stuStatus.count},name:${s.name},age:${s.age}<br>
</c:forEach>

 其中varStatus这个属性表示var的状态,这个名字可以随便起,这个对象中有count属性,可以直接用,这个属性的值是从1开始,以1递增,主要用于编号:

<c:forEach var="i" begin="1" end="10" step="1">
    ${i}、
</c:forEach>

 其中var指定循环的变量相当于for循环前的的int i,begin为开始,end为结束,step为步长,和for循环都有对应。需要注意的是:底层实际上会将i存储到pageContext域中,因为取数据使用EL表达式取得,而EL表达式取出的数据一定是域中的。

if标签:

<c:if test="${empty param.username}">
<h1>用户名不能为空</h1>
</c:if>

<c:if test="${not empty param.username}">
    ${param.username}
</c:if>

需要注意的是:if属性中的test属性必须要有,并且text属性只能是Boolean类型。

choose标签:就类似于if-else或者switch

<c:choose>
    <c:when test="${param.age < 18}">
        青少年
    </c:when>
    <c:when test="${param.age < 35}">
        青年
    </c:when>
    <c:when test="${param.age < 60}">
        中年
    </c:when>
    <c:otherwise>
        老年
    </c:otherwise>
</c:choose>

3 改造oa项目

使用EL表达式和JSTL标签继续改造oa项目

首先在jsp页面将java代码全用EL表达式和JSTL标签代替,代替也很简单,基本上就是路径的代替,list页面稍微复杂一点,需要使用JSTL标签。

还有我们发现在前端需要写不少项目的根路径,有点麻烦,有没有方便的方式:在前端HTML代码中有一个标签叫做base,这个标签可以设置整个网页的基础路径,这是HTML中的语法,通常出现在head标签中:<base href="http://localhost:8080/oa3/">,这样设置之后,在页面中凡是没有以“/”开始的,都会自动将base中的路径添加到这些路径之前。但需要注意的是:在JS代码中的路径,保险起见,最好不要依赖base标签,JS代码按之前的方法写。但这个路径是写死的,我们不喜欢写死,可以写一个动态的:

<base href="${pageContext.request.scheme}://${pageContext.request.serverName}: ${pageContext.request.serverPort}${pageContext.request.contextPath}/">

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值