JSP今日目标:
理解 JSP 及 JSP 原理
能在 JSP中使用 EL表达式 和 JSTL标签
理解 MVC模式 和 三层架构
能完成品牌数据的增删改查功能
1,JSP 概述代码语言:txt复制 JSP(全称:Java Server Pages):Java 服务端页面。是一种动态的网页技术,其中既可以定义 HTML、JS、CSS等静态内容,还可以定义 Java代码的动态内容,也就是 `JSP = HTML + Java`。如下就是jsp代码代码语言:java复制
JSP,Hello World
<%
System.out.println("hello,jsp~");
%>
上面代码 h1 标签内容是展示在页面上,而 Java 的输出语句是输出在 idea 的控制台。
那么,JSP 能做什么呢?现在我们只用 servlet 实现功能,看存在什么问题。如下图所示,当我们登陆成功后,需要在页面上展示用户名
在这里插入图片描述上图的用户名是动态展示,也就是谁登陆就展示谁的用户名。只用 servlet 如何实现呢?在今天的资料里已经提供好了一个 LoginServlet ,该 servlet 就是实现这个功能的,现将资料中的 LoginServlet.java 拷贝到 request-demo 项目中来演示。接下来启动服务器并访问登陆页面
在这里插入图片描述输入了 zhangsan 用户的登陆信息后点击 登陆 按钮,就能看到如下图效果
在这里插入图片描述当然如果是 lisi 登陆的,在该页面展示的就是 lisi,欢迎您,动态的展示效果就实现了。那么 LoginServlet 到底是如何实现的,我们看看它里面的内容
在这里插入图片描述看完代码,我们可以发现,上面的代码有大量使用到 writer
对象向页面写标签内容,这样我们的代码就显得很麻烦;将来如果展示的效果出现了问题,排错也显得有点力不从心,那我们一个怎样避免出现此类问题呢。
在资料中也提供了一个 login.jsp 页面,该页面也能实现该功能,现将该页面拷贝到项目的 webapp下,需要修改
login.html 中表单数据提交的路径为下图
在这里插入图片描述重新启动服务器并进行测试,发现也可以实现同样的功能。来看看 login.jsp 是如何实现的
在这里插入图片描述上面代码可以看到里面基本都是 HTML 标签,而动态数据使用 Java 代码进行展示;这样操作看起来要比用 servlet 实现要舒服很多。
JSP 作用:简化开发,避免了在Servlet中直接输出HTML标签。
2,JSP 快速入门接下来我们做一个简单的快速入门代码。
2.1 搭建环境创建一个maven的 web 项目,项目结构如下:
在这里插入图片描述pom.xml 文件内容如下:
代码语言:html复制
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
代码语言:html复制
该依赖的 scope 必须设置为 provided,因为 tomcat
中有这个jar包了,所以在打包时我们是不希望将该依赖打进到我们工程的war包中。
2.3 创建 jsp 页面在项目的 webapp 下创建jsp页面
在这里插入图片描述通过上面方式创建一个名为 hello.jsp 的页面。
2.4 编写代码在 hello.jsp 页面中书写 HTML 标签和 Java 代码,如下
代码语言:java复制<%@ page contentType="text/html;charset=UTF-8" language="java" %>
hello jsp
<%
System.out.println("hello,jsp~");
%>
2.5 测试启动服务器并在浏览器地址栏输入 http://localhost:8080/jsp-demo/hello.jsp,我们可以在页面上看到如下内容
在这里插入图片描述同时也可以看到在 idea 的控制台看到输出的 hello,jsp~ 内容。
3,JSP 原理我们之前说 JSP 就是一个页面,那么在 JSP 中写 html 标签,我们能理解,但是为什么还可以写 Java 代码呢?
因为 ==JSP 本质上就是一个 Servlet。==接下来我们聊聊访问jsp时的流程
在这里插入图片描述浏览器第一次访问 hello.jsp 页面tomcat 会将 hello.jsp 转换为名为 hello_jsp.java 的一个 Servlettomcat 再将转换的 servlet 编译成字节码文件 hello_jsp.classtomcat 会执行该字节码文件,向外提供服务我们可以到项目所在磁盘目录下找 target\tomcat\work\Tomcat\localhost\jsp-demo\org\apache\jsp 目录,而这个目录下就能看到转换后的 servlet
打开 hello_jsp.java 文件,来查看里面的代码

由上面的类的继承关系可以看到继承了名为 HttpJspBase 这个类,那我们在看该类的继承关系。到资料中的找如下目录: 资料\tomcat源码\apache-tomcat-8.5.68-src\java\org\apache\jasper\runtime ,该目录下就有 HttpJspBase 类,查看该类的继承关系,可以看到该类继承了 HttpServlet ;那么 hello_jsp 这个类就间接的继承了 HttpServlet ,也就说明 hello_jsp 是一个 servlet。
继续阅读 hello_jsp 类的代码,可以看到有一个名为 _jspService() 的方法,该方法就是每次访问 jsp 时自动执行的方法,和 servlet 中的 service 方法一样 。
而在 _jspService() 方法中可以看到往浏览器写标签的代码:
在这里插入图片描述以前我们自己写 servlet 时,这部分代码是由我们自己来写,现在有了 jsp 后,由tomcat完成这部分功能。这就是我们使用JSP的原因
4,JSP 脚本JSP脚本用于在 JSP页面内定义 Java代码。在之前的入门案例中我们就在 JSP 页面定义的 Java 代码就是 JSP 脚本。
4.1 JSP 脚本分类JSP 脚本有如下三个分类:
<%...%>:内容会直接放到_jspService()方法之中<%=…%>:内容会放到out.print()中,作为out.print()的参数<%!…%>:内容会放到_jspService()方法之外,被类直接包含代码演示:
在 hello.jsp 中书写
代码语言:java复制<%
System.out.println("hello,jsp~");
int i = 3;
%>通过浏览器访问 hello.jsp 后,查看转换的 hello_jsp.java 文件,i 变量定义在了 _jspService() 方法中
在这里插入图片描述在 hello.jsp 中书写
代码语言:java复制<%="hello"%>
<%=i%>通过浏览器访问 hello.jsp 后,查看转换的 hello_jsp.java 文件,该脚本的内容被放在了 out.print() 中,作为参数
在这里插入图片描述在 hello.jsp 中书写
代码语言:java复制<%!
void show(){}
String name = "zhangsan";
%>通过浏览器访问 hello.jsp 后,查看转换的 hello_jsp.java 文件,该脚本的内容被放在了成员位置
在这里插入图片描述5,EL 表达式5.1 概述EL(全称Expression Language )表达式语言,用于简化 JSP 页面内的 Java 代码。
EL 表达式的主要作用是 ==获取数据==。其实就是从域对象中获取数据,然后将数据展示在页面上。
而 EL 表达式的语法也比较简单,== ${expression}== 。例如:$${brands} 就是获取域中存储的 key 为 brands 的数据。
5.2 代码演示定义servlet,在 servlet 中封装一些数据并存储到 request 域对象中并转发到 el-demo.jsp 页面。代码语言:java复制 @WebServlet("/demo1")
public class ServletDemo1 extends HttpServlet {
代码语言:txt复制 @Override代码语言:txt复制 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {代码语言:txt复制 //1. 准备数据代码语言:txt复制 List
代码语言:txt复制==注意:== 此处需要用转发,因为转发才可以使用 request 对象作为域对象进行数据共享
在 el-demo.jsp 中通过 EL表达式 获取数据代码语言:java复制 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
代码语言:txt复制
代码语言:txt复制 ${brands}
代码语言:txt复制在浏览器的地址栏输入 http://localhost:8080/jsp-demo/demo1 ,页面效果如下:在这里插入图片描述5.3 域对象JavaWeb中有四大域对象,分别是:
page:当前页面有效request:当前请求有效session:当前会话有效application:当前应用有效el 表达式获取数据,会依次从这4个域中寻找,直到找到为止。而这四个域对象的作用范围如下图所示
在这里插入图片描述例如: ${brands},el 表达式获取数据,会先从page域对象中获取数据,如果没有再到 requet
域对象中获取数据,如果再没有再到 session 域对象中获取,如果还没有才会到 application 中获取数据。
6,JSTL标签6.1 概述JSP标准标签库(Jsp Standarded Tag Library) ,使用标签取代JSP页面上的Java代码。如下代码就是JSTL标签
代码语言:java复制
男
女
上面代码看起来是不是比 JSP 中嵌套 Java 代码看起来舒服好了。而且前端工程师对标签是特别敏感的,他们看到这段代码是能看懂的。
JSTL 提供了很多标签,如下图
在这里插入图片描述我们只对两个最常用的标签进行讲解,
JSTL 使用也是比较简单的,分为如下步骤:
导入坐标代码语言:html复制
代码语言:txt复制
代码语言:txt复制
代码语言:txt复制在JSP页面上引入JSTL标签库代码语言:java复制 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
代码语言:txt复制使用标签6.2 if 标签
属性:test,用于定义条件表达式代码语言:java复制
男
女
代码演示:
定义一个 servlet ,在该 servlet 中向 request 域对象中添加 键是 status ,值为 1 的数据代码语言:java复制 @WebServlet("/demo2")
public class ServletDemo2 extends HttpServlet {
代码语言:txt复制 @Override代码语言:txt复制 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {代码语言:txt复制 //1. 存储数据到request域中代码语言:txt复制 request.setAttribute("status",1);代码语言:txt复制 //2. 转发到 jstl-if.jsp代码语言:txt复制 数据request.getRequestDispatcher("/jstl-if.jsp").forward(request,response);代码语言:txt复制 }代码语言:txt复制 @Override代码语言:txt复制 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {代码语言:txt复制 this.doGet(request, response);代码语言:txt复制 } }
代码语言:txt复制定义 jstl-if.jsp 页面,在该页面使用
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
代码语言:txt复制
代码语言:txt复制 <%--代码语言:txt复制 c:if:来完成逻辑判断,替换java if else代码语言:txt复制 --%>代码语言:txt复制
代码语言:txt复制==注意:== 在该页面已经要引入 JSTL核心标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
6.3 forEach 标签
6.3.1 用法一类似于 Java 中的增强for循环。涉及到的
items:被遍历的容器var:遍历产生的临时变量varStatus:遍历状态对象如下代码,是从域对象中获取名为 brands 数据,该数据是一个集合;遍历遍历,并给该集合中的每一个元素起名为 brand,是 Brand对象。在循环里面使用 EL表达式获取每一个Brand对象的属性值
代码语言:java复制
代码演示:
servlet 还是使用之前的名为 ServletDemo1 。定义名为 jstl-foreach.jsp 页面,内容如下:代码语言:java复制 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
代码语言:txt复制 代码语言:txt复制
| 序号 | 代码语言:txt复制品牌名称 | 代码语言:txt复制企业名称 | 代码语言:txt复制排序 | 代码语言:txt复制品牌介绍 | 代码语言:txt复制状态 | 代码语言:txt复制操作 | 代码语言:txt复制||
|---|---|---|---|---|---|---|---|---|
| ${brand.id} | --%>代码语言:txt复制${status.count} | 代码语言:txt复制${brand.brandName} | 代码语言:txt复制${brand.companyName} | 代码语言:txt复制${brand.ordered} | 代码语言:txt复制${brand.description} | 代码语言:txt复制启用 | 代码语言:txt复制禁用 | 代码语言:txt复制修改 删除 | 代码语言:txt复制
代码语言:txt复制6.3.2 用法二类似于 Java 中的普通for循环。涉及到的
begin:开始数end:结束数step:步长实例代码:
从0循环到10,变量名是 i ,每次自增1
代码语言:java复制
${i}
7,MVC模式和三层架构MVC 模式和三层架构是一些理论的知识,将来我们使用了它们进行代码开发会让我们代码维护性和扩展性更好。
7.1 MVC模式MVC 是一种分层开发的模式,其中:
M:Model,业务模型,处理业务
V:View,视图,界面展示
C:Controller,控制器,处理请求,调用模型和视图
在这里插入图片描述控制器(serlvlet)用来接收浏览器发送过来的请求,控制器调用模型(JavaBean)来获取数据,比如从数据库查询数据;控制器获取到数据后再交由视图(JSP)进行数据展示。
MVC 好处:
职责单一,互不影响。每个角色做它自己的事,各司其职。有利于分工协作。有利于组件重用7.2 三层架构三层架构是将我们的项目分成了三个层面,分别是 表现层、业务逻辑层、数据访问层。
在这里插入图片描述数据访问层:对数据库的CRUD基本操作业务逻辑层:对业务逻辑进行封装,组合数据访问层层中基本功能,形成复杂的业务逻辑功能。例如 注册业务功能 ,我们会先调用 数据访问层 的 selectByName() 方法判断该用户名是否存在,如果不存在再调用 数据访问层 的 insert() 方法进行数据的添加操作表现层:接收请求,封装数据,调用业务逻辑层,响应数据而整个流程是,浏览器发送请求,表现层的Servlet接收请求并调用业务逻辑层的方法进行业务逻辑处理,而业务逻辑层方法调用数据访问层方法进行数据的操作,依次返回到serlvet,然后servlet将数据交由 JSP 进行展示。
三层架构的每一层都有特有的包名称:
表现层: com.itheima.controller 或者 com.itheima.web业务逻辑层:com.itheima.service数据访问层:com.itheima.dao 或者 com.itheima.mapper后期我们还会学习一些框架,不同的框架是对不同层进行封装的
image.png7.3 MVC 和 三层架构通过 MVC 和 三层架构 的学习,有些人肯定混淆了。那他们有什么区别和联系?
image.png如上图上半部分是 MVC 模式,上图下半部分是三层架构。 MVC 模式 中的 C(控制器)和 V(视图)就是 三层架构 中的表现层,而 MVC 模式 中的 M(模型)就是 三层架构 中的 业务逻辑层 和 数据访问层。
可以将 MVC 模式 理解成是一个大的概念,而 三层架构 是对 MVC 模式 实现架构的思想。 那么我们以后按照要求将不同层的代码写在不同的包下,每一层里功能职责做到单一,将来如果将表现层的技术换掉,而业务逻辑层和数据访问层的代码不需要发生变化。