问题:
按照前面文章中提到的代码实现方式,如果用户登录失败,我们不用再单独书写一个LoginErrorServlet,直接新创键一个login.jsp页面即可。
但是我们先访问login.html,然后错误在跳转到login.jsp页面,那么我们是否可以直接访问login.jsp页面,而不用再使用login.html页面。这样更为简单。
在浏览器中直接访问login.jsp页面:
我们发现最开始访问jsp页面,页面显示null,原因是最开始访问request中的msg没有任何数据,所以是null。那么有的同学就会想在login.jsp页面中使用java代码对request中的msg进行判断。虽然可以实现,但是脚本表达式在JSP页面上书写起来比较麻烦。而在页面上取值在开发中使用的又比较多,所以Sun公司为了简化在页面上的取值操作。我们这里有更为简单的方案,就是我们下面要讲解的EL表达式。
【需求】使用EL表达式改造login.jsp页面的取值操作
提示:EL表达式从request域对象中取值:${request域对象中的key}
温馨提示:
原来JSP页面中的脚本表达式<%=msg%>被EL表达式取代。
【代码示例】login.jsp
xml复制代码<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>登录页面</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/login.css" rel="stylesheet">
<script src="js/jquery.js"></script>
<script src="js/bootstrap.js"></script>
</head>
<body>
<%
// String msg = (String) request.getAttribute("msg");
%>
<div class="container text-center">
<form class="form-signin" action="/loginInterServlet" method="get">
<h2 class="form-signin-heading">登录页面</h2>
<%--<font color="red"><%=msg%></font>--%>
<font color="red">${msg}</font>
<input type="text" name="username" class="form-control" placeholder="用户名" required autofocus>
<input type="password" name="password" class="form-control" placeholder="密码" required>
<button class="btn btn-lg btn-primary btn-block" type="submit">登录</button>
</form>
</div>
</body>
</html>
说明:
1)在jsp页面中使用EL表达式可以简化Java代码。
2)EL表达式从域对象取值,如果域对象中有值则获取,没有值则不获取。
bash复制代码EL全称: Expression Language 中文的意思是EL表达式。
作用:代替jsp中脚本表达式<%=输出内容%>的功能,简化对java代码的操作,从【域对象】中取值。 EL表达式简化<%= %>方式取值
EL语法表达式的格式:${域对象中的key}
JSP的四大域对象指的是:page域,request域,session域,application域。我们通常使用EL表达式从这4个域对象中取值。以下是这4个域对象的详细信息:
域对象 | 在EL中的对象名称 | 在servlet中的对象名 | 说明 |
page域 | pageScope | pageContext,属于javax.servlet.jsp.PageContext类的对象 | page域指的是当前JSP页面,其中存储的数据只在当前页面有效,因为jsp本质是servlet,所以page域只在一个servlet中有效。 |
request域 | requestScope | request,属于javax.servlet.http.HttpServletRequest接口的对象 | request域:一次请求或请求链中request域 |
session域 | sessionScope | session,属于javax.servlet.http.HttpSession接口的对象 | session域:一次会话过程中,session域 |
application域 | applicationScope | application,属于javax.servlet.ServletContext接口的对象 | application域:服务启动后整个项目对应的ServletContext域 |
EL表达式从指定的域中取值的方式如下:
域对象 | 取值方式 |
page域 | ${pageScope.key} |
request域 | ${requestScope.key} |
session域 | ${sessionScope.key} |
application域 | ${applicationScope.key} |
【需求】
【参考代码】
bash复制代码<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
EL表达式 page request session application 四大域对象
【需求】
1. 在一个JSP页面中,使用脚本表达式分别向page域、request域,session域,application域和中存储数据;
2. 使用EL表达式从这4个域中取值;
--%>
<%
//page域,对一servlet中的pageContext对象
pageContext.setAttribute("pageValue","page的值");
//request域
request.setAttribute("requestValue","request的值");
//session域
request.getSession().setAttribute("sessionValue","session的值");
//application域,属于ServletContext类的对象
application.setAttribute("applicationValue","application的值");
%>
<%--
EL表达式来域对象中取值
--%>
page中取值:${pageScope.pageValue}<br>
request中取值:${requestScope.requestValue}<br>
session中取值${sessionScope.sessionValue}<br>
application中取值${applicationScope.applicationValue}<br>
</body>
</html>
EL表达式取值的时候也可以不指定域,如果取值的时候不指定域对象。就会按照从page域--->request域--->session域--->application域从小到大逐级根据key值查找。
bash复制代码<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
EL表达式 page request session application 四大域对象
【需求】
1. 在一个JSP页面中,使用脚本表达式分别向page域、request域,session域,application域和中存储数据;
2. 使用EL表达式从这4个域中取值;
--%>
<%
//page域,对一servlet中的pageContext对象
pageContext.setAttribute("pageValue","page的值");
//request域
request.setAttribute("requestValue","request的值");
//session域
request.getSession().setAttribute("sessionValue","session的值");
//application域,属于ServletContext类的对象
application.setAttribute("applicationValue","application的值");
//向域对象中存储值,key值一样,则先从小向大的域中查找
pageContext.setAttribute("value","page的值");
request.setAttribute("value","requst的值");
%>
<%--
EL表达式来域对象中取值
--%>
page中取值:${pageScope.pageValue}<br>
request中取值:${requestScope.requestValue}<br>
session中取值${sessionScope.sessionValue}<br>
application中取值${applicationScope.applicationValue}<br>
相同的key:${value}
</body>
</html>
之前我们在学习cookie的时候,做过记住用户名和密码的案例,但是前端页面我们并没有实现。因为我们还没有学习使用什么技术在前端如何将cookie中的数据取出,而今天我们学习了EL表达式,我们就可以实现前端记住用户名和密码的案例了。
new Cookie(name,value)
使用EL表达式获取cookie中的值格式:(掌握)
ini复制代码cookie.cookie的name名.value
例如:
Cookie cookieName = new Cookie("username","锁哥");
cookie.username.value获取的值是锁哥。
创建一个登陆的jsp页面:
xml复制代码<%--
Created by IntelliJ IDEA.
Time: 16:52
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/login2Servlet">
<input name="username" type="text" placeholder="请输入账号"><br>
<input name="password" type="password" placeholder="请输入密码"><br>
<input type="submit" value="登录">
<br>
<input type="checkbox" name="ck" class="checkbox">记住用户名和密码
</form>
</body>
</html>
xml复制代码<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/loginServlet" method="post">
<%--
${cookie.username.value} 表示从浏览器存储的cookie中获取值
cookie表示对象名
username 表示cookie中的名,看服务器端给的什么名字,这里就写什么名字,不固定。可以理解为key
value属于固定属性。表示获取值
--%>
用户名:<input type="text" name="username" value="${cookie.username.value}"><br>
密码:<input type="password" name="password" value="${cookie.password.value}"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
在servlet生成cookie LoginServlet.java
scala复制代码@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
//创建cookie
Cookie cookieName = new Cookie("username",username);
Cookie cookiePsw = new Cookie("password",password);
response.addCookie(cookieName);
response.addCookie(cookiePsw);
}
}
温馨提示:要去访问Java代码LoginServlet,才能将cookie存储到浏览器中
效果图:
先访问:http://localhost:8080/login.jsp也面,点击登录按钮,访问了LoginServlet,在LoginServlet中 生成cookie。
再访问login.jsp页面,使用EL表达式获取用户名和密码
http://localhost:8080/login.jsp
EL表达式获取到值之后可以直接通过运算符进行运算。EL表达式的运算符主要有以下几类:算术运算,关系运算,逻辑运算,三元运算,empty运算符。
【素材】页面数据准备demo08.jsp
vbscript复制代码<%
request.setAttribute("n1",40);
request.setAttribute("n2",30);
request.setAttribute("n3","20");
request.setAttribute("n4","10");
%>
顾名思义,算术运算是进行算术运算的符号,和java中的一致。主要包括:加,减,乘,除,取余。具体使用如下表:
运算符 | 说明 | 使用示例 | 结果 |
+ | 加 | ${n1+n2} | 70 |
- | 减 | ${n1-n2} | 10 |
* | 乘 | ${n1*n2} | 1200 |
/或div | 除 | ${n1/n4} | 4 |
%或mod | 取余 | ${n1%n4} | 0 |
【代码示例】demo08.jsp代码片段
xml复制代码算数运算:<br>
n1+n2:${n1 + n2}<br>
n1-n3:${n1 - n3}<br>
n3-n4:${n3-n4}<br>
n2*n3:${n2 * n3}<br>
效果图:
注意:在进行算术运算的时候,EL表达式会对字符串中的内容进行判断,如果都是数值,那么会转化为数值再进行算术运算,如果含有非数字类型,则会报异常。
vbscript复制代码<%
request.setAttribute("n1",40);
request.setAttribute("n2",30);
request.setAttribute("n3","20");
request.setAttribute("n4","10");
%>
关系运算符是判断两个数据的大小关系的,关系运算符有:==,!=,<,<=,>,>=。具体使用方法如下:
运算符 | 说明 | 使用示例 | 结果 |
== 或 eq | 等于 equal | ${n1 == n2} | false |
!= 或ne | 不等于 not equal | ${n1 != n2} | true |
> 或 gt | 大于 greater than | ${n1 > n2} | true |
>= 或ge | 大于等于 greater than or equal | ${n1 >= n2} | true |
< 或 lt | 小于 less than | ${n1 < n2} | false |
<= 或le | 小于等于 less than or equal | ${n1 <= n2} | false |
【代码示例】demo08.jsp
xml复制代码关系运算符:<br>
n1==n2:${n1==n2}<br>
n3>=n4:${n3>=n4}<br>
n1!=n2:${n1 ne n2}<br>
效果:
逻辑运算符包括:&& ,||,! 使用方法如下:
运算符 | 说明 | 使用示例 | 结果 | ||
&& 或 and | 逻辑与,一假即假 | ${true && false} | false | ||
或 or | 逻辑或,一真即真 | `${true | false}` | true | |
! 或 not | 非,取反 | ${!false} | true |
参考代码demo08.jsp
arduino复制代码逻辑运算符:<br>
false && true:${false && true}<br>
false || true:${false || true}<br>
!false:${!false}<br>
EL表达式也支持三元运算符:如,判断n1是否大于等于n2,可以写成如下:参考代码demo08.jsp
lua复制代码<%--
表达式1?表达式2:表达式3
--%>
三元运算符:<br>
${n1>=n2?"正确":"错误!"}<br>
empty运算符表示判断数据是否为空,如果为空返回true。对以下数据运算返回true:
【代码示例】 demo08.jsp
vbscript复制代码<%
String str = "";
request.setAttribute("str",str);
Student student=null;
request.setAttribute("student",student);
List<String> list = new ArrayList<>();
request.setAttribute("list",list);
%>
empty:<br>
${empty str}<br>
${empty student}<br>
<%--
not empty list :表示对empty的结果取反,由于list.size()等于0,所以empty list的结果是true,
但是这里加了一个not,结果变为了false
--%>
${not empty list}<br>
页面效果:
demo08.jsp完整代码
ruby复制代码<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page import="com.ithea.sh.el.cookie_01.Student" %><%--
Created by IntelliJ IDEA.
Time: 8:59
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>运算符</title>
</head>
<body>
<%
//向request域对象中存储数据
request.setAttribute("n1",40);
request.setAttribute("n2",30);
request.setAttribute("n3","20");
request.setAttribute("n4","10");
%>
算数运算:<br>
n1+n2:${n1 + n2}<br>
n1-n3:${n1 - n3}<br>
n3-n4:${n3-n4}<br>
n2*n3:${n2 * n3}<br>
关系运算符:<br>
n1==n2:${n1==n2}<br>
n3>=n4:${n3>=n4}<br>
n1!=n2:${n1 ne n2}<br>
逻辑运算符:<br>
false && true:${false && true}<br>
false || true:${false || true}<br>
!false:${!false}<br>
<%--
表达式1?表达式2:表达式3
--%>
三元运算符:<br>
${n1>=n2?"正确":"错误!"}<br>
<%
String str = "";
Student student=null;
List<String> list = new ArrayList<>();
%>
empty:<br>
${empty str}<br>
${empty student}<br>
<%--
not empty list :表示对empty的结果取反,由于list.size()等于0,所以empty list的结果是true,
但是这里加了一个not,结果变为了false
--%>
${not empty list}<br>
</body>
</html>
效果图:
【注】not empty可以用在EL表达式中,判断非空的情况。
EL表达式小结:
作者:also_lucky
链接:https://juejin.cn/post/7241760513205059639
L表达式
JSTL标签
EL(Expression Language)表达式语言
EL的作用是简化JSP的开发,让我们更方便的进行数据的读取(从application、session、request、pageContext)
语法:
${表达式}
如:读取session中的name属性
Java脚本输出:
<%= session.getAttribute("name")%>
EL:
${name}
读取对象属性的方法:
Java脚本:
<%= user.getName()%>
EL:
${user.name} 或
${user["name"]}
问题:如果在JSP的application、session、request、pageContext对象中都保存了num参数
那么EL表达式${num}会读取哪个num呢?
EL表达式的查找顺序是从最小范围开始找:
pageContext -> request -> session -> application -> null
域对象:可以指定读取数据的范围
域对象 对应的JSP对象
pageScope pageContext
requestScope request
sessionScope session
applicationScope application
${域对象.表达式}
如:
读取页面中的num参数:
${pageScope.num}
JSTL(Java Standard Tag Library)Java标准标签库
作用是将JSP中的Java脚本和HTML代码分开,将Java封装到标签中,在页面调用。
使用方法:
1、导入jar包
2、在JSP页面中加入taglib指令
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
3、使用标签
<c:标签名 属性=”值">
核心标签的使用:
输出标签
<c:out value=“输出内容”></c:out>
赋值标签
<c:set var="变量名" value=“值”></c:set>
示例:
<c:set var="num" value="999"></c:set>
<c:out value="num=${num}"></c:out>
删除变量标签
<c:remove var="变量名">
异常处理标签
<c:catch var="ex">
可能有异常出现的内容
</c:catch>
示例:
<c:catch var="ex">
<%int n = 6 / 0; %>
</c:catch>
<br>
<c:if test="${ex != null}">
<h3>异常:${ex}</h3>
</c:if>
if标签
<c:if test="EL表达式">
HTML代码
</c:if>
示例:
<c:if test="${num > 500}">
<h3>${num }大于500</h3>
</c:if>
choose标签
多重判断
<c:choose>
<c:when test="${条件}">
HTML代码
</c:when>
<c:when test="${条件}">
HTML代码
</c:when>
...
<c:otherwise>
HTML代码
</c:otherwise>
</c:choose>
示例:
<c:choose>
<c:when test="${score>=90 }">
${score }属于A级
</c:when>
<c:when test="${score>=80 }">
${score }属于B级
</c:when>
<c:when test="${score>=70 }">
${score }属于C级
</c:when>
<c:when test="${score>=60 }">
${score }属于D级
</c:when>
<c:otherwise>
${score }属于E级
</c:otherwise>
</c:choose>
forEach标签
实现循环的标签
用法1:
<c:forEach var="循环变量" begin="初始值" end="结束值" step="增长量">
HTML代码
</c:forEach>
示例:
<c:forEach var="i" begin="1" end="10" step="1">
<p style="font-size:${i + 10}px">这是段落${i}</p>
</c:forEach>
用法2:
<c:forEach var="循环变量" items="${集合或数组名}">
HTML代码
</c:forEach>
示例:
<c:forEach var="user" items="${users}">
<p>${user.name } - ${user.age }</p>
</c:forEach>
总结:本章我们学习了JSP开发的两个强大工具,EL表达式让我们能用简洁的语法读取JSP对象中的值;而JSTL标签库让HTML代码和Java代码实现了分离,从而提高了JSP代码的可维护性,也让JSP开发变得更加简单。
、VueJS生命周期
1.1 每个 Vue 实例在被创建之前都要经过一系列的初始化过程
vue在生命周期中有这些状态,created,beforeMount,mounted,beforeUpdate,updated,beforeDestroy,destroyed。Vue 在实例化的过程中,会调用这些生命周期的钩子,给我们提供了执行自定义逻辑的机会。
1.2 vue对象初始化过程中会执行到钩子的内容:
beforeCreate :数据还没有监听,没有绑定到vue对象实例,同时也没有挂载对象
created :数据已经绑定到了对象实例,但是还没有挂载对象
beforeMount:模板已经编译好了,根据数据和模板已经生成了对应的元素对象,将数据对象关联到了对象的 el属性,el属性是一个HTMLElement对象,也就是这个阶段,vue实例通过原生的createElement等方法来创 建这个html片段,准备注入到我们vue实例指明的el属性所对应的挂载点
mounted:将el的内容挂载到了el,相当于我们在jquery执行了(el).html(el),生成页面上真正的dom,上面我们就会发现dom的元素和我们el的元素是一致的。在此之后,我们能够用方法来获取到el元素下的dom对象,并进行各种操作,当我们的data发生改变时,会调用beforeUpdate和updated方法
beforeUpdate :数据更新到dom之前,我们可以看到$el对象已经修改,但是我们页面上dom的数据还没有发生改变
updated:dom结构会通过虚拟dom的原则,找到需要更新页面dom结构的最小路径,将改变更新到 dom上面,完成更新
beforeDestroy,destroed:实例的销毁,vue实例还是存在的,只是解绑了事件的监听还有watcher对象数据与view的绑定,即数据驱动
二、VueJS ajax
2.1 vue-resource:
vue-resource是Vue.js的插件提供了使用XMLHttpRequest或JSONP进行Web请求和处理响应的服务。 当vue更新到2.0之后,作者就宣告不再对vue-resource更新,而是推荐的axios,在这里大家了解一下vue-resource就可以。 vue-resource的github: https://github.com/pagekit/vue-resource
2.2 axios
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中 axios的github:https://github.com/axios/axios
2.2.1 引入axios
首先就是引入axios,如果你使用es6,只需要安装axios模块之后:
import axios from 'axios';
//安装方法
npm install axios
当然也可以用script引入:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
2.2.2 get请求
2.2.3 post请求
2.2.4 为方便起见,为所有支持的请求方法提供了别名:
axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
*请认真填写需求信息,我们会在24小时内与您取得联系。