课程回顾
JSP的概念
JSP执行流程
JSP和Servlet的关系
区别: Servlet三件事: ①获取数据②调用业务方法③流程控制, JSP侧重数据的展示。
联系: JSP就是Servlet,JSP继承HttpServlet。
EL表达式
${ } 可以访问作用域的数据
综合案例
九大内置对象
什么是内置对象
内置对象是JSP中可以直接使用的对象,普通对象我们需要new创建对象,而内置对象不用创建可以直接使用;内置对象是由服务器创建,传递给JSP页面对象。
九大内置对象
- request对象: 获取请求数据 HttpServletRequest
- response对象: 响应数据对象 HttpServletResponse
- session对象: 会话对象,存储用户的会话信息 HttpSession
- application对象: 应用程序 app ,DAMA,application代表整个web应用程序 ServletContext
- page对象: 当前页面对象 Object
- pageContext对象: 当前页面上下文环境对象 PageContext
- exception对象: 表示页面的异常信息 Throwable
- config对象: 表示jsp的配置信息, ServletConfig
- out对象: 输出数据到浏览器 JspWriter 输出流对象,字符
request对象
获取客户端提交的信息、服务器自身信息;
- reques.getParamter( “name” ) 获取单个值
- request.getParameterValues( “ 复选框 “ ) 获取多个值 String[]
- request.getParameterNames(); 返回 Enumration
- request.getParameterMap(); 返回Map<String,String[]>
- request.getContextPath(); 返回web跟路径信息
- request.getRequestDispatcher(“路径”).forward( request,response ); 转发
response对象
响应对象,向客户端浏览器发送数据。
- response.sendRedirect( “fail.jsp” ); 重定向
- response.setContextType( “” ); 设置浏览器响应的内容类型
- response.setHeader( “key”, “value” );设置响应头信息
- response.addHeader( “key”, “value” );添加响应头信息
- response.getOutputStream(); 获取输出字节流对象
- response.getWriter(); 获取输出字符流对象
- response.addCookie( cookie ); 添加Cookie信息
session对象
表示客户端和服务器的会话,浏览器和服务器的多次请求和响应。我们购物的过程就是会话,多次和服务器进行交互。
下次课和Cookie一起讲解
application对象
是ServletContext对象,全局的对象,服务器加载web应用创建该对象,服务器卸载web应用则停止;服务器停止该对象销毁。声明周期伴随web应用,所以不适合存储大量数据,会一直占用服务器内存。
- application.setAttribute( “key”, “value" );
- application.getAttribute(“key”);
- application.getAttributeNames();//获取所有的属性名
- application.removeAttribute( “key” ); 删除属性
- application.getRealPath( “image/00.jpeg” );获取文件的真实路径
- application.getContextPath();获取web应用的项目名称
- application.getResourceAsStream( “/WEB-INF/classes/jdbc.properties” ); //注意: classes/config/jdbc.properties
page对象
page代表当前页面对象,类型是Object的,该对象没有特殊的方法,都是Object对象的方法。
这个对象就是页面实例的引用。它可以被看做是整个JSP页面的代表。page 对象就是this对象的同义词。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
out.println( page );
%>
</body>
</html>
pageContext对象
pageContext对象表示页面的环境,用来代表整个JSP页面;这个对象存储了request对象和response对象的引用。application对象,config对象,session对象,out对象可以通过访问这个对象的属性来导出。
pageContext对象也包含了传给JSP页面的指令信息,包括缓存信息,ErrorPage URL,页面scope等。
PageContext类定义了一些字段,包括PAGE_SCOPE,REQUEST_SCOPE,SESSION_SCOPE, APPLICATION_SCOPE。它也提供了40余种方法,有一半继承自javax.servlet.jsp.JspContext 类。
pageContext作用域方法
- pageContext.setAttribute(“key”,”value")
- pageContext.getAttribute( “key” )
- pageContext.getAttribute( “key”, 作用域 )
- pageContext.getAttributeNamesInScope(作用域)
- pageContext.removeAttribute(“key”)
exception对象
显示异常信息,
a.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" errorPage="ex.jsp" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
out.println(5/0);
%>
</body>
</html>
b.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" isErrorPage="true" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>错误页面</title>
</head>
<body>
错误信息: <%=exception.getMessage() %>
</body>
</html>
config对象
ServletConfig类型,获取配置信息,
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
Config对象: <br/>获取ServletName:<%=config.getServletName() %><br/>
获取ServletContext对象: <%=config.getServletContext().getContextPath() %><br/>
</body>
</html>
out对象
向客户端浏览器输出数据的。out对象是 javax.servlet.jsp.JspWriter 类的实例,用来在response对象中写入内容。
- out.println(); 支持各种数据类型的输出
- out.flush(); 刷新缓冲区
- out.close(); 关闭输出流
- out.write(); 输出数据
四大作用域对象
作用域: pageContext 当前页面 < request 请求 < session 会话 < application对象
page.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
out.println( page );
pageContext.setAttribute("name", "赵敏");
pageContext.setAttribute("age", 30, PageContext.REQUEST_SCOPE);
request.setAttribute("req_address", "四川峨眉山峨眉派");
session.setAttribute("ses_money", 10000);
application.setAttribute("app", "信阳绿茶-毛尖");
%>
<h1>取值</h1>
pageContext的默认作用域: <%=pageContext.getAttribute("name") %><br/>
pageContext的指定作用域: <%=pageContext.getAttribute("age", PageContext.REQUEST_SCOPE) %><br/>
request的作用域: <%=request.getAttribute("req_address") %><br/>
session的作用域: <%=session.getAttribute("ses_money") %><br/>
application的作用域:<%=application.getAttribute("app") %>
<%
//response.sendRedirect("show.jsp");
request.getRequestDispatcher("show.jsp").forward(request, response);
%>
</body><br/>
</html>
show.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>取值</h1>
pageContext的默认作用域: <%=pageContext.getAttribute("name") %><br/>
pageContext的指定作用域: <%=pageContext.getAttribute("age", PageContext.REQUEST_SCOPE) %><br/>
request的作用域: <%=request.getAttribute("req_address") %><br/>
session的作用域: <%=session.getAttribute("ses_money") %><br/>
application的作用域:<%=application.getAttribute("app") %>
</body>
</html>
总结:
- pageContext 默认设置属性是当前页面,不管是转发还是重定向都不可以获取
- pageContext.setAttribute(“age”, 30, PageContext.REQUEST_SCOPE); 指定作用域转发可以获取,重定向不可以
- request作用域: 转发可以,重定向不可以
- session作用域: 转发和重定向都可以,但是仅限当前客户端浏览器
- application作用域: 都可以获取,可以存储共享数据,在线人数,到监听器时讲解案例
EL表达式详解
EL Express Language 表达式语言, ${ } 用来简化JSP页面的编码,JSP技术是用来显示数据,但是还有大量的JAVA代码,如何优化、简化java代码,EL是一种方案、另一种方案JSTL。
EL 可以访问四大作用域的对象,并且支持访问对象的属性以及数组、集合类。也支持常见的算术运算符,+ - * /等等。EL表达式的应用场景:
- 获取变量的值
- 获取对象的属性值
- 获取数组的元素
- 获取集合的元素
- 获取执行表达式
1、获取变量的值
按照page → request → session → application的作用域顺序依次查找,找到即返回,最终找不到返回null。还可以指定作用域:
属性范围 | EL中的名称 |
---|---|
page | pageScope,例如${pageScope.username}表示在page作用域查找变量username,找不到返回null |
request | requestScope |
session | sessionScope |
application | applicationScope |
package com.ujiuye.controller;
import java.io.IOException;
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 com.ujiuye.serivce.UserService;
import com.ujiuye.serivce.impl.UserServiceImpl;
@WebServlet("/userServlet")
public class UserServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private UserService userService = new UserServiceImpl();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取变量的值: 变量可以是自己定义的、可以是外界传入的、可以是数据库的
String name = "胡一刀";
String age = request.getParameter("age");
int count = userService.getCount();
request.setAttribute("name", name);
request.setAttribute("age", age);
request.setAttribute("count", count);
request.getRequestDispatcher("el.jsp").forward(request, response);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
2、获取对象的属性值
语法: ${ 对象名.属性名 } 访问getter方法
package com.ujiuye.controller;
import java.io.IOException;
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 com.ujiuye.entity.User;
import com.ujiuye.serivce.UserService;
import com.ujiuye.serivce.impl.UserServiceImpl;
@WebServlet("/userServlet")
public class UserServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private UserService userService = new UserServiceImpl();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取变量的值: 变量可以是自己定义的、可以是外界传入的、可以是数据库的
String name = "胡一刀";
String age = request.getParameter("age");
int count = userService.getCount();
request.setAttribute("name", name);
request.setAttribute("age", age);
request.setAttribute("count", count);
//2、获取对象的属性值
String userCode = request.getParameter("userCode");
User user = userService.findById(userCode);
request.setAttribute("u", user);
request.getRequestDispatcher("el.jsp").forward(request, response);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
el.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>访问变量的值</h1>
自定义变量: ${name }, 传入参数变量: ${age }, 数据库数据: ${count } <br/>
<h1>访问对象的值</h1>
userCode: ${u.userCode },loginCode: ${u.loginCode },userName:${u.userName }<br/>
</body>
</html>
3、获取数组的元素
//3、获取集合的元素,数组也可以
String [] citys = {"北京市","上海市","杭州市","郑州市"};
List<String> list = new ArrayList<>();
list.add("张无忌");
list.add("赵敏");
list.add("小昭");
List<User> ulist = userService.findAll();
request.setAttribute("list", list);
request.setAttribute("ulist", ulist);
request.setAttribute("citys", citys);
el.jsp
<h1>访问数组的值</h1>
数组: ${citys[0]}, ${citys[1]}, ${citys[2]},
<h1>访问集合List的值</h1>
普通数据: list[0]=${list[0]}, list[1] = ${list[1] },list[2]= ${list[2]},list[3] = ${list[3]}<br/>
对象数据: userList: ${ulist[0].userName} , ${ulist[1].userName}
4、获取集合的元素
//4.获取Map的数据
Map<String, String> map1 = new HashMap<String, String>();
map1.put("k1", "白眉鹰王");
map1.put("k2", "灭绝师太");
request.setAttribute("m1", map1);
Map<String,User> map2 = new HashMap<String, User>();
map2.put("uk", user);
request.setAttribute("m2", map2);
el.jsp
<h1>访问map中的数据</h1>
简单Map: k1 = ${m1.k1 }, k2 = ${m1.k2}<br>
对象Map: ${m2.uk.userName } === ${m2.uk.password }
5、获取执行表达式
//5.计算表达式的值
String sex = null;
request.setAttribute("sex", sex);
request.getRequestDispatcher("el.jsp").forward(request, response);
el.jsp
<h1>访问表达式的值</h1>
5>3 ${ 5 > 3 } <br/>empty判断字符串是否为null或者长度为0: ${empty sex };
JSTL标签库
JSTL: jsp standard tag library java标准标签库; 提供一组标准标签,也是用来简化java代码的编写。EL不能进行逻辑判断,不能进行if,for循环。例如我们要在页面显示List集合,还要写java代码,如何简化,使用JSTL。搭建开发环境:
- 添加jar包: jstl1.2.jar
- 在JSP页面引入标签库 <%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %> taglib指令
- prefix 标签库的前缀,可以自定义,一般core标签prefix是c
- format格式化标签: <%@ taglib prefix=“fmt” uri=“http://java.sun.com/jsp/jstl/fmt” %>
JSTL标签库包括如下一组标签:
- core 核心标签: 最常用的
- fmt 格式化标签: 常用的
- function 标签: 函数标签,主要是处理String的方法,字符串截取,次常用
- sql 标签:数据库标签,可以在jsp页面直接访问数据库,不符合三层结构,一般不用
- xlm 标签: 处理XML文件或者数据, 很少用
说明:开发模式是前后端分离的,前端工程师用HTML Vue;不用JSP技术,所以有B站up主说JSP可以淘汰了,但是JSP是我们理解现代开发模式的基础,所以还有必要了解,JSP需要Tomcat环境,前后端分离之后,前端工程师不用Tomcat开发,所以就没法用JSP,都是Vue。通过发送AJAX请求获取数据,axios是一个发送请求的JavaScript库。
core核心标签
通用标签: c:set c:out c:remove
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<c:set var="name" value="张三丰" scope="request"></c:set>
<c:set var="age" value="65" scope="request"></c:set>
<c:remove var="age"/>
姓名:<c:out value="${name}"></c:out><br/>
年龄:<c:out value="${age}"></c:out>
</body>
</html>
条件标签: c:if c:choose
LoginServlet.java
package com.ujiuye.controller;
import java.io.IOException;
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 com.ujiuye.entity.User;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取用户名和密码,调用业务类,返回User对象
User user = new User();
user.setUserName("admin");
request.setAttribute("u", user);
request.getRequestDispatcher("jstl.jsp").forward(request, response);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
jstl.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>c:if标签</h1>
<c:if test="${ empty u }">
<h3>用户登录</h3>
<form action="userServlet?flag=login" method="post">
用户账号: <input type="text" name="username"/><br/>
用户密码: <input type="text" name="password"/><br/>
<input type="submit" value="登录"/>
</form>
</c:if>
<c:if test="${! empty u }">
<h3>欢迎登录${u.userName}</h3>
</c:if>
</body>
</html>
迭代标签: c:forEach
LoginServlet.java
package com.ujiuye.controller;
import java.io.IOException;
import java.util.List;
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 com.ujiuye.entity.User;
import com.ujiuye.serivce.UserService;
import com.ujiuye.serivce.impl.UserServiceImpl;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
private UserService userService = new UserServiceImpl();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取用户名和密码,调用业务类,返回User对象
User user = new User();
user.setUserName("admin");
request.setAttribute("u", user);
List<User> list = userService.findAll();
request.setAttribute("list", list);
request.getRequestDispatcher("jstl.jsp").forward(request, response);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
jstl.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
#t1{
border: 1px solid #000;
width: 1000px;
border-collapse: collapse;
}
#t1 tr td, #t1 tr th{
border: 1px solid #000;
}
</style>
</head>
<body>
<h1>c:forEach遍历</h1>
<table id="t1">
<tr>
<th>用户号码</th>
<th>用户编码</th>
<th>登录账号</th>
<th>用户姓名</th>
<th>用户密码</th>
<th>电子邮箱</th>
</tr>
<c:forEach items="${list}" var="u" varStatus="s">
<tr <c:if test="${s.index % 2 == 0 }" > style="background-color:#CCCCFF" </c:if> >
<td> ${s.index }</td>
<td> ${u.userCode } </td>
<td> ${u.loginCode } </td>
<td> ${u.userName }</td>
<td> ${u.password }</td>
<td> ${u.email } </td>
</tr>
</c:forEach>
</table>
</c:if>
</body>
</html>
乘法口诀表
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>c:ForEach乘法口诀表</h1>
<c:forEach begin="1" end="9" step="1" var="i">
<c:forEach var="j" begin="1" end="${i}" step="1">
${j} * ${i} = ${j*i}
</c:forEach>
<br>
</c:forEach>
</body>
</html>
遍历Map
//c:forEach遍历map
Map<String, String> map1 = new HashMap<String, String>();
map1.put("k1", "白眉鹰王");
map1.put("k2", "灭绝师太");
request.setAttribute("m1", map1);
User u1 = new User("周芷若","zhouzhiruo@163.com");
User u2 = new User("小昭","xiaozhao@sohu.com");
Map<String, User> map2 = new HashMap<String, User>();
map2.put("u1", u1);
map2.put("u2", u2);
request.setAttribute("m2", map2);
request.getRequestDispatcher("jstl.jsp").forward(request, response);
jstl.jsp
<h1>c:forEach遍历Map集合</h1>
<h4>遍历普通Map</h4>
<c:forEach var="entry" items="${m1}">
${entry.key }---->${entry.value }<br/>
</c:forEach>
<h4>遍历对象Map</h4>
<c:forEach var="u" items="${m2}">
${u.key}---${u.value.userName }---${u.value.email }<br/>
</c:forEach>
三层结构
数据访问层
业务逻辑层
表示层
综合案例: 单表增删改查
按照三层结构实现。