JSP技术(@Magi)

一、JSP简介

1.jsp介绍

JSP(全称 Java Server Pages)Java 服务端页面技术,是 JavaEE 平台下的技术规范。它允许使用特定的标签在 HTML 网页中插入 Java 代码,实现动态页面处理,所以 JSP 就是 HTML 与Java 代码的复合体。JSP 技术可以快速的实现一个页面的开发,相比在 Servlet 中实现页面开 发将变得更加容易。

2.常见的视图层技术

HTML、JSP、Thymeleaf等

3.前后端分离开发方式

在前后端分离的项目中真正可以做到“术业有专攻”(开发人员分离) 。前后端分离开发方式中前端页面由专业团队完成页面的开发,并通过请求调用后端的 api 接口进行数据交互。在开发前端页面的团队中更多关注的技术如:html、CSS、jQuery、Vue、Nodejs 等前端技术。前端追求的是:页面表现,速度流畅,兼容性,用户体验等等。而后端团队则更多的是业务的具体实现。在后端开发的团队中更多关注的技术如:设计模式、分布式架构、微 服务架构、数据库的操作、Java 的性能优化以及数据库优化等技术。前后端分离已成为互联 网项目开发的业界标准使用方式,特别是为大型分布式架构、弹性计算架构、微服务架构、 多端化服务(多种客户端,例如:浏览器,车载终端,安卓、IOS 等等)打下坚实的基础。

二、JSP运行原理

1.JSP技术特点

image-20220323235757392

JSP 和 Servlet 是本质相同的技术。当一个 JSP 文件第一次被请求时、JSP 引擎会将该 JSP编译成一个 Servlet,并执行这个 Servlet。如果 JSP 文件被修改了,那么 JSP 引擎会重新编译 这个 JSP。

JSP 引擎对 JSP 编译时会生成两个文件分别是.java 的源文件以及编译后的.class 文件,并放到 Tomcat 的 work 目录的 Catalina 对应的虚拟主机目录中的 org\apache\jsp 目录中。两个 文件的名称会使用 JSP 的名称加”_jsp”表示。如:index_jsp.java、index_jsp.class

3.JSP与Servlet区别

JSP 以源文件形式部署到容器中。而 Servlet 需要编译成 class 文件后部署到容器中。

JSP 部署到 web 项目的根目录下或根目录下的其他子目录和静态同资源位于相同位置。而 Servlet 需要部署到 WEB-INF/classes 目录中

JSP 中的 HTML 代码会被 JSP 引擎放入到 Servlet 的 out.write()方法中。而在 Servlet 中我们需要自己通过对字符流输出流的操作生成响应的页面。

JSP 更擅长表现于页面显示,Servlet 更擅长于逻辑控制。

三、 JSP的使用

image-20220324000759109

1 JSP的三种原始标签

JSP 的原始标签在 JSP 的任何版本中都可以使用。

1.1 <%! %>声明标签

声明标签用于在 JSP 中定义成员变量与方法的定义。标签中的内容会出现在 JSP 被编译后的 Servlet 的 class 的{}中。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
Welcome JSP!
<%!
int a = 10;
int add(int a,int b)
{
return a+b;
}
%>
</body>
</html>

image-20220324001848464

1.2<% %>脚本标签

脚本标签用于在 JSP 中编写业务逻辑。标签中的内容会出现在 JSP 被编译后的 Servlet 的_jspService 方法体中。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
Welcome JSP!
<%!
int a = 10;
int add(int a,int b)
{
return a+b;
}
%>

<%
int c =20;
%>
</body>
</html>

image-20220324001903528

1.3<%= %>赋值标签

赋值标签用于在 JSP 中做内容输出。标签中的内容会出现在_jspService 方法的 out.print()方法的参数中。注意我们在使用赋值标签时不需要在代码中添加 ”;”。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
Welcome JSP!
<%!
int a = 10;
int add(int a,int b)
{
return a+b;
}
%>

<%
int c =20;
%>
<%=a%>
<%=c%>
</body>
</html>

image-20220324002446066

1.4 JSP原始标签的使用

需求:以 20%概率显示你中奖了。

<%@ page import="java.util.Random" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--jsp的原始标签是不允许嵌套的--%>
<%
int flag = new Random().nextInt(100);
String str = "";
if(flag<=20)
{
str = "中奖了";
}else
{
str = "再试试!";
}
%>
<%=str%>

</body>
</html>

2 JSP的指令标签

JSP 指令标签的作用是声明 JSP 页面的一些属性和动作。

<%@指令名称 属性=”值” 属性=”值”%>

2.1 JSP指令标签分类:

page:主要声明 JSP 页面的一些属性

include:静态包含

taglib:导入标签库

image-20220324100419061

2.1.1 Page指令标签
2.1.1.1 contentType

设置响应类型和编码。

2.1.1.2 pageEncoding

设置页面的编码。

2.1.1.3 import

导入所需要的包

2.1.1.4 language

当前 JSP 页面里面可以嵌套的语言。

2.1.1.5 session

设置 JSP 页面是否获取 session 内置对象。

2.1.1.6 buffer

设置 JSP 页面的流的缓冲区的大小。

2.1.1.7 autoFlush

是否自动刷新。

2.1.1.8 extends

声明当前 JSP 的页面继承于那个类.必须继承的是 httpservlet 及其子类。

2.1.1.9 isELIgnored

是否忽略 el 表达式。

2.1.1.10 errorPage

当前 JSP 页面出现异常的时候要跳转到的 JSP 页面。

2.1.1.11 isErrorPage

当前 JSP 页面是否是一个错误页面。若值为 true,可以使用 JSP 页面的一个内置对象 exception。

2.1.2 Include 指令标签

静态包含,可以将其他页面内容包含进来,一起进行编译运行.生成一个 java 文件. <%@include file=”被包含 JSP 的相对路径” %>

2.1.3 Taglib指令标签

导入标签库<%@taglib prefix=”前缀名” uri=”名称空间” %>

3. JSP的内置对象

JSP 中一共预先定义了 9 个这样的对象,分别为:request、response、session、application、 out、pagecontext、config、page、exception。

3.1 request对象

request对象是HttpServletRequest 类型的对象。

3.2 response对象

response 对象是 HttpServletResponse 类型的对象

3.3 session对象

session 对象是 HttpSession 类型的对象。只有在包含 session=“true” 的页面中才 可以被使用

3.4 application对象

application 对象是 ServletContext 类型的对象

3.5 out对象

out 对象是 JspWriter 类型的对象。

3.6 config对象

config 对象是 ServletConfig 类型的对象。

3.7pageContext 对象

pageContext 对象是 PageContext 类型的对象。作用是取得任何范围的参数,通过 它可以获取 JSP 页面的 out、request、reponse、session、application 等对象。pageContext对象的创建和初始化都是由容器来完成的,在 JSP 页面中可以直接使用 pageContext 象

3.8 page对象

page 对象代表 JSP 本身。

3.9 exception对象

exception 对象的作用是显示异常信息,只有在包含 isErrorPage=”true” 的页面中 才可以被使用。

4 请求转发

4.1 什么是请求转发

请求转发是服务端的一种请求方式,相当于在服务端中直接请求某个资源。 RequestDispatcher dispatcher = request.getRequestDispatcher(“/test.jsp”); dispatcher.forward(request,response);

简写方式:

request.getRequestDispatcher(“/test.jsp”).forword(request,response);

image-20220324102245782

4.2 请求转发(服务端操作)与重定向(客户端操作)的区别

请求转发对于客户端浏览器而言是在一次请求与响应中完成,而重定向是在两次请求两次响应中完成。

请求转发并不会改变客户端浏览器的地址栏中的内容。而重定向会改变客户端浏览器地 址栏中的内容。

请求转发可以使用 request 对象传递数据,而重定向不能使用 request 对象传递数据。

如果是处理的 DML 操作,建议使用重定向方式为客户端浏览器产生响应,可以解决表 单重复提交现象。

4.3 请求转发案例

需求:在 Servlet 中获取客户端浏览器所支持的语言,并通过 JSP 页面将客户端浏览器 所支持的语言响应给客户端浏览器。

/**
*在servlet中获取客户端浏览器所支持的语言,
* 并通过JSP页面将客户端浏览器所支持的语言响应给客户端浏览器
*/
@WebServlet("/language.do")
public class LanguageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求头中所支持的语言
String header = req.getHeader("Accept-Language");
//将数据存放到Request对象中
req.setAttribute("header",header);
//使用请求转发跳转到JSP
req.getRequestDispatcher("showMsg.jsp").forward(req,resp);;
}
}
<%--
Created by IntelliJ IDEA.
User: 百里诀
Date: 2022/3/24
Time: 10: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>
<%
String header = (String) request.getAttribute("header");
%>
<font color="blue"><%= header%>></font>

</body>
</html>

5 JSP中的四大作用域对象

作用域:”数据共享的范围”,也就说数据能够在多大的范围内有效

image-20220324105659466

6 JSTL标签库

6.1 什么是JSTL标签库

JSTL(Java server pages standarded tag library,即 JSP 标准标签库)JSTL 标签是基于 JSP 页面的。这些标签可以插入在 JSP 代码中,本质上 JSTL 也是提前定义好的一组标签,这些标签封装了不同的功能,在页面上调用标签时,就等于调用了封装起来的功能。JSTL 的目标是 使 JSP 页面的可读性更强、简化 JSP 页面的设计、实现了代码复用、提高效率。

在 JSP2.0 版本后开始支持 JSTL 标签库。在使用 JSTL 标签库时需要在 JSP 中添加对应的 taglib 指令标签。

<%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core" %>

6.2 JSTL标签分类

根据 JSTL 标签所提供的功能,可以将其分为 5 个类别

6.2.1 核心标签

最常用、最重要、也是最基本的标签

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

image-20220324191407424

6.2.2 格式化标签

JSTL 格式化标签用来格式化并输出文本、日期、时间、数字

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

image-20220324191521773

6.2.3 SQL标签
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>

JSTL SQL 标签库提供了与关系型数据库(Oracle,MySQL,SQL Server 等等)进行交互的 标签。

image-20220324191627096

6.2.4 XML标签

JSTL XML 标签库提供了创建和操作 XML 文档的标签。

<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>

image-20220324191724405

6.2.5 JSTL函数

JSTL 包含一系列标准函数,大部分是通用的字符串处理函数

<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

image-20220324191809405

7 EL表达式

7.1 什么是EL表达式

EL(Expression Language)是一种表达式语言。是为了使 JSP 写起来更加简单,减少 java 代码,可以使得获取存储在 Java 对象中的数据变得非常简单。在 JSP2.0 版本后开始支持 EL 表达式。

7.2 语法结构

${表达式}

${对象.属性名}

7.3 EL表达式中的操作符

image-20220324193033972

7.4 EL表达式的隐含对象

image-20220324193105197

7.5 使用EL表达式取出作用域中的值

${pageScope.name}

${requestScope.name}

${sessionScope.name}

${applicationScope.name}

获取作用域属性中的数据时,也可以只写属性名,EL 表达式会按照 pageScope、 requestScope、sessionScope、applicationScope 的顺序查找该属性的值。

8 JSTL标签库与EL表达式的使用

8.1 JSTL标签库的使用步骤

添加 jstl.jar 与 standard.jar

在 Idea 中添加 JSTL 标签的约束文件(DTD)。

在 JSP 页面中添加 taglib 指令标签。

image-20220324194243139

image-20220324194622881

8.2 JSTL核心标签的使用

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
8.2.1 <c:if>

标签判断表达式的值,如果表达式的值为 true 则执行其主体内容。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<c:if test="${1==1}">
Hello JSTL!
</c:if>
</body>
</html>
8.2.1 <c:choose>, <c:when>, <c:otherwise>

<c:choose>标签与 Java switch 语句的功能一样,用于在众多选项中做出选择。switch 语句中有 case,而<c:choose>标签中对应有<c:when>,switch 语句中有 default,而<c:choose>标签中有<c:otherwise>。

<c:when>中如果有多个条件满足,则只会执行第一个<c:when>标签里的内容

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<c:if test="${1==1}">
Hello JSTL!
</c:if>
<c:choose>
<c:when test="${2==1}">
Hello When1!
</c:when>
<c:when test="${2==1}">
Hello When2!
</c:when>
<c:otherwise>
Hello Otherwise!
</c:otherwise>:
</c:choose>
</body>
</html>
8.2.3 <c:forEach>

迭代器,用于迭代集合

image-20220324193500430

varStatus 属性

current: 当前这次迭代的(集合中的)项

index: 当前这次迭代从 0 开始的迭代索引

count: 当前这次迭代从 1 开始的迭代计数

first: 用来表明当前这轮迭代是否为第一次迭代的标志

last: 用来表明当前这轮迭代是否为最后一次迭代的标志

begin: 属性值

end: 属性值

step: 属性值

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<c:if test="${1==1}">
Hello JSTL!
</c:if>
<c:choose>
<c:when test="${1==1}">
Hello When1!
</c:when>
<c:when test="${1==1}">
Hello When2!
</c:when>
<c:otherwise>
Hello Otherwise!
</c:otherwise>
</c:choose>

<hr/>
<c:forEach begin="0" end="9" step="2" varStatus="suibian">
ForEach.....${suibian.count},${suibian.first},${suibian.last},${suibian.index}<br/>
</c:forEach>
</body>
</html>
8.2.3.1 使用 ForEach 迭代 List

需求:

创建 Users 对象,含有 userid,username 属性。

创建一个 Servlet,在 Servlet 中创建多个 Users 对象并放到 List 集合中,在 showUsers.jsp

的页面中显示所有的 Users 对象的信息。

image-20220324202856629

@WebServlet("/findUsers.do")
public class FindUsersServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建测试数据
Users users = new Users(1,"fgrggdg");
Users users1 = new Users(2,"GFGFGFGF");

//实例化List
List<Users> list = new ArrayList<>();
list.add(users);
list.add(users1);

//将List添加request对象中
req.setAttribute("list",list);

//通过请求转发方式跳转
req.getRequestDispatcher("showUsers.jsp").forward(req,resp);

}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<table border="1" align="center">
<tr>
<th>用户ID</th>
<th>用户姓名</th>
</tr>

<c:forEach items="${list}" var="u">
<tr>
<td>${u.userid}</td>
<td>${u.username}</td>
</tr>
</c:forEach>

</table>
</body>
</html>
8.2.3.2 使用 ForEach 迭代 Map

需求:

创建 Users 对象,含有 userid,username 属性。

创建一个 Servlet,在 Servlet 中创建多个 Users 对象并放到 Map 集合中,在 showUsers2.jsp

的页面中显示所有的 Users 对象的信息。

@WebServlet("/findUser2.do")
public class FindUsers2Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建测试数据
Users users = new Users(1,"fgrggdg");
Users users1 = new Users(2,"GFGFGFGF");

//实例化Map
Map<String,Users> map = new HashMap<>();
map.put("users1",users);
map.put("users2",users1);

//将Map添加request对象中
req.setAttribute("Map",map);

//通过请求转发方式跳转
req.getRequestDispatcher("showUsers1.jsp").forward(req,resp);
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<table border="1" align="center">
<tr>
<th>Map-Key</th>
<th>用户ID</th>
<th>用户姓名</th>
</tr>

<c:forEach items="${map}" var="u">
<tr>
<td>${u.key}</td>
<td>${u.value.userid}</td>
<td>${u.value.username}</td>
</tr>
</c:forEach>
</body>
</html>

8.3 JSTL格式化标签的使用

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

8.3.1 对日期的格式化处理

<fmt:formatDate value="${data}" pattern="yyyy-MM-dd"/>

8.3.2 对数字格式化的处理

<fmt:formatNumber value="${balance}" type="currency"/>
<%--
Created by IntelliJ IDEA.
User: 百里诀
Date: 2022/3/24
Time: 20:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${date}
<hr/>
<fmt:formatDate value="${date}" pattern="yyyy-MM-dd"/>
<hr>
<fmt:formatNumber value="${balance}" type="currency"/>
</body>
</html>
@WebServlet("/format.do")
public class FormatServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("date",new Date());
req.setAttribute("balance",45645657657.765756756);
req.getRequestDispatcher("format.jsp").forward(req,resp);

}
}

四、MVC模式

1.什么是MVC模式

MVC 模式:Model、View、Controller 即模型、视图、控制器。是软件的一种架构模式 (Architecture pattern)。MVC 要实现的目标是将软件的用户界面和业务逻辑分离,可提高代码可扩展性、可复用性、可维护性、以及灵活性。

View(视图):用户的操作界面。如:html、jsp。

Model(模型):具体的业务模型与数据模型。如:service、dao、pojo。

Controller(控制):处理从视图层发送的请求,并选取模型层的业务模型完成响应的业务

实现,并产生响应。如:Servlet。

image-20220324204323698

2 MVC模式与应用程序分层的区别

MVC 模式是一种软件的架构方式,而应用程序分层这是一种代码的组织方式。MVC 模式与应用程序分层的目标都是一致的:为了解耦和、提高代码复用性。

image-20220324204354929

https://www.aliyundrive.com/s/fWBtTsfqQah 提取码: 7tb2