学习目标
JSP (Java Server Pages)
EL ( Expression Language )
JSTL (The JavaServer Pages Standard Tag Library)
一、JSP
1、概述
JSP全名为Java Server Pages 、java服务器页面。既能写html代码、又能写Servlet、其本质是一个简化的Servlet。
创建:如图idea
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
</body>
</html>
2、jsp原理
当我们通过浏览器访问到jsp页面、最终访问的是tomcat服务器中的jsp页面。下面我们可以通idea发布web项目。
当启动tomcat时可看到下面的信息
C:\Users\root\.IntelliJIdea2018.2\system\tomcat\Tomcat_8_5_31_day10Ajax\work\Catalina\localhost\ROOT\org\apache\jsp
打开index_jsp.java文件后,发现我们在JSP页面上写的代码都在_jspService方法中:
1. <% %> 中书写的代码被直接解析成java代码;
2. html部分都被out.write("")方法以字符串的形式拼接,然后响应给浏览器;
3. 在这个java文件中有个_jspService,这个方法有两个参数request,response。
由此可看出JSP本质上就是一个Servlet。
3、jsp中书写java代码三种方式
jsp页面中书定java代码要使用三种方法:
3.1、脚本片段<% java代码 %>
脚本片段指的是一段java代码 demo2.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
response.getWriter().println()任意数据
response.getWriter().write//只能输出字符 字符数组 字符串
--%>
<%
response.getWriter().println("hello jsp");
response.getWriter().write(65);
%>
</body>
</html>
response.getWriter().write(65);输出的是A。A的ASCII是65。
3.2、脚本声明<%! java代码 %>
声明成员方法和属性 demo3.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
成员变量 int num = 0;
public void method(){}
--%>
<%!
int num = 10;
public void method(){}
%>
</body>
</html>
【被翻译后的代码】成员变量
3.3、脚本表达式<%=内容%>
脚本表达式的格式:<%= 内容 %> 等价于:out.print(内容)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
out.println("hello out");
response.getWriter().println("response");
%>
<%="我爱JAVA"%>
</body>
</html>
【小结】
1. 脚本表达式<%= str %> :在页面输出内容,
2. 脚本片段<% %> :在service方法中,原样输出的代码片段;
3. 脚本声明:<%! String str = "我爱java" %> :定义成员变量;
write() 和println()区别
(1)、write():仅支持输出字符类型数据,字符、字符数组、字符串等
(2)、print():可以将各种类型(包括Object)的数据通过默认编码转换成bytes字节形式,这些字节
response.getWriter().println();先输出、out.write(65)后输出
4、登录案例
登录代码:
@WebServlet("/loginServletin")
public class LoginInServlet 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 {
//解决中文乱码问题
request.setCharacterEncoding("utf-8");
//获取用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
//使用service层来解决业务逻辑
UserServiceIn serviceIn = new UserServiceInImpl();
boolean result = serviceIn.login(username,password);
if (result){
//登陆成功 需要携带数据
//使用 重定向
// request.getRequestDispatcher("/success.html").forward(request,response);
response.sendRedirect("/success.html");
}else {
//登陆失败 应用去login.html
//希望用户得到 登陆错误信息
//使用转发 servlet处理业务太多了,代码臃肿问题
request.setAttribute("msg","用户名或者密码错误");
request.getRequestDispatcher("/login.jsp").forward(request,response);
}
}
}
login.jsp登录页
<body>
<%
// String str = (String) request.getAttribute("msg");
%>
<div class="container text-center">
<form class="form-signin" action="/loginServletin" method="post">
<font color="red"><%=str%></font>
<h2 class="form-signin-heading">登录页面</h2>
<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>
当登录出错时会显示如下
二、EL表达式
1、概述
EL全称: Expression Language
作用:代替jsp中脚本表达式的功能,简化对java代码的操作,从【域对象】中取值。 EL表达式简化<%= %>方式取值
EL语法表达式的格式:${表达式内容}
2、EL取值
2.1、JSP的四大域对象
JSP的四大域对象指的是:page域,request域,session域,application域。我们通常使用EL表达式从这4个域对象用取值。以下是这4个域对象的详细信息:
| 域对象 | 对象名称 | 说明 |
|---|---|---|
| page域 | pageScope | page域指的是当前JSP页面,其中存储的数据只在当前页面有效 |
| request域 | requestScope | request域:一次请求或请求链中request域 |
| session域 | sessionScope | session域:一次会话过程中,session域 |
| application域 | applicationScope | application域:服务启动后整个项目对应的ServletContext域 |
2.2、EL表达式从四大域中取值
EL表达式从指定的域中取值的方式如下:
| 域对象 | 取值方式 |
|---|---|
| page域 | ${pageScope.xxx} |
| request域 | ${requestScope.xxx} |
| session域 | ${sessionScope.xxx} |
| application域 | ${applicationScope.xxx} |
代码:
<body>
<%--
EL表达式 page request session application 四大域对象
--%>
<%
pageContext.setAttribute("pageValue","page的值");
request.setAttribute("requestValue","request的值");
request.getSession().setAttribute("sessionValue","session的值");
application.setAttribute("applicationValue","applicatin的值");
%>
<%--
EL表达式来域对象中取值
--%>
page中取值:${pageScope.pageValue}<br>
request中取值:${requestScope.requestValue}<br>
session中取值${sessionScope.sessionValue}<br>
application中取值${applicationScope.applicationValue}<br>
</body>
2.3、EL表达式搜索数据
EL表达式取值的时候也可以不指定域,如果取值的时候不指定域对象。就会按照从page域--->request域--->session域--->servletContext域从小到大逐级根据name属性值查找。
<body>
<%
pageContext.setAttribute("pageValue","page的值");
request.setAttribute("requestValue","request的值");
request.getSession().setAttribute("sessionValue","session的值");
application.setAttribute("applicationValue","applicatin的值");
pageContext.setAttribute("value","page的值");
request.setAttribute("value","requst的值");
%>
<%--
默认从最小的域对象的范围-->最大域对象。
--%>
page中取值:${pageScope.pageValue}<br>
page:${pageValue}<br>
request中取值:${requestValue}<br>
session中取值${sessionValue}<br>
application中取值${applicationValue}<br>
相同key:${value}
</body>
2.4、EL表达式cookie中取值
语法格式:${cookie.cookie名称.value} 取出单个cookie的值
java代码:CreateCookieServlet.java
@WebServlet("/create")
public class CreateCookieServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建cookie
Cookie cookieName = new Cookie("name","lisi");
Cookie cookiePsw = new Cookie("password","1234");
response.addCookie(cookieName);
response.addCookie(cookiePsw);
}
}
demo7.jsp
<body>
<form action="" method="post">
用户名:<input type="text" name="username" value="${cookie.name.value}"><br>
密码:<input type="text" name="password" value="${cookie.password.value}"><br>
<input type="submit" value="提交">
</form>
</body>
先访问:http://localhost:8080/CreateCookieServlet 生成cookie
再访问demo07.jsp页面,使用EL表达式获取用户名和密码
http://localhost:8080/CreateCookieServlet
3、EL运算符
3.1 算术运算
顾名思义,算术运算是进行算术运算的符号,主要包括:加,减,乘,除。具体使用如下表:
| 运算符 | 说明 | 使用示例 | 结果 |
|---|---|---|---|
| + | 加 | ${n1+n2} |
30 |
| - | 减 | ${n1-n2} |
-10 |
| * | 乘 | ${n1*n2} |
200 |
| /或div | 除 | ${n1/n2} |
|
| %或mod | 取余 |
3.2 关系运算
关系运算符是判断两个数据的大小关系的,关系运算符有:==,!=,<,<=,>,>=。具体使用方法如下:
| 运算符 | 说明 | 使用示例 | 结果 |
|---|---|---|---|
== 或 eq |
等于 equal | ${n1 == n2} |
false |
!= 或ne |
不等于 not equal | ${n1 != n2} |
true |
> 或 gt |
大于 greater than | ${n1 > n2} |
false |
>= 或ge |
大于等于 greater than or equal | ${n1 >= n2} |
false |
< 或 lt |
小于 less than | ${n1 < n2} |
true |
<= 或le |
小于等于 less than or equal | ${n1 <= n2} |
true |
3.3 逻辑运算
逻辑运算符包括:&& ,||,!使用方法如下:
| 运算符 | 说明 | 使用示例 | 结果 |
|---|---|---|---|
| && 或 and | 逻辑与 | ${true && false} |
false |
| || 或 or | 逻辑或 | `${true | |
| ! 或 not | 非 | ${!false} |
true |
3.4 三元运算
<%--
表达式1?表达式2:表达式3
--%>
三元运算符:<br>
${n1>=n2?"正确":"错误!"}<br>
3.5 empty运算
empyt运算符对以下数据运算返回true:
1. 字符串:"";
2. 空集合(size=0):List list = new ArrayList();
3. 空对象(null):Student stu = null;
小结:
EL表达式小结:
-
EL:Expression Language;
-
EL语法:${ }
-
作用:简化脚本表达式的取值,简化<%= request.getAttribute("name") %> ===> ${name}
-
jsp的四大域对象
-
page域:pageContext pageContext.setAttrubute() pageContext.getAttribute() JSP特有 作用范围:当前的JSP页面
-
requst域:request request.setAttribute() request.getAttribute() 作用范围:一次请求和响应之间
-
session域: session session.setAttribute() session.getAttribute() 作用范围:会话期间(多次请求和响应)
-
servletContext域:application application.setAttribute() application.getAttribute() 作用范围:整个项目;
-
-
jsp从四大域中取值(指定域对象):
-
${pageScope.name}
-
${requestScope.name}
-
${sessionScope.name}
-
${applicationScope.name}
-
-
JSP搜索域对象中的值:page --- request --- session --- servletContext
-
${name}
-
-
运算
-
算术运算
-
关系运算
-
逻辑运算:&& || !
-
三元运算
-
empty运算:empty not empty
-
空字符串:""
-
空对象:null
-
空集合:list.size = 0;
-
-
三、JSTL标签库
1、概述
Apache Jakarta小组开发了一套用于解决这些常用问题的自定义标签库,
这套标签库被SUN公司定义为标准标签库(The JavaServer Pages Standard Tag Library),简称JSTL。
2、安装使用JSTL
JSTL标签是将一段java代码功能封装成一个标签来使用。所以,我们使用JSTL标签之前必须导入被封装的java代码---jar包。JSTL标签库主要依赖以下两个jar包:
在JSP页面中通过以下标签,通过taglib标签引入JSTL资源:
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
注意】
1. prefix:是jstl标签在使用的时候的前缀;
2. uri:是标签库的资源路径;
3、常用JSTL标签
JSTL核心标签库
| 标签名称 | 作用 |
|---|---|
| <c:out> | 通常用于输出一段文本内容到客户端浏览器 |
| <c:set> | 用于设置各种Web域中的属性 |
| <c:remove> | 用于删除各种Web域中的属性 |
| <c:catch> | 用于捕获嵌套在标签体中的内容抛出的异常 |
| <c:if> | 用户java代码if(){}语句功能 |
| <c:choose> | 用于指定多个条件选择的组合边界,它必须与c:when和c:otherwise标签一起使用 |
| <c:forEach> | 用户代替java代码for循环语句 |
| <c:forTokens> | 用户迭代操作String字符 |
| <c:param> | 给请求路径添加参数 |
| <c:url> | 重写url,在请求路径添加sessionid |
| <c:import> | 用于在JSP页面中导入一个URL地址指向的资源内容 |
| <c:redirect> | 用于将当前的访问请求转发或重定向到其他资源 |
<c:if>格式:
<c:if test=条件判断 >标签的作用相当于java中的if判断语句。
if(条件判断){}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
session.setAttribute("user","username");
%>
<c:if test="${user==null}">
<c:out value="请登录"></c:out>
</c:if>
<c:if test="${user!= null}">
<c:out value="登录成功"></c:out>
</c:if>
</body>
</html>
<c:foreach>遍历
属性如下:
var:在不循环对象的时候,保存的是控制循环的变量;在循环对象的时候,保存的是被循环对象中的元素
items:指定要循环的对象
varStatus:保存了当前循环过程中的信息(循环的开始、结束、步长、次数等)
begin:设置循环的开始
end:设置循环的结束
step:设置步长——间隔几次循环,执行一次循环体中的内容
演示一:list遍历
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
使用EL表达式和JSTL将数据遍历出来,填放在标签里面
--%>
<c:forEach items="${list}" var="product">
惊爆价:<font color="red">${product.price}</font>商品名称:<font color="aqua">${product.name}</font><br>
</c:forEach>
</body>
</html>
ProductServlet.java
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.ArrayList;
import java.util.List;
@WebServlet("/produceServlet")
public class ProduceServlet 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 {
//去数据库查询商品信息
Product product1 = new Product(9.9,"布娃娃");
Product product2 = new Product(99,"苹果");
Product product3 = new Product(12000,"电脑");
Product product4 = new Product(8,"鼠标");
Product product5 = new Product(20,"杯子");
List<Product> list = new ArrayList<>();
list.add(product1);
list.add(product2);
list.add(product3);
list.add(product4);
list.add(product5);
//将数据存储在域对象中
request.setAttribute("list",list);
//使用转发 list.jsp
request.getRequestDispatcher("/list.jsp").forward(request,response);
}
}
实体类Product
public class Product {
private int id;
private double price;
private String name;
public Product(double price, String name) {
this.price = price;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Product{" +
"id=" + id +
", price=" + price +
", name='" + name + '\'' +
'}';
}
}
演示二:map集合
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
Map map = new HashMap();
map.put("one","郭德纲");
map.put("two","c罗");
map.put("thr","小罗");
map.put("four","贾宝玉");
request.setAttribute("map",map);
%>
<c:forEach items="${map}" var="item">
明星人物key:${item.key}+value:${item.value}<br>
</c:forEach>
</body>
</html>
choose标签作用
<c:choose>标签用于指定多个条件选择的组合边界,它必须与<c:when>和<c:otherwise>标签一起使用。
演示:choose.jsp
<body>
<c:choose>
<c:when test="${temp == 1}">
<c:out value="一年级"></c:out>
</c:when>
<c:when test="${temp == 2}">
<c:out value="二年级"></c:out>
</c:when>
<c:when test="${temp == 3}">
<c:out value="三年级"></c:out>
</c:when>
<c:when test="${temp == 4}">
<c:out value="四年级"></c:out>
</c:when>
<c:when test="${temp == 5}">
<c:out value="五年级"></c:out>
</c:when>
<c:otherwise>
<c:out value="输入有误"></c:out>
</c:otherwise>
</c:choose>
</body>
switchServlet.java
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;
@WebServlet("/switchServlet")
public class SwitchServlet 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 {
//实现switch功能
int temp = 7;
//转发到servlet
request.setAttribute("temp",temp);
//转发到choose.jsp
request.getRequestDispatcher("/choose.jsp").forward(request,response);
}
}
访问URL:http://localhost:8080/switchServlet