JavaWeb04
一、EL表达式
1、简介
Expression Language(表达式语言)
可以代替jsp文件中的Java代码,使jsp文件更整洁美观
可以算是JSP语法的一部分,归属于JSP
三个功能:从某个作用域取数据,转换成字符串(调用toString方法),展示到浏览器
基本语法格式:${表达式}
2、简单示例
<%User user = new User();user.setUsername("bob");user.setPassword("123456");// 将user对象存储到某个域中request.setAttribute("UserObj", user);
%>// 使用EL表达式获取
// 这里实际调用了getXxxx方法
${UserObj.username}
<br>
${UserObj.password}// 或者使用中括号,里面要加双引号
${UserObj["username"]}
${UserObj} 的底层实现:从域中取数据,取出user对象,调用该对象的toString方法,输出到浏览器
3、注意事项
(1)错误处理
如果使用EL表达式时输错了名称,取不到数据,浏览器相应位置会显示空字符串,不会报错
(2)同名数据处理
如果不同的域里有同名的数据,则优先从小范围里取数据(在没有指定范围时)
EL表达式有四个隐含的范围对象,可以用来指定范围
pageScope, requestScope, sessionScope, applicationScope
使用 ${范围对象.数据名} 的格式来取指定范围内的数据
(3)从Map集合中取数据
方式:${map.key}
(4)从数组或List集合取数据
方式:${数组[下标]}
(5)忽略EL表达式
page指令的isELIgnored属性设置为true即可将EL表达式当成普通字符串
<%@page isELIgnored="true" %> 会忽略整个jsp文件的所有EL表达式
如果只想忽略某一个,可以使用反斜杠:\${data}
(6)获取request对象
requestScope这个对象只代表范围,不是request对象
在EL表达式中有一个隐式对象pageContext,和九大内置对象的pageContext是同一个
pageContext对象有getRequest方法
因此可以:${pageContext.request}
获取应用的根路径:${pageContext.request.contextPath}
4、EL表达式的隐含对象
(1)param
用于获取单个请求参数
${param.username}
等同于:
<%=request.getParameter("username")%>
(2)paramValues
如 http://localhost:8080/xmm/hello.jsp?hobby=running&hobby=swimming
使用方式示例:${paramValues.hobby[0]}
5、EL表达式的运算符
会将加号两边的变量都转成数字,转不成则抛出java.lang.NumberFormatException
注意==, eq, != 都会调用对象的equals方法来进行判断
二、JSTL标签库
1、简介
Java Standard Tag Lib(Java标准标签库)
通常和EL表达式一起使用,目的是取代jsp文件中的Java代码
2、使用步骤
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
这个就是核心标签库,prefix这里随便起名,但核心标签库一般叫做c
uri实际指向了一个xxx.tld文件,实际上是一个xml配置文件
3、tld配置文件
<tag><description>对该标签的描述</description><name>标签名称</name><tag-class>对应的Java类</tag-class><body-content>标签中可以出现的内容,如JSP</body-content><attribute>标签的属性,可以有多个<description>对该属性的描述</description><name>属性名称</name><required>是否必须,true表示必须</required><rtexprvalue>是否支持EL表达式,true表示支持</retexprvalue><type>属性值的类型</type></attribute>
</tag>
4、简单示例
<%@page contentType="text/html;charset=UTF-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%// 这一部分通常写在Servlet里Student s1 = new Student("1", "Alice");Student s2 = new Student("2", "Bobby");Student s3 = new Student("3", "Candy");List<Student> stuList = new ArrayList<>();stuList.add(s1);stuList.add(s2);stuList.add(s3);request.setAttribute("students", stuList);
%>// items表示要遍历的集合,var表示遍历到的某一项
<c:forEach items="${students}" var="ss">id: ${ss.id}, name: ${ss.name} <br>
</c:forEach>
三、Filter过滤器
1、简介
每一个Servlet类有一些公共的代码(例如判断登录状态),可以抽取出来,提高复用性
Filter可以在Servlet执行之前过滤,也可以在Servlet执行之后过滤,请求和响应都会经过过滤器
Servlet是和用户的请求路径对应的,Filter也是和用户的请求路径对应的,过滤器可以有多层
如果有多层过滤器,这里用到了责任链设计模式(过滤器的调用顺序写在配置文件中)
2、编写步骤
(1)编写一个类实现jakarta.servlet.Filter接口,并实现这个接口中的所有方法
init() 方法:在Filter对象被创建后调用,只调用一次
doFilter() 方法:用户每发送一次请求就调用一次,在这个方法中编写过滤规则
要在doFilter方法中,调用chain.doFilter(),表示执行下一个过滤器,没有下一个则执行Servlet
destroy() 方法:在Filter对象被销毁前调用,只调用一次
默认情况下,服务器启动时会直接创建Filter对象,且Filter对象是单实例的
Filter的生命周期和Servlet对象的生命周期一致
(2)在web.xml文件中对Filter对象进行配置
与Servlet的配置十分类似
也可以使用 @WebFilter 注解,在自己编写的Filter类上
<filter><filter-name></filter-name><filter-class></filter-class>
</filter>
<filter-mapping><filter-name><filter-name><url-pattern><!--可以有多个--></url-pattern>
</filter-mapping>
如果有多个Filter对象
则这些Filter的执行顺序取决于filter-mapping标签的位置,越靠上越先执行
如果用的是注解,则Filter类的执行顺序取决于类名的字典序
3、示例代码
校验用户是否已经登录
@WebFilter("/*")
public class LoginCheckFIlter implements Filter {@overridepublic void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response = (HttpServletResponse) resp;HttpSession session = request.getSession(false);String servletPath = request.getServletPath(); // 获取请求路径boolean haveLogin = (session != null && session.getAttribute("username") != null);boolean goToLogin = ("/user/login".equals(servletPath));boolean goToWelcome = ("/welcome".equals(servletPath));boolean goToIndex = ("/index.jsp".equals(servletPath));if (haveLogin || goToLogin || goToWelcome || goToIndex) {chain.doFilter(request, response); } else {response.sendRedirect(request.getContextPath); } }
}