Java Web学习 JSP
1 JSP 概述
(1) JSP(全称:Java Server Pages):Java 服务端页面。是一种动态的网页技术,其中既可以定义 HTML、JS、CSS等静态内容,还可以定义 Java代码的动态内容,也就是 JSP = HTML + Java 。
(2) JSP 作用:简化开发,避免了在Servlet中直接输出HTML标签。
<!-- 不必再使用response对象来获取输出流,使用输出流写入html拼字符串 -->
2 JSP 快速入门
(1) 导入 JSP 依赖
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
<!-- 该依赖的 scope 必须设置为 provided ,因为 tomcat 中有这个jar包了,所以在打包时不应该将该依赖打进到工程的war包中。 -->
</dependency>
(2) 创建 jsp 页面
在项目的webapp下创建jsp页面,创建一个名为hello.jsp的页面。
(3) 编写代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>hello jsp</h1>
<%
System.out.println("hello,jsp~");
%>
</body>
</html>
(4) 测试
启动服务器并在浏览器地址栏输入 http://localhost:8080/jsp-demo/hello.jsp
3 JSP 原理
<!--JSP就是一个页面,在JSP中写html标签,但JSP本质上是一个Servlet。-->
(1) 浏览器第一次访问hello.jsp页面
(2) tomcat会将hello.jsp转换为名为hello_jsp.java的一个Servlet
(3) tomcat再将转换的servlet编译成字节码文件hello_jsp.class
(4) tomcat会执行该字节码文件,向外提供服务
<!-- 我们可以到项目所在磁盘目录下找 target\tomcat\work\Tomcat\localhost\jsp-demo\org\apache\jsp 目录,而这个目录下就能看到转换后的
servlet -->
<!-- 转化后的Servlet类继承了HttpJspBase类,HttpJspBase类继承了HttpServlet,那么转化后的Servlet类就间接的继承了HttpServlet,也就说明JSP文件是一个servlet 。 -->
<!-- 转化后的Servlet类有一个名为_jspService()的方法,该方法就是每次访问jsp时自动执行的方法,和servlet中的service方法一样。 -->
<!-- _jspService()方法中往浏览器写标签的代码,仍是由out.write()实现,out.write()底层仍是response对象获取输入流。 -->
4 JSP 脚本
<!-- JSP页面定义的Java代码就是JSP脚本。 -->
(1) JSP 脚本分类
<%...%>:内容会直接放到_jspService()方法之中
<!-- 即要被执行的代码 -->
<%=…%>:内容会放到out.print()中,作为out.print()的参数
<!-- 相当输出到JSP页面的System.out.print() -->
<%!…%>:内容会放到_jspService()方法之外,被类直接包含
<!-- 相当于设置为转化后的Servlet类的属性,或方法 -->
(2) JSP脚本可以被截断
<%
for (int i = 0; i < brands.size(); i++) {
//获取集合中的 每一个 Brand 对象
Brand brand = brands.get(i);
%>
<tr align="center">
<td>1</td>
<td>三只松鼠</td>
<td>三只松鼠</td>
<td>100</td>
<td>三只松鼠,好吃不上火</td>
<td>启用</td>
<td><a href="#">修改</a> <a href="#">删除</a></td>
</tr>
<%
}
%>
5 JSP 缺点
(1) 由于 JSP页面内,既可以定义 HTML 标签,又可以定义 Java代码,造成了以下问题:
<1> 书写麻烦:既要写 HTML 标签,还要写 Java 代码
<2> 阅读麻烦:看代码时需要花费很长的时间去梳理
<3> 复杂度高:运行需要依赖于各种环境,JRE,JSP容器,JavaEE…
<4> 占内存和磁盘:JSP会自动生成.java和.class文件占磁盘,运行的是.class文件占内存
<5> 调试困难:出错后,需要找到自动生成的.java文件进行调试
<6> 不利于团队协作:前端人员不会 Java,后端人员不精 HTML
(2) 技术发展(如何处理动态资源)
<1> 第一阶段Servlet:使用 servlet 即实现逻辑代码编写,也对页面进行拼接。
<2> 第二阶段JSP:随着技术的发展,出现了 JSP ,人们发现 JSP 使用起来比 Servlet 方便很多,但是还是要在 JSP 中嵌套Java代码。
<3> 第三阶段Servlet+JSP:使用 Servlet 进行逻辑代码开发,而使用 JSP 进行数据展示
<!-- Servlet进行逻辑处理,封装数据,通过request域请求转发给JSP;JSP获取数据,遍历展现数据,尽可能少的在JSP中写Java代码。 -->
<4> 第四阶段Servlet+html+ajax:使用 servlet 进行后端逻辑代码开发,而使用 HTML 进行数据展示(使用ajax)。
6 EL 表达式
<!-- 目的:尽可能减少展示数据所使用的Java代码 -->
(1) 概述
<1> EL(全称Expression Language )表达式语言,用于简化 JSP 页面内的 Java 代码。<!-- ${}内的变量若为空,则不显示数据。 -->
<2> EL 表达式的主要作用是 获取数据。其实就是从域对象中**获取数据**,然后将数据**展示在页面上**。
<3> 而 EL 表达式的语法也比较简单,${expression} 。例如:${brands} 就是获取域中存储的 key 为 brands 的数据。${cookie.key.value}获取cookie中键为key的value
<!-- 该EL表达式中只有key为变量 -->
<!--注意这个地方el表达式中写的变量名要和Servlet中存储到request域里的变量名一致,不然页面会是空白的-->
<!-- 通过EL表达式获取request域共享的数据时,在jsp页面上需要设置<%@ page isELIgnored="false"%>默认情况下是 <%@ page isELIgnored="true"%> ,会将jsp页面的数据直接进行字符处理,否则jsp会忽略EL表达式。 -->
(2) 域对象
<1> JavaWeb中有四大域对象,分别是:page:当前页面有效request:当前请求有效session:当前会话有效application:当前应用有效
<2> el 表达式获取数据,会依次从这4个域中寻找,直到找到为止。
例如: ${brands},el 表达式获取数据,会先从page域对象中获取数据,如果没有再到 requet 域对象中获取数据,如果再没有再到 session域对象中获取,如果还没有才会到 application 中获取数据。
<!-- ${}代表为可执行的部分,${}之外的部分会当作字符串处理 -->
<!-- ${}既有输出功能也有当作变量的功能 -->
7 JSTL标签
<!-- 目的:取代JSP内Java代码中的for和if -->
(1) 概述
JSP标准标签库(Jsp Standarded Tag Library) ,使用标签取代JSP页面上的Java代码
(2) JSTL 使用
<1> 导入坐标
<dependency>
<!-- JSTL坐标 -->
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<!-- 标准标签库 -->
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<2> 在JSP页面上引入JSTL标签库<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- prefix的值随意,但建议是c -->
<!-- 注意这个地方是uri不是url -->
<3> 使用标签
(3) if 标签
<1> <c:if> :相当于 if 判断,属性如下:test:用于定义条件表达式
<2> 代码实现
<c:if test="${flag == 1}">
<!-- ${}代表为可执行的部分,${}之外的部分会当作字符串处理 -->
男
</c:if>
<c:if test="${flag == 2}">
女
</c:if>
(4) forEach 标签
<1> <c:forEach> :相当于 for 循环。java中有增强for循环和普通for循环,JSTL 中的 <c:forEach> 也有两种用法
<2> 用法一
<2.1> 类似于 Java 中的增强for循环。涉及到的 <c:forEach> 中的属性如下items:被遍历的容器var:遍历产生的临时变量varStatus:遍历状态对象
<2.2> 代码实现
<c:forEach items="${brands}" var="brand" varStatus="status">
<tr align="center">
<td>${status.count}</td>
<!-- status.count排序从1开始;status.index排序从0开始 -->
<td>${brand.brandName}</td>
<!-- 并非调用brand的属性,而是调用其get方法。 -->
<!-- JSP会自动解析,首先将brandName首字母大写,然后加上get,自动调用其getBrandName()方法。 -->
<td>${brand.companyName}</td>
<td>${brand.ordered}</td>
<td>${brand.description}</td>
<c:if test="${brand.status == 1}">
<td>启用</td>
</c:if>
<c:if test="${brand.status != 1}">
<td>禁用</td>
</c:if>
<td><a href="#">修改</a> <a href="#">删除</a></td>
</tr>
</c:forEach>
<3> 用法二
<3.1> 类似于 Java 中的普通for循环。涉及到的 <c:forEach> 中的属性如下begin:开始数
<!-- 相当于i=? -->end:结束数
<!-- 相当于i<? -->step:步长
<!-- 相当于i++ -->var:相当于i
<3.2> 代码实现
<c:forEach begin="0" end="10" step="1" var="i">
<!-- var的变量名随意 -->
${i}
</c:forEach>
8 MVC模式和三层架构
(1) MVC模式
<1> MVC 是一种分层开发的模式,其中:
M:Model,业务模型,处理业务
V:View,视图,界面展示
C:Controller,控制器,处理请求,调用模型和视图
<2> 流程
控制器(serlvlet)用来接收浏览器发送过来的请求,控制器调用模型(JavaBean)来获取数据,比如从数据库查询数据;
控制器获取到数据后再交由视图(JSP)进行数据展示。
<3> MVC 好处:
<3.1> 职责单一,互不影响。每个角色做它自己的事,各司其职。
<3.2> 有利于分工协作。
<3.3> 有利于组件重用
(2) 三层架构
<1> 三层架构是将我们的项目分成了三个层面,分别是 表现层 、 业务逻辑层 、 数据访问层
<1.1> 数据访问层(别名持久层、dao层):对数据库的CRUD基本操作
<1.2> 业务逻辑层(别名业务层、service层):对业务逻辑进行封装,组合数据访问层层中基本功能,形成复杂的业务逻辑功能。例如 注册业务功能 ,我们会先调用 数据访问层 的 selectByName() 方法判断该用户名是否存在,如果不存在再调用 数据访问层 的 insert()方法进行数据的添加操作
<1.3> 表现层(别名web层):接收请求,封装数据,调用业务逻辑层,响应数据
<2> 流程
浏览器发送请求,表现层的Servlet接收请求并调用业务逻辑层的方法进行业务逻辑处理,而业务逻辑层方法调用数据访问层方法进行数据的操作,依次返回到serlvet,然后servlet将数据交由 JSP 进行展示。
<3> 三层架构的每一层都有特有的包名称:
<3.1> 表现层: com.itheima.controller 或者 com.itheima.web
<3.2> 业务逻辑层: com.itheima.service
<3.3> 数据访问层: com.itheima.dao 或者 com.itheima.mapper
(3) MVC 和 三层架构
MVC 模式 中的 C(控制器)和 V(视图)就是 三层架构 中的表现层,而 MVC 模式 中的 M(模型)就是 三层架构 中的 业务逻辑层 和 数据访问层。可以将 MVC 模式 理解成是一个大的概念,而 三层架构 是对 MVC 模式 实现架构的思想。 那么我们以后按照要求将不同层的
代码写在不同的包下,每一层里功能职责做到单一,将来如果将表现层的技术换掉,而业务逻辑层和数据访问层的代码不需要发生变化。

浙公网安备 33010602011771号