JavaWeb 学习笔记 5:JSP

news2025/4/16 9:58:30

JavaWeb 学习笔记 5:JSP

简单的说,JSP 就是 Java + Html,JSP 的出现是为了让 Java Web 应用生成动态页面更容易。

1.快速开始

1.1.依赖

添加 JSP 依赖:

<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.2</version>
    <scope>provided</scope>
</dependency>

servlet-api 的依赖类似,jsp-api 依赖同样存在于 Tomcat 中,所以这里范围要设置为provided

1.2.JSP

/rwebapp 目录中添加一个简单的 JSP 文件 hello.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <h1>hello</h1>
    <% System.out.println("hello"); %>
</head>
<body>

</body>
</html>

<% ... %>标签中的是 Java 脚本。

访问 http://localhost:8080/login-demo/hello.jsp 就能看到h1标签中的内容,同时服务端控制台也会输出信息。

1.3.原理

JSP 本质上就是一个 Servlet,在项目运行后,/target/tomcat/work目录下会生成一个hello_jsp.java文件:

public final class hello_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {
    // ...
}

这个文件实际上就是 Tomcat 在收到hello.jsp的请求后,将hello.jsp”翻译“为一个 Servlet 类。

查阅 Tomcat 的 API 文档 可以知道,这个类实际上就是HttpServlet的子类:

public abstract class HttpJspBase
extends HttpServlet
implements HttpJspPage{
    // ...
}

它有一个_jspService()方法,负责处理 HTTP 请求,其主要内容是输出 JSP 中的 HTML 内容以及执行其中的 Java 脚本:

public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
    throws java.io.IOException, javax.servlet.ServletException {
    // ...
    out.write("\r\n");
    out.write("\r\n");
    out.write("<html>\r\n");
    out.write("<head>\r\n");
    out.write("    <title>Title</title>\r\n");
    out.write("    <h1>hello</h1>\r\n");
    out.write("    ");
    System.out.println("hello"); 
    out.write("\r\n");
    out.write("</head>\r\n");
    out.write("<body>\r\n");
    out.write("\r\n");
    out.write("</body>\r\n");
    out.write("</html>\r\n");
    // ...
}

当然,Tomcat 生成的 Java 文件同样要编译为字节码(.class)才能执行。

整个过程可以表示为:

image-20210818111039350

2.JSP 脚本

JSP 脚本有三种类型:

  • <% ... %>,脚本中的 Java 代码将在_jspService方法中执行。
  • <%= ... %>,脚本中的 java 表达式的运行结果将作为out.print()方法的参数输出到 Html 页面中。
  • <%! ... %>,脚本中的 Java 代码将作为 Tomcat 生成的 Servlet 的成员变量或成员方法。

第一种之前已经看到过,这里看后两种。

在 JSP 中添加:

<div>
    当前时间:
    <%= LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) %>
</div>

请求 JSP 页面就能看到显示的时间,这个时间是服务端的 JSP 脚本生成并写入 Html 中的。

/target/Tomcat/.../hello_jsp.java_jspService方法中可以看到:

out.print( LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) );

还可以用<% ... %>定义的局部变量进行输出,比如:

<div>
    <% LocalDateTime now = LocalDateTime.now(); %>
    当前时间:
    <%= now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) %>
</div>

可以用<%! ... %>定义成员方法,并由<% ... %><%= ... %>中的 Java 代码调用:

<%!
    String getNowTimeStr(){
    return LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
}
%>
<div>
    当前时间:
    <%= this.getNowTimeStr() %>
</div>

3.案例:品牌列表页

在下面的案例中,用 JSP 实现一个简单的品牌列表展示页面。

先导入表结构和测试数据 tb_brand.sql。

用 MyBatis 实现持久层和服务层。

实现用于展示品牌列表的 JSP 页面 brand.jsp

<%@ page import="cn.icexmoon.logindemo.service.BrandService" %>
<%@ page import="cn.icexmoon.logindemo.service.impl.BrandServiceImpl" %>
<%@ page import="cn.icexmoon.logindemo.entity.Brand" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<input type="button" value="新增"><br>
<hr>
<%
  BrandService brandService = new BrandServiceImpl();
  List<Brand> brands = brandService.getAllBrands();
%>
<table border="1" cellspacing="0" width="800">
  <tr>
    <th>序号</th>
    <th>品牌名称</th>
    <th>企业名称</th>
    <th>排序</th>
    <th>品牌介绍</th>
    <th>状态</th>
    <th>操作</th>
  </tr>
  <% for(Brand b : brands){ %>
  <tr align="center">
    <td><%= b.getId() %></td>
    <td><%= b.getBrandName() %></td>
    <td><%= b.getCompanyName() %></td>
    <td><%= b.getOrdered() %></td>
    <td><%= b.getDescription() %></td>
    <td>
      <% if(b.getStatus()==0){ %>
      启用
      <% }else{ %>
      禁用
      <% } %>
    </td>
    <td><a href="#">修改</a> <a href="#">删除</a></td>
  </tr>
  <% } %>
</table>

</body>
</html>

在 JSP 中调用了服务层的代码,需要使用<%@ page import="..." %>导入到 Tomcat 生成的 Servlet 类中。

此外获取到品牌列表数据后,这里通过循环遍历的方式输出表格内容。

4.EL 和 JSTL

将 Java 代码和 HTML 混合起来的 JSP 并不是一个好的解决方案,可读性差。MVC 思想中,将视图(页面展示)和数据准备分离是很重要的一条原则。当然使用 JSP 也可以实现视图和数据的分离,比如将数据准备放在 Servlet 中,在 JSP 中加载数据和页面渲染。

但是加载数据和页面渲染同样要使用 JSP 脚本,可以使用 EL 和 JSTL 两种技术来进行简化。

4.1.EL 表达式

EL(Expression Language,表达式语言)用于简化在 JSP 中获取数据的操作。

EL 中,可以用${name}表示一个名称为name的域属性值。这里所谓的”域“分为以下几种:

  • page:当前页面
  • request,当前请求
  • session,当前会话
  • application,当前应用

我们之前使用的HttpServletRequest.setAttribute就是设置request域的属性,request域的属性对当前 HTTP 请求都有效,所以可以用于多个 Servlet 流转时传递信息。

一个简单示例:

@WebServlet("/brand/list")
public class ListController extends HttpServlet {
    private BrandService brandService = new BrandServiceImpl();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        List<Brand> brands = brandService.getAllBrands();
        request.setAttribute("brands", brands);
        request.getRequestDispatcher("/demo.jsp").forward(request, response);
    }
	// ...
}

demo.jsp 的内容:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@page isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${brands}
</body>
</html>

这里<%@page isELIgnored="false" %>是为了开启 EL 表达式解析功能。

此时请求 /brand/list 就能在页面上直接打印我们传递的List对象了。

查看 Tomcat 生成的 demo_jsp.java

out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${brands}", java.lang.String.class, (javax.servlet.jsp.PageContext)_jspx_page_context, null, false));

可以看到是将${brands}作为 EL表达式解析,以获取属性值。

如果 EL 表达式不起作用,可以检查 web.xml 中的web-app版本,在低版本中默认不开启 EL 表达式。具体相关内容可以阅读这篇文章。

这里获取属性值的规则是按照域的大小从小到大获取:

image-20210818152857407

即先检查 Page 中有没有该名称的属性,再检查 Request,以此类推,直到找到为止。

4.2.JSTL

JSTL(Jsp Standard Tag Library,JSP 标准标签库)是用于取代 JSP 中常见 Java 代码的一组标签库。

要使用 JSTL 需要引用依赖:

<dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
<dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
</dependency>

使用 JSTL 标签替换 JSP 脚本:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<input type="button" value="新增"><br>
<hr>
<table border="1" cellspacing="0" width="800">
  <tr>
    <th>序号</th>
    <th>品牌名称</th>
    <th>企业名称</th>
    <th>排序</th>
    <th>品牌介绍</th>
    <th>状态</th>
    <th>操作</th>
  </tr>
<c:forEach items="${brands}" var="b">
  <tr align="center">
    <td>${b.id}</td>
    <td>${b.brandName}</td>
    <td>${b.companyName}</td>
    <td>${b.ordered}</td>
    <td>${b.description}</td>
    <td>
      <c:if test="${b.status==0}">
        启用
      </c:if>
      <c:if test="${b.status==1}">
        禁用
      </c:if>
    </td>
    <td><a href="#">修改</a> <a href="#">删除</a></td>
  </tr>
</c:forEach>
</table>
</body>
</html>

JSP 的内容简略了很多,并且可读性更强,更接近于 HTML 的风格。

更多的 JSTL 标签介绍可以阅读这里。

5.案例:对品牌的增加、删除和修改

用上边介绍的内容可以在之前示例的基础上进一步实现对品牌的增加、删除和修改。

实现并不复杂,可以查看视频我参考我实现的完整示例。

The End,谢谢阅读。

本文的完整示例可以从这里获取。

6.参考资料

  • 彻底解决IDEA编写jsp时EL表达式不起作用的问题_千篇不一律的博客-CSDN博客
  • JSP 标准标签库(JSTL) | 菜鸟教程 (runoob.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1028058.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为云云耀云服务器L实例评测|使用docker部署禅道系统

大家好&#xff0c;我是早九晚十二&#xff0c;目前是做运维相关的工作。写博客是为了积累&#xff0c;希望大家一起进步&#xff01; 我的主页&#xff1a;早九晚十二 文章目录 前言准备工作华为云账号注册充值、购买服务器 服务器操作密码修改登录远程工具 禅道部署简介 部署…

【校招VIP】java语言考点之序列化

考点介绍&#xff1a; 将java对象转换为字节序列的过程称为对象的序列化。对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上&#xff0c;通常存放在一个文件中。 2) 在网络上传送对象的字节序列。 java语言考点之序列化-相关题目及解析内容可点击文章末尾链…

PyCharm:No Python interpreter configured for the project

一、问题概述 Your 的 Pycharm 软件创建完项目后&#xff0c;结果无法运行&#xff0c;观察后&#xff0c;在Pycharm代码编辑区上面出现了这样的一个黄色条提示&#xff1a;No Python interpreter configured for the project 【问题】在您的Python项目中无Python解释器…

金融业需要的大模型,是一个系统化工程

今年年初&#xff0c;在AIGC刚刚开始爆火的时候&#xff0c;我们曾经采访过一位AI领域的专家。当我们提问哪个行业将率先落地大模型时&#xff0c;他毫不犹豫地说道&#xff1a;“金融。” 金融行业场景多、数据多、知识多&#xff0c;这样的“三多”特点让其成为AI大模型发挥价…

yarn安装依赖时报错 error An unexpected error occurred:

一切起因是因为前一天安装了volta管理node&#xff0c;第二天启动项目&#xff0c; 显示error An unexpected error occurred: “https://registry.npmmirror.com/webpack-aliyun-oss/-/webpack-aliyun-oss-0.2.6.tgz: Request failed “404 Not Found””. 项目启动时发现报错…

Selenium Grid 的搭建方法

传统 Selenium Grid 的搭建方法 搭建一个具有 1 个 Node 的 Selenium Grid。那么通常来讲我们需要 2 台机器&#xff0c;其中一台作为 Hub&#xff0c;另外一台作为 Node&#xff0c;并要求这两台机器已经具备了 Java 执行环境。 1.通过官网下载 selenium-server-standalone-…

Java 21 发布,新功能助力开发更高效

Java 21 是 Java SE 平台的最新长期支持 (LTS) 版本&#xff0c;于 2023 年 9 月 19 日发布。它包括了一系列新功能和改进&#xff0c;可以让开发人员编写更高效、更可靠、更安全的 Java 应用程序。 新功能亮点 Java 21 的新功能包括&#xff1a; 虚拟线程&#xff1a;虚拟线程…

【 Tkinter界面-练习05】 event和bind

一、说明 事件和动作有关&#xff1b;所有的界面都与运动有关&#xff0c;本篇将对事件、事件触发、绑定回调函数等&#xff0c;其实是一系列部件配合的复杂的过程&#xff0c;这些过程牵扯到系统如何设计&#xff0c;线程、消息队列循环等。本篇将详细介绍各种因素的关系。 二…

BCC源码编译和安装

接前一篇文章&#xff1a;BCC源码下载 1. 进入源码根目录 进入到BCC源码根目录。命令及结果如下&#xff1a; $ cd bcc ~/eBPF/BCC/bcc$ ls cmake CONTRIBUTING-SCRIPTS.md docs images libbpf-tools man scripts src CMakeLists.txt …

Matlab论文插图绘制模板第115期—带Latex公式的图

之前的文章中&#xff0c;分享了Matlab带线标记的图&#xff1a; 带阴影标记的图&#xff1a; 带箭头标记的图&#xff1a; 带图形标记的图&#xff1a; 进一步&#xff0c;分享一下带Latex公式的图&#xff0c;先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『…

http1和http2的主要区别

主要有四个方面&#xff1a; 二进制分帧多路复用服务器主动推送头部压缩 将前两点结合来说&#xff0c;首先 二进制分帧 帧&#xff1a;HTTP/2 数据通信的最小单位&#xff1b; 消息&#xff1a;HTTP/2 中&#xff0c;例如在请求和响应等操作中&#xff0c;消息由一个或多个…

赛宁党支部赴延安开展革命旧址学习主题党日活动

为深入学习贯彻新时代中国特色社会主义思想和中共二十大精神&#xff0c;不断提升党支部成员综合素质和业务能力&#xff0c;2023年9月&#xff0c;赛宁公司党支部组织北京、南京、广州等三地部分党员及入党积极分子开展了“革命旧址学习”主题党日活动&#xff0c;深入寻访延安…

TongWeb8下应用忙碌线程监控

问题 &#xff1a; 在系统运行过程中发现TongWeb进程占用CPU过高&#xff0c;需要分析是应用哪里引起的问题。 分析过程(仅限Linux环境)&#xff1a; 1. 通过top命令查看TongWeb的java进程占用的CPU情况。 查看误区&#xff1a;不要以为java进程CPU占到398%就是高&#xff0…

Java基于微信小程序的青少年健康心理科普平台

第一章 简介 青少年心理健康科普平台为用户提供心理医生咨询服务&#xff0c;系统包括微信小程序端和后台。 微信小程序用户可以先进行注册&#xff0c;填写个人的基本信息提交到服务器&#xff0c;服务器把数据保存到数据库。管理员对青少年的信息进行验证后&#xff0c;青少…

面试官:Javscript数组的常用方法有哪些?

&#x1f3ac; 岸边的风&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 一、操作方法 增 push() unshift() splice concat() 删 pop() shift() splice() slice() 改 splice() …

uview组件库的安装

更多的请查看官方文档uView 2.0 - 全面兼容 nvue 的 uni-app 生态框架 - uni-app UI 框架 (uviewui.com) // 如果您的根目录没有package.json文件的话&#xff0c;请先执行如下命令&#xff1a; // npm init -y 安装 npm install uview-ui2.0.36 // 更新 // npm update uvie…

生产数据追溯产线管理看板助力企业实现产品质量追踪

在现代制造业中&#xff0c;企业对于产品质量的追踪和管理变得越来越重要。产品质量的好坏直接关系到企业的声誉和客户满意度。然而&#xff0c;传统的生产管理方式往往无法提供足够的数据和信息来进行全面的质量追踪。生产看板管理系统的出现为企业解决了这一难题。通过实时的…

大模型LLM深入浅出、主打通俗易懂

AI(人工智能)是通过机器来模拟人类认识能力的一种科技能力。AI最核心的能力就是根据给定的输入做出判断或预测。对数据进行分析&#xff0c;从而总结得到研究对象的内在规律。一般通过使用适当的统计、机器学习、深度学习等方法&#xff0c;对收集的大量数据进行计算、分析、汇…

【FAQ】安防监控系统/视频云存储EasyCVR平台安全检查Proxy出现sql injection的漏洞,该如何修改?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。 最近有用户反馈&…

安卓系列机型 框架LSP 安装步骤 支持多机型 LSP框架通用安装步骤【二】

​​​​​​安卓玩机教程---全机型安卓4----安卓12 框架xp edx lsp安装方法【一】 低版本可以参考上个博文了解相关安装方法。 LSP框架优点 简单来说装lsp框架的优点在于可以安装各种模块。包括 但不限于系统优化 加速 游戏开挂等等的模块。大致相当于电脑的扩展油猴 Lspos…