【Java学习路线之JavaWeb】JSP教程

2023-05-16

文章目录

    • 为什么要学习JSP?
    • 读者
    • 阅读条件
  • JSP到底是什么
    • JSP的由来
    • Servlet与JSP异同点
    • JSP相对于Servlet的优点
        • 1)易于维护
        • 2)快速开发:无需重新编译和部署
        • 3)代码简洁
  • JSP生命周期(图解)
    • 1. JSP编译
    • 2. JSP初始化
    • 3. JSP执行
    • 4. JSP销毁
  • 第一个JSP程序
    • 1. 编写代码
    • 2. 运行
    • 3. 代码解释
  • Eclipse创建JSP项目(图解)
    • 1. 创建动态Web项目
    • 2. 创建JSP文件
    • 3. 启动服务器并部署项目
  • JSP脚本
        • 示例
  • JSP声明语句
        • 示例
        • JSP脚本和声明的区别
  • JSP表达式
        • 例 1
        • 例 2
  • JSP指令
  • JSP page指令
        • 例 1
        • 例 2
  • JSP include指令
        • 例 1
  • JSP taglib指令
        • 例 1
  • JSP动作
  • JSP九大内置对象一览表
    • 九大内置对象
    • 四大域对象
  • JSP request对象
    • 示例
  • JSP response对象
    • 示例
  • JSP out对象
    • 示例
  • JSP session对象
    • 示例
        • 拓展
  • JSP application对象
    • 示例
  • JSP config对象
    • 示例
  • JSP pageContext对象
    • 示例
  • JSP page对象
    • 示例
  • JSP Cookie的使用
    • cookie方法
    • JSP使用cookie
        • 1)创建 cookie 对象
        • 2)写入 cookie
        • 3)设置 cookie 有效期
        • 4)读取cookie
    • 示例
    • 读取cookie
    • 删除cookie
    • session和cookie的区别
  • JSP JavaBean的使用
    • JavaBean示例
    • JavaBean属性
        • 1)getPropertyName( )
        • 2)setPropertyName( )
  • JSP JDBC访问数据库
    • 示例
  • JSP分页功能
    • 实现分页步骤
        • 1)确定每页显示的数据数量
        • 2)计算显示的总页数
        • 3)编写SQL语句
    • 示例

转载于:http://c.biancheng.net/jsp2/

JSP 是 Java Server Pages 的缩写,是一种动态网页开发技术。动态网页是指跟静态网页相对的一种网页编程技术。静态网页,随着 HTML 代码的生成,页面的内容和显示基本上不会发生变化,除非修改页面代码。动态网页显示的内容可以随着时间、环境或者数据库操作的结果而发生改变。

JSP 本质是一个 Java 类(Servlet),我们可以在 JSP 页面中嵌入 Java 代码,即:JSP = HTML + Java。

请求 JSP 时,服务器内部会经历一次动态资源(JSP)到静态资源(HTML)的转化。服务器会自动把 JSP 中的 HTML 片段和数据拼接成静态资源响应给浏览器。也就是说,JSP 运行在服务器端,但最终发给客户端的是已经转换好的 HTML 静态页面。

为什么要学习JSP?

JSP 的功能与 CGI 相似,但相对于 CGI 来说,JSP 具有很多优势。

  • JSP 性能更加优越。因为 JSP 可以直接在 HTML 页面中嵌入动态元素,而不需要单独的引入 CGI 文件。
  • JSP 会在服务器调用之前进行编译,而不是像 CGI/Perl 必须先加载解释器和目标脚本。
  • JSP 基于 Java Servlet API,因此,JSP 可以使用各种强大的企业级 Java API,包括 JDBC、JNDI、EJB 和 JAXP 等。
  • JSP 页面可以和处理业务逻辑的 Servlet 一起使用。

JSP 是 Java EE 不可或缺的一部分,是一个完整的企业级应用平台。这意味着 JSP 可以用最简单的方式来实现最复杂的应用。

读者

本 JSP 教程适合初学者阅读,可以帮助读者了解 JSP 的基本功能以及如何开发动态网页。学习完本教程后,您将具有 JSP 方面的中等靠上的专业知识。

阅读条件

在学习本教程之前,您应当至少具备 HTML、CSS Java 和 Servlet 基础。

JSP到底是什么

JSP(Java Server Pages)是一种动态网页开发技术。JSP 文件就是在传统的 HTML 文件中插入 Java 代码和 JSP 标签,后缀名为.jsp

JSP 与 PHP、ASP、ASP.NET 等语言类似,都运行在服务端。通常返回给客户端的就是一个 HTML 文件,因此只要有浏览器就能查看 JSP 页面。

JSP 使用 JSP 标签在 HTML 网页中插入 Java 代码,标签通常以<%开头,以%>结束。JSP 标签有多种功能,比如访问数据库和 JavaBean 组件等,还可以在不同的网页之间传递和共享信息。

JSP 是 Servlet 的扩展,我们可以在 JSP 中使用 Servlet 的所有功能。另外,JSP 还提供了一些其他功能,例如 EL 表达式、自定义标签等。

JSP 依赖于 Servlet,用户访问 JSP 页面时,JSP 代码会被翻译成 Servlet 代码,最终,以字符串的形式向外输出 HTML 代码。所以,JSP 只是在 Servlet 的基础上做了进一步封装。

JSP 通过表单获取用户输入的数据、访问数据库或其它数据源生成动态的 Web 内容。

JSP 具有以下特点:

  • JSP 具有 Servlet 的所有优点,例如 JSP 文件跨平台,即一次编写,处处运行。
  • JSP 比 CGI 性能更加优越,因为 JSP 可以直接在 HTML 中嵌入标签,而 CGI 需要单独引用 CGI 文件。
  • JSP 比 Servlet 更易于维护,JSP 将业务逻辑与网页设计分离,使其更加灵活。
  • 使用 JSP,Web 开发人员可以更注重于网页设计,Java 开发人员可以更注重于逻辑处理。

JSP的由来

1997 年,Sun 公司推出了 Servlet。

由于当时的 Java Web 层体系结构中只有 Servlet,所以接收用户请求、处理业务逻辑、生成 HTML 代码等都在 Servlet 中完成。Servlet 不能像 PHP、ASP 等语言镶嵌 HTML 代码,因此输出 HTML 比较困难,且部署过程复杂。

为了克服 Servlet 的这些弱点,1999 年初,Sun 公司推出了 JSP。在生成 HTML 代码方面 JSP 比 Servlet 方便许多,而且不需要特殊部署,只需要复制到服务器下面即可运行。简而言之,JSP 就是为了简化 Servlet 工作而出现的替代品。

JSP 包括很多技术,包括 Java Bean、自定义标签(Custom Tags)、EL 表达式(Expression Language)、JSTL 标准标签类库(Java Standard Tag Library)等。这些强大成熟的技术使得 JSP 在视图层(View)具有很大的优势。

Servlet与JSP异同点

相同点:与 Servlet 一样,JSP 也用于生成动态网页。

不同点如下:

序号ServletJSP
1Servlet 在 Java 内添加 HTML 代码JSP 在 HTML 内添加 Java 代码
2Servlet 是一个 Java 程序,支持 HTML 标签JSP 是一种 HTML 代码,支持 Java 语句
3Servlet 一般用于开发程序的业务层(做一些复杂的逻辑处理)JSP 一般用于开发程序的表示层(显示数据)
4Servlet 由 Java 开发人员创建和维护JSP 常用于页面设计,由 Web 开发人员使用

JSP相对于Servlet的优点

1)易于维护

相对于 Servlet 来说,JSP 更易于管理。在 JSP 中,我们可以轻松地将业务逻辑与网页设计分开,而在 Servlet 技术中,它们是混合在一起的。

2)快速开发:无需重新编译和部署

JSP 页面被修改后,不需要重新编译和部署项目。而 Servlet 被修改后,需要重新编译和部署。

3)代码简洁

在 JSP 中,我们可以使用 EL、JSTL、自定义标签、隐式对象等,能够有效的减少代码。

JSP生命周期(图解)

JSP 生命周期定义了 JSP 从创建到销毁的整个过程。这类似于 Servlet 生命周期,不同的是,JSP 需要先被编译成 Servlet。

JSP 生命周期阶段如下:

  1. 编译
  2. 初始化(容器调用 jspInit() 方法)
  3. 执行(容器调用 _jspService() 方法)
  4. 销毁(容器调用 jspDestroy() 方法)

JSP生命周期

1. JSP编译

当浏览器请求 JSP 时,JSP 容器会首先检查是否需要编译页面。如果该页面从未被编译过,或者自上次编译以来对其进行了修改,则编译该页面。

JSP 本质是 Servlet,因此 JSP 容器就是 Servlet 容器。

编译过程包括 3 个步骤:

  • 解析 JSP:JSP 容器解析 JSP 文件,查看是否有语法错误
  • 翻译 JSP:JSP 容器把 JSP 文件翻译为 Servlet 类
  • 编译 Servlet

2. JSP初始化

当容器加载 JSP 时,它将在处理任何请求之前调用 jspInit() 方法。如果您需要自定义 JSP 的初始化内容,可以重写 jspInit() 方法。

public void jspInit(){
   // ...
}

一般情况下,程序只初始化一次。与 Servlet init 方法一样,我们通常在 jspInit() 方法中初始化数据库连接、打开文件。

3. JSP执行

此阶段表示了 JSP 生命周期中所有与请求相关的交互行为,直到被销毁。

JSP 页面完成初始化后,JSP 将会调用 _jspService() 方法。

_jspService() 以 HttpServletRequest 对象和 HttpServletResponse 对象作为方法参数,如下所示:

void _jspService(HttpServletRequest request, HttpServletResponse response) {
   // ...
}

JSP 的 _jspService() 方法根据 request 来生成相应的 response,并且它还负责生成对 HTTP 方法的响应,即 GET、POST、DELETE 等。

4. JSP销毁

JSP 生命周期的销毁阶段表示从容器中删除 JSP。

jspDestroy() 方法等效于 Servlet 中的 destroy() 方法。如果您需要自定义 JSP 的销毁内容,可以重写 jspDestroy() 方法。

jspDestroy() 方法具有以下形式。

public void jspDestroy() {
   ...
}

通常我们在 jspDestroy() 方法中释放数据库连接、关闭打开的文件。

第一个JSP程序

本节我们来简单创建一个 JSP 程序。

新建文件,编写以下代码,并将该文件存为 index.jsp,并放在文件夹 jspDemo 中,然后将该文件夹粘贴到 tomcat 的 webapps 目录下,运行 JSP 页面。

1. 编写代码

index.jsp 代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title></title>
</head>
<body>
    <%out.print("Hello,编程帮!网址是:http://www.biancheng.net");%>
</body>
</html>

2. 运行

运行步骤:

  1. 把 JSP 文件放在文件夹内,部署到服务器中
  2. 启动服务器
  3. 通过 URL 访问,例如:http://localhost:8080/jspDemo/index.jsp

访问结果如下:

访问结果

3. 代码解释

<% @ page%> 用来指定该页面的配置信息,contentType="text/html; charset=UTF-8"指定该网页类型为 html,网页字符编码为 UTF-8;language="java" 指定该网页编程语言为 Java。

和 都是 HTML 标签,用于静态网页,他们包含的内容都将直接传递给客户端,也就是 Web 浏览器。

<%out.print("Hello,编程帮");%> 是 JSP 中的输出语句,<% %> 中的代码是 Java 语句,因此以;结尾,out.print("Hello,编程帮")输出信息为“Hello,编程帮”。

Eclipse创建JSP项目(图解)

本节我们在 Eclipse 中创建一个简单的 JSP 文件。

使用 Eclipse 创建 JSP 文件分为 3 个步骤:

  1. 创建动态 Web 项目
  2. 创建 JSP 文件
  3. 启动 Tomcat 服务器,部署项目

1. 创建动态Web项目

打开 Eclipse,单击 File -> New -> Project -> Dynamic Web Project,如下图所示:

img

img

输入项目名称,配置服务器,点击完成。

img

2. 创建JSP文件

在项目的 WebContent 目录单击鼠标右键,按顺序依次单击 New -> Other -> JSP File -> Next,输入文件名 index.jsp,如下图所示。

img

index.jsp 代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<html>
<head>
    <title></title>
</head>
<body>
    <%out.print("Hello,编程帮");%>
</body>
</html>

3. 启动服务器并部署项目

运行 JSP,在您的 JSP 页面中单击鼠标右键,单击 Run As -> Run on Server,如下图所示。

img

选择 Tomcat 服务器,点击Next -> 选中项目 -> Add(也可双击项目直接部署到Tomcat上)-> Finish。

img

img

启动 Tomcat 服务器,在浏览器输入相应的 URL,例如:http://localhost:8080/jspDemo/index.jsp,页面如下。

img

JSP脚本

在 JSP 中,可以使用 JSP 脚本写入 Java 代码。

JSP 脚本可以包含任意数量的 Java 语句,变量、方法和表达式。JSP 脚本会把包含的内容插入到 Servlet 的 service() 方法中。

JSP 脚本语法如下:

<% Java语句 %>

等效于

<jsp:scriptlet>
    Java语句
</jsp:scriptlet>

任何文本、HTML 标签和 JSP 元素(声明,表达式等)都必须在脚本程序之外。

示例

大家可先参考《第一个JSP程序》中使用 JSP 脚本的一个简单实例。

下面创建 login.html 和 welcome.jsp 两个文件,login.html 提供表单供用户输入用户名,welcome.jsp 获取用户输入用户名并显示欢迎消息。

login.html 代码如下:

<!DOCTYPE html>
<html>
<body>
    <form action="welcome.jsp" method="post">
        <input type="text" name="uname"><br/>
        <input type="text" name="url"><br/>
        <input type="submit" value="go">
    </form>
</body>
</html>

welcome.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<body>
    <%
        String name = request.getParameter("uname");
        String url= request.getParameter("url");
        out.print("欢迎" + name + ",我们的网址是:" + url);
    %>
</body>
</html>

运行结果如下:

login.html运行页面
login.html运行页面

welcome.jsp运行页面
welcome.jsp运行页面

JSP声明语句

JSP 声明语句用于声明一个或多个变量、方法,以供后面的 Java 代码使用。您必须先对变量和方法进行声明,才能使用它们。

JSP 声明语法如下:

<%! 声明语句 %>

等效于

<jsp:declaration>
    声明语句
</jsp:declaration>

示例

<%! int num = 0; %>
<%! Circle a = new Circle(2.0); %>
<%!
    public void show () {
    }
%>

JSP脚本和声明的区别

JSP 脚本只能声明变量,不能声明方法。JSP 声明语句可以声明变量和方法。

JSP 脚本会把包含的内容转译插入到 Servlet 的 service() 方法中,也就是 <% %> 中定义的变量是局部变量。这也是 JSP 脚本不能声明方法的原因,因为 Java 不允许方法中嵌套方法。

JSP 声明会把包含的内容添加到 Servlet 类中(在任何方法之外),也就是 <%! %> 中定义的变量是成员变量,方法是成员方法。

JSP表达式

JSP 表达式可以把变量或者表达式输出到网页上,不需要 out.print() 就能输出数据。通常用于打印变量和方法的值。

JSP 表达式语法如下:

<%= 表达式 %>

等效于

<jsp:expression>
    表达式
</jsp:expression>

可以将 <%=表达式 %> 理解为 <% out.println(表达式) %> 的简写方式。这里需要注意,JSP 表达式不能以分号结尾。

例 1

使用 JSP 表达式显示欢迎消息,代码如下:

<html> 
<body> 
    <%="欢迎来到编程帮(http://www.biancheng.net)!"%> 
</body> 
</html>  

浏览器输出信息为:

欢迎来到编程帮(http://www.biancheng.net)!

例 2

下面使用 JSP 表达式显示当前时间,代码如下:

<html>
<body>
    当前时间: <%= java.util.Calendar.getInstance().getTime() %> 
</body>
</html>

浏览器输出信息为:

当前时间: Mon Dec 07 15:11:33 CST 2020

JSP指令

JSP 指令(directive)用来告诉 Web 服务器如何处理 JSP 页面的请求和响应。

服务器会根据 JSP 指令来编译 JSP,生成 Java 文件。JSP 指令不产生任何可见输出,在生成的 Java 文件中,不存在 JSP 指令。

JSP 指令以<%@开始,以%>结束,语法如下:

<%@ directive attribute = “value” [attribute2 = “value2” …]%>

注意:[ ]中的内容是可选的,@ 符号和指令名称之间,以及最后一个属性和结束%>之间的空格是可选的。

指令分为以下 3 种类型。

指 令说 明
<%@ page … %>定义与页面相关的属性,例如脚本语言、错误页面和缓冲要求
<%@ include … %>引入其它 JSP 文件
<%@ taglib … %>声明并导入标签库

在以下章节中,我们详细介绍了这几种指令。

  • JSP page指令
  • JSP include指令
  • JSP taglib指令

JSP page指令

JSP page 指令用来定义当前页面的相关属性。page 指令可以在 JSP 页面的任意位置编写,通常放在 JSP 页面的顶部。

page 指令的语法如下:

<%@ page attribute = “value” %>

下表是与 page 指令相关的属性。

属 性取 值说 明举 例
buffernone、缓冲区大小(默认值为 8kb)指定输出流是否有缓冲区<%@ page buffer=“16kb” %>
autoFlushtrue(默认值)、false指定缓冲区是否自动清除<%@ page autoFlush=“true” %>
contentTypetext/html; charset = ISO-8859-1、 text/xml;charset = UTF-8 等指定 MIME 类型和字符编码<%@ page contentType=“text/html;charset=UTF-8” %>
errorpage页面路径指定当前 JSP 页面发生异常时,需要重定向的错误页面<%@ page errorpage=“myerrorpage.jsp” %> 注意:myerrorpage.jsp 的 isErrorpage 值必须为 true
isErrorpagetrue、false(默认值)指定当前页面为错误页面<%@ page isErrorpage=“true” %>
extends包名.类名指定当前页面继承的父类,一般很少使用<%@ page extends=“mypackage.SampleClass”%>
import类名、接口名、包名导入类、接口、包,类似于 Java 的 import 关键字<%@ page import = " java.util.Date" %> <%@ page import=“java.io., java.lang.”%>
info页面的描述信息定义 JSP 页面的描述信息,可以使用 getServletInfo() 方法获取<%@ page info=“这里是编程帮的页面信息”%>
isThreadSafetrue(默认值)、false是否允许多线程使用<%@ page isThreadSafe=“false” %>
language脚本语言指定页面中使用的脚本语言<%@ page language= “java” %>
sessiontrue(默认值)、false指定页面是否使用 session<%@ page session=“false” %>
isELIgnoredtrue(默认值)、false指定页面是否忽略 JSP 中的 EL<%@ page isELIgnored=“false” %>

以上属性除了 import 可以声明多个外,其它属性都只能出现一次。

例 1

下面通过 page 指令的 import 属性导入 java.util.Date 类,显示欢迎信息和用户登录的日期时间。login.jsp 代码如下:

<%@ page import="java.util.Date" language="java"
    contentType="text/html;charset=utf-8"%>
<html>
<body>
    您好,欢迎登录编程帮!
    <br /> 您登录的时间是<%=new Date()%>
</body>
</html>

运行结果如下:

img

例 2

下面通过 page 指令的 errorpage 和 isErrorPage 属性定义以及重定向到错误页面。index.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<body>
    <%@page errorPage="errorpage.jsp"%>
    <%=100/0 %>
</body>
</html>

errorpage.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<body>
    <%@page isErrorPage="true"%>
    抱歉,发生了异常!
    <br /> 异常为<%= exception%>
</body>
</html>

注意:exception 只能在错误页面使用。

访问 index.jsp 页面,结果如下:

index.jsp访问结果

JSP include指令

include 指令用于在 JSP 页面引入其它内容,可以是 JSP 文件、html 文件和文本文件等,相当于把文件的内容复制到 JSP 页面。引入的文件和 JSP 页面同时编译运行。

使用 include 指令有以下优点:

  • 增加代码的可重用性
  • 使 JSP 页面的代码结构清晰易懂
  • 维护简单

include 的语法如下:

<%@ include file=“URL” %>

其中,file 指定需要引入文件的相对路径。

可以在页面的任何位置编写 include 指令。

例 1

在 index.jsp 页面使用 include 指令引入 head.jsp。head.jsp 代码如下:

<p>header内容</p>

index.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<body>
    <%@ include file="head.jsp" %>
    <p>编程帮(http://www.biancheng.net)</p>
</body>
</html>

此示例中,head.jsp 和 index.jsp 在同一目录中,如果不在同一目录,引入 head.jsp 文件时需要指定完整路径。运行结果如下:

img

JSP taglib指令

在 JSP 中,我们可以使用 taglib 指令声明并引入标签库。Java API 允许在页面中自定义标签,标签库就是自定义标签的集合。

taglib 指令的语法如下:

<%@ taglib uri=“tagliburl” prefix=“tagPre” %>

其中,uri 指定自定义标签库的存放位置;prefix 指定标签库的前缀。为了区分不同的标签库,在页面中使用标签库以对应的 prefix 开头。

例 1

下面我们使用 currentDate 标签,首先使用 taglib 指令指定标签库存放位置和使用前缀。示例代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://www.biancheng.net/tags" prefix="mytag"%>
<!DOCTYPE html>
<html>
<body>
    <mytag:currentDate />
</body>
</html>

以上代码会出现找不到标签库路径错误,这里只演示 taglib 指令的用法,具体应用会在教程后面进行详细说明。

JSP动作

JSP 动作使用 XML 语法格式的标签来控制服务器的行为。利用 JSP 动作可以动态地插入文件、重用 JavaBean 组件、把用户重定向到另一个页面、为 Java 插件生成 HTML 代码等。

JSP 动作与 JSP 指令的不同之处如下:

  • JSP 指令在翻译阶段执行,从而设置整个 JSP 页面的属性。JSP 页面被执行时首先进入翻译阶段,程序会先查找页面中的 JSP 指令,并将它们转换成 Servlet。所以,JSP 指令是在页面转换时期被编译执行的,且编译一次。
  • JSP 动作在请求处理阶段执行,它们只有执行时才实现自己的功能。通常用户每请求一次,动作标识就会执行一次。

JSP 动作语法如下:

<jsp:action_name attribute = "value" />

<jsp:action_name attribute="value"></jsp:action_name>

action_name 表示 JSP 动作名称,attribute 表示相应 JSP 动作的属性名称。常用的 JSP 动作如下表所示:

动作说明
jsp:include页面被请求时引入一个文件
jsp:userBean实例化JavaBean
jsp:setProperty设置 JavaBean 的属性
jsp:getProperty获取 JavaBean 的属性
jsp:forward将请求转发到另一个页面
jsp:plugin根据浏览器类型替换成 或者 标签
jsp:element定义动态 XML 元素
jsp:attribute设置动态 XML 元素的属性
jsp:body设置动态 XML 元素的内容

在以下章节中,我们详细介绍了几种常用的动作:

  • JSP include动作
  • JSP forward动作
  • JSP param动作
  • JSP useBean动作
  • JSP setProperty和getProperty动作

JSP九大内置对象一览表

为了简化页面的开发过程,JSP 提供了一些内置对象。

JSP 内置对象又称为隐式对象,它们由容器实现和管理。在 JSP 页面中,这些内置对象不需要预先声明,也不需要进行实例化,我们可以直接在脚本和表达式中使用。

注意:JSP 内置对象只能在脚本和表达式中使用,在声明中不能使用。

九大内置对象

JSP 中定义了 9 个内置对象,它们分别是:request、response、session、application、out、pagecontext、config、page 和 exception,这些对象在客户端和服务器端交互的过程中分别完成不同的功能。

对 象类型说 明
requestjavax.servlet.http.HttpServletRequest获取用户请求信息
responsejavax.servlet.http.HttpServletResponse响应客户端请求,并将处理信息返回到客户端
outjavax.servlet.jsp.JspWriter输出内容到 HTML 中
sessionjavax.servlet.http.HttpSession用来保存用户信息
applicationjavax.servlet.ServletContext所有用户共享信息
configjavax.servlet.ServletConfig这是一个 Servlet 配置对象,用于 Servlet 和页面的初始化参数
pageContextjavax.servlet.jsp.PageContextJSP 的页面容器,用于访问 page、request、application 和 session 的属性
pagejavax.servlet.jsp.HttpJspPage类似于 Java 类的 this 关键字,表示当前 JSP 页面
exceptionjava.lang.Throwable该对象用于处理 JSP 文件执行时发生的错误和异常;只有在 JSP 页面的 page 指令中指定 isErrorPage 的取值 true 时,才可以在本页面使用 exception 对象。

JSP 的内置对象主要有以下特点:

  • 由 JSP 规范提供,不用编写者实例化;
  • 通过 Web 容器实现和管理;
  • 所有 JSP 页面均可使用;
  • 只有在脚本元素的表达式或代码段中才能使用。

四大域对象

在 JSP 九大内置对象中,包含四个域对象,它们分别是:pageContext(page 域对象)、request(request 域对象)、session(session 域对象)、以及 application(application 域对象)。

JSP 中的 4 个域对象都能通过以下 3 个方法,对属性进行保存、获取和移除操作。

返回值类型方法作用
voidsetAttribute(String name, Object o)将属性保存到域对象中
ObjectgetAttribute(String name)获取域对象中的属性值
voidremoveAttribute(String name)将属性从域对象中移除

JSP 中的 4 个域对象的作用域各不相同,如下表。

作用域描述作用范围
page如果把属性保存到 pageContext 中,则它的作用域是 page。该作用域中的属性只在当前 JSP 页面有效,跳转页面后失效。
request如果把属性保存到 request 中,则它的作用域是 request。该作用域中的属性只在当前请求范围内有效。服务器跳转页面后有效,例如jsp:forward;客户端跳转页面后无效,例如超链接。
session如果把属性保存到 session 中,则它的作用域是 session。该作用域中的属性只在当前会话范围内有效,网页关闭后失效。
application如果把属性保存到 application 中,则它的作用域是 application。该作用域中的属性在整个应用范围内有效,服务器重启后失效。

JSP request对象

JSP request 是 javax.servlet.http.HttpServletRequest 的实例对象,主要用来获取客户端提交的数据。

request 对象提供了一系列方法,可以获取请求参数信息、表单数据、HTTP 头信息、cookie 和 HTTP 请求方法等。request 对象常用方法如下表所示。

方法说明
String getParameter(String name)获取请求参数 name 的值
Enumeration getParameterNames()获取所有参数名称
String[] getParameterValues(String name)获取请求参数 name 的所有值
Object getAttribute(String name)获取 name 属性的值
Enumeration getAttributeNames()返回所有属性的名称集合
void setAttribute(String key, Object value)给 key 对象赋 value 值
void removeAttribute(String name)删除指定的 name 属性
cookie[] getCookies()获取所有的 cookie 对象
HttpSession getSession()返回 request 对应的 session 对象,如果没有则创建一个 session 对象
HttpSession getSession(boolean create)返回 request 对应的 session 对象,如果没有,且 create 值为 true,则创建一个 session 对象
Enumeration getHeaderNames()返回 HTTP 头信息的名称集合
String getHeader(String name)获取 name 指定的 HTTP 头信息
String getMethod()获取 HTTP 请求方法/客户提交信息方式

示例

在 index.jsp 页面使用 getHeaderNames() 方法获取 HTTP 头信息,并遍历输出参数名称和对应值。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*"%>
<!DOCTYPE html>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body>
    <h2>获取HTTP请求头信息</h2>
    <table width="100%" border="1" align="center">
        <tr bgcolor="#949494">
            <th>参数名称</th>
            <th>参数值</th>
        </tr>
        <%
            Enumeration headerNames = request.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                String paramName = (String) headerNames.nextElement();
                out.print("<tr><td>" + paramName + "</td>\n");
                String paramValue = request.getHeader(paramName);
                out.println("<td> " + paramValue + "</td></tr>\n");
            }
        %>
    </table>
</body>
</html>

运行结果如下:

index.jsp运行结果

头信息介绍如下:

参数名称说明
host表示服务器的主机名和端口号
connection判断客户端是否可以持续性的连接 HTTP
cache-control网页缓存控制,默认值为 no-cache,表明每次访问都从服务器中获取页面
upgrade-insecure-requestsChrome(谷歌浏览器)会在 HTTP 请求中加入Upgrade-Insecure-Requests: 1 ,服务器收到请求后会返回 Content-Security-Policy: upgrade-insecure-requests头来告诉浏览器,可以把本站的所有 http 连接升级为 https 连接。使用其它浏览器没有该参数
user-agent客户端程序的相关信息,例如:浏览器版本、操作系统类型等
accept客户端能接收的 MIME 类型
sec-fetch-*网络请求的元数据描述,也是 Chrome 特有的参数
accept-encoding指明客户端能够处理的编码类型有哪些
accept-language浏览器的首选语言
cookie会话信息,每个会话都有一个对应的会话 ID 或其他信息

JSP response对象

JSP response 是 javax.servlet.http.HttpServletResponse 的实例对象。response 对象和 request 对象相对应,主要用于响应客户端请求,将处理信息返回到客户端。

response 对象的常用方法如下:

方 法说 明
void addHeader(String name, String value)添加头信息(参数名称和对应值)
void addCookie(Cookie cookie)添加 cookie 信息
void sendRedirect(String location)实现页面重定向
void setStatus(int sc)实现页面的响应状态代码
void setContentType(String type)设置页面的 MIME 类型和字符集
void setCharacterEncoding(String charset)设定页面响应的编码类型

示例

下面在 login.jsp 新建表单,在 checkdetails.jsp 接收 login.jsp 提交的用户名和密码,与指定的用户名和密码相比,相同则登录成功,重定向到 success.jsp;反之登录失败,重定向到 failed.jsp。

login.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body>
    <h2>用户登录</h2>
    <form action="checkdetails.jsp">
        用户名: <input type="text" name="username" /> <br> <br> 
        密码: <input type="text" name="pass" /> <br> <br> 
        <input type="submit" value="登录" />
    </form>
</body>
</html>

checkdetails.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body>
    <%
        String username = request.getParameter("username");
        String password = request.getParameter("pass");
        if (username.equals("biancheng") && password.equals("bianchengbang")) {
            response.sendRedirect("success.jsp");
        } else {
            response.sendRedirect("failed.jsp");
        }
    %>
</body>
</html>

success.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body>
    <h2>登录成功!</h2>
</body>
</html>

failed.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body>
    <h2>登录失败,用户名或密码错误!</h2>
</body>
</html>

运行结果如下所示:

登录页面(输入正确的用户名和密码)
登录页面(输入正确的用户名和密码)

登录成功页面
登录成功页面

登录页面(输入错误的用户名)
登录页面(输入错误的用户名)

登录失败页面
登录失败页面

JSP out对象

JSP out 是 javax.servlet.jsp.JspWriter 的实例对象。out 对象包含了很多 IO 流中的方法和特性,最常用的就是输出内容到 HTML 中。

out 对象的常用方法如下:

方法说明
void print()将内容直接打印在 HTML 标签中
void println()类似于 print,唯一区别是 println 方法添加了换行符
void newLine()输出换行字符
void clear()清除页面缓冲区
boolean isAutoFlush()检查页面是否自动清除缓冲区

示例

out 对象的方法相对比较简单,一般情况下很少使用。下面我们使用 out 对象的 print、println 和 newLine 方法将内容输出到 HTML 中。index.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*"%>
<!DOCTYPE html>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body>
    <%
        out.print("欢迎来到编程帮,");
        out.newLine();
        out.println("我们的网址是:");
        out.print("www.biancheng.net");
    %>
</body>
</html>

运行结果如下:

index.jsp运行结果
index.jsp运行结果

注意:这里的 println 与 newLine 换行指的是 HTML 代码换行,并不是页面显示的换行。页面显示换行需要在代码后面加
标签。

JSP session对象

JSP session 是 javax.servlet.http.HttpSession 的实例对象,主要用来访问用户数据,记录客户的连接信息。

HTTP 协议是一种无状态的协议(即不保存连接状态的协议)。每次用户向服务器发出请求,且服务器接收请求并返回响应后,该连接就被关闭了,服务器端与客户端的连接被断开。此时,服务器端不保留连接的有关信息,要想记住客户的连接信息,就用到了 session 对象。

session 对象的常用方法如下:

方法说明
void setAttribute(String name, Object value)将参数名和参数值存放在 session 对象中
Object getAttribute(String name)通过 name 返回获取相应的 value 值,如果 name 没有相应的 value 值,则返回 null
void removeAttribute(String name)删除指定的 name 参数
Enumeration getAttributeNames()获取 session 对象中存储的所有参数
long getCreationTime()返回 session 对象创建的时间
String getId()获取 session 对象的 ID 值
boolean isNew()用于检查 session 对象是不是新对象,如果客户端禁用了 cookie ,则 session.isNew() 始终返回 true
void invalidate()终止 session,即指定 session 对象失效
void setMaxInactiveInterval()设置 session 对象的有效时间,单位:秒
int getMaxInactiveInterval()获取 session 对象的有效时间,单位:秒
long getLastAccessedTime()获取上次访问 session 对象的时间

示例

在 login.jsp 页面登录,并跳转到 index.jsp。login.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body>
    <h2>用户登录</h2>
    <form action="index.jsp">
        用户名: <input type="text" name="username" /> <br> <br>
        密码: <input type="text" name="pass" /> <br> <br>
        <input type="submit" value="登录" />
    </form>
</body>
</html>

在 index.jsp 中,使用 session.setAttribute() 方法将用户名存储到 session 对象中,代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body>
    <%
        String username = request.getParameter("username");
        out.print("欢迎" + username + "登录");
        session.setAttribute("sessname", username);
    %>
    <a href="success.jsp">跳转成功页面</a>
</body>
</html>

在 success.jsp 中,使用 session.getAttribute() 方法获取 session 对象中的用户名,并显示。success.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body>
    <%
        String name = (String) session.getAttribute("sessname");
        out.print("您好,您的用户名为:" + name);
    %>
</body>
</html>

运行结果如下图所示:

login.jsp
login.jsp运行结果

index.jsp运行结果
index.jsp运行结果

success.jsp运行结果
index.jsp运行结果

拓展

如果使用的是 Tomcat 服务器,可以在 web.xml 文件中添加以下内容来设置 session 的有效时间:

<session-config>
    <session-timeout>15</session-timeout>
</session-config>

这里单位是分钟,即表示 session 对象的有效时间为 15 分钟,Tomcat 默认有效时间为 30 分钟。

如果在 web.xml 中配置的是15分钟,则 getMaxInactiveInterval( ) 方法返回 900。

JSP application对象

JSP application 是 javax.servlet.ServletContext 的实例对象。在服务器部署应用和项目时,Web 容器仅创建一次 ServletContext 实例,也就是说 application 设置的任何属性和值可以用于整个应用(所有 JSP 页面)。可以将 application 对象看作 Web 应用的全局变量。一般用于保存应用程序的公用数据。

application 对象在 Web 应用运行时一直存在于服务器中,非常占用资源,因此在实际开发中不推荐使用,否则容易造成内存不足等情况。

application 对象常用方法如下:

方 法说 明
Object getAttribute(String attributeName)获取 attributeName(属性名称)对应的 object
void setAttribute(String attributeName, Object object)设置 attributeName 对应的属性值
Enumeration getAttributeNames()返回 application 对象中所有的 attributeName
void removeAttribute(String objectName)删除 application 对象中指定 attributeName 的属性
String getServerInfo()获取当前 Servlet 的版本信息
String getRealPath(String value)获取指定文件的实际路径

示例

可以使用 application 对象来保存 JSP 页面的访问人数,也就是我们常说的网站计数器,下面通过一个例子来演示。index.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*"%>
<!DOCTYPE html>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body>
    <%
        Integer count = (Integer) application.getAttribute("count");
        if (count == null) {
            count = 1;
        } else {
            count++;
        }
        application.setAttribute("count", count);
    %>
    <h2>编程帮网站计数器</h2>
    欢迎访问编程帮,您是第<%=count%>位访问客户!
</body>
</html>

运行结果如下:

首次访问count为1
首次访问count为1

连续刷新页面count增加
连续刷新页面count增加

JSP config对象

JSP config 是 javax.servlet.ServletConfig 的实例对象,一般用于获取页面和 Servlet 的初始化参数。

config 对象的常用方法如下:

方法说明
String getInitParameter(String paramname)获取指定的初始化参数值
Enumeration getInitParameterNames()获取当前页面所有的初始化参数值
ServletContext getServletContext()获取当前执行 Servlet 的 servletContext(Servlet 上下文)的值
String getServletName()获取当前执行 Servlet 的名称

示例

在 web.xml 文件中定义 Servlet 名称和映射,然后使用 config 对象获取信息。web.xml 代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">
    <servlet>
        <servlet-name>BianChengBangServlet</servlet-name>
        <jsp-file>/index.jsp</jsp-file>
        <init-param>
            <param-name>url</param-name>
            <param-value>http://www.biancheng.net</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>BianChengBangServlet</servlet-name>
        <url-pattern>/index</url-pattern>
    </servlet-mapping>
</web-app>

在 index.jsp 页面获取 Servlet 名称以及初始化参数,代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body>
    <%
        String sname = config.getServletName();
        String url = config.getInitParameter("url");
        out.print("Servlet名称为:" + sname + "<br>");
        out.print("初始化参数为:" + url + "<br>");
    %>
</body>
</html>

运行结果如下:

index.jsp运行结果

注意:因为 JSP 页面的实质是 Servlet,所以一般很少在 JSP 页面中使用 config 对象。

JSP pageContext对象

pageContext 是 javax.servlet.jsp.PageContext 的实例对象。pageContext 对象表示整个 JSP 页面,可以获取或删除以下对象的任意属性:

  • page
  • request
  • session
  • application

pageContext 常用的方法如下:

方 法说 明
Object findAttribute (String AttributeName)按 page、request、session、application 的顺序查找指定的属性,并返回对应的属性值。如果没有相应的属性,则返回 NULL
Object getAttribute (String AttributeName, int Scope)在指定范围内获取属性值。与 findAttribute 不同的是,getAttribute 需要指定查找范围
void removeAttribute(String AttributeName, int Scope)在指定范围内删除某属性
void setAttribute(String AttributeName, Object AttributeValue, int Scope)在指定范围内设置属性和属性值
Exception getException()返回当前页的 Exception 对象
ServletRequest getRequest()返回当前页的 request 对象
ServletResponse getResponse()返回当前页的 response 对象
ServletConfig getServletConfig()返回当前页的 ServletConfig 对象
HttpSession getSession()返回当前页的 session 对象
Object getPage()返回当前页的 page 对象
ServletContext getServletContext()返回当前页的 application 对象

示例

使用 PageContext 对象取得不同范围的属性值。index.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body>
    <%
        request.setAttribute("info", "request范围的值");
        session.setAttribute("info", "session范围的值");
        application.setAttribute("info", "application范围的值");
    %>
    利用 pageContext 取出以下范围内各值(方法一):
    <br> request 设定的值:<%=pageContext.getRequest().getAttribute("info")%>
    <br> session 设定的值:<%=pageContext.getSession().getAttribute("info")%>
    <br> application 设的值:<%=pageContext.getServletContext().getAttribute("info")%>
    <hr>
    利用pageContext取出以下范围内各值(方法二):
    <br> 范围1(page)内的值:<%=pageContext.getAttribute("info", 1)%>
    <br> 范围2(request)内的值:<%=pageContext.getAttribute("info", 2)%>
    <br> 范围3(session)内的值:<%=pageContext.getAttribute("info", 3)%>
    <br> 范围4(application)内的值:<%=pageContext.getAttribute("info", 4)%>
    <hr>
    利用 pageContext 修改或删除某个范围内的值:
    <%
        pageContext.setAttribute("info", "修改request范围的值", 2);
    %>
    <br> 修改 request 设定的值:
    <br>
    <%=pageContext.getRequest().getAttribute("info")%>
    <br>
    <%
        pageContext.removeAttribute("info");
    %>
    删除 session 设定的值:<%=session.getAttribute("info")%>
</body>
</html>

运行结果如下:

index.jsp运行结果
index.jsp运行结果

JSP page对象

JSP page 的实质是 java.lang.Object 对象,相当于 Java 中的 this 关键字。page 对象是指当前的 JSP 页面本身,在实际开发中并不常用。

page 对象的常用方法如下:

方 法说 明
class getClass()返回当前页面所在类
int hashCode()返回当前页面的 hash 代码
String toString()将当前页面所在类转换成字符串
boolean equals(Object obj)比较对象和指定的对象是否相等
void copy (Object obj)把对象复制到指定的对象中
Object clone()复制对象

示例

下面通过一个简单的例子来演示 page 中的方法。index.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body>
    <%
        Object obj;
        obj = null;
    %>
    返回当前页面所在类:<%=page.getClass()%>
    <br> 返回当前页面的 hash 代码:<%=page.hashCode()%>
    <br> 转换成 String 类的对象:<%=page.toString()%>
    <br> page和obj比较:<%=page.equals(obj)%>
    <br> page和this比较:<%=page.equals(this)%>
</body>
</html>

运行结果如下:

index.jsp运行结果

JSP Cookie的使用

Cookie 不是 JSP 内置对象,而是由 Netscape 公司发明,用来跟踪用户会话(session)的方式。

Cookie 由服务器生成并发送给浏览器(客户端),浏览器会将其以文本文件的形式存储在某个目录下。

例如,IE 浏览器把 cookie 信息保存在类似于 C://windows//cookies 的目录下,当用户再次访问某个网站时,服务器就会要求浏览器查找并返回之前发送的 cookie 信息,来识别此用户。

识别用户通常有以下步骤:

  1. 服务器把 cookie 信息发送到浏览器,例如:用户 ID、用户名称等信息。
  2. 浏览器在本地存储这些信息。
  3. 浏览器再次向服务器发送请求时,它会同时将本地存储的 cookie 信息一同发送给服务器,然后服务器使用这些信息来识别用户或其它。

cookie 的作用表现在以下方面:

  • 对特定对象的追踪,如用户的访问次数、最后访问时间等。
  • 统计网页的浏览次数。
  • 在 cookie 有效期内,记录用户的登录信息,简化下一次的登录过程。
  • 实现各种个性化服务,如”最近浏览过的商品“。

注意:由于 cookie 会将用户的个人信息保存在客户端,如用户名、计算机名、以及浏览和登录的网站等。这些信息可能会包含一些比较敏感的内容,所以从安全角度来说,使用 cookie 存在着一定的风险,因此不建议在 cookie 中保存比较重要或隐私的内容。

cookie方法

cookie 常用方法如下:

方法说明
public void setDomain(String pattern)设置 cookie 的域名,如 biancheng.net
public String getDomain()获取 cookie 的域名
public void setMaxAge(int expiry)设置 cookie 有效期,单位:秒 默认仅在当前会话中存在
public int getMaxAge()获取 cookie 有效期,单位:秒 默认为 -1,表示 cookie 保存到浏览器关闭为止
public String getName()返回 cookie 的名称,名称创建后将不能被修改
public void setValue(String newValue)设置 cookie 的值
public String getValue()获取 cookie 的值
public void setPath(String uri)设置 cookie 的路径 默认为当前页面目录以及子目录下的所有 URL
public String getPath()获取 cookie 的路径
public void setSecure(boolean flag)设置 cookie 是否要加密传输
public void setComment(String purpose)设置 cookie 注释
public String getComment()返回 cookie 注释,如果 cookie 没有注释,则返回 null

JSP使用cookie

JSP 使用 cookie 主要分为以下几个步骤。

1)创建 cookie 对象

创建 cookie 对象,name 代表 cookie 的名称,value 表示该名称对应的值,语法如下:

cookie cookie = new cookie(String name,String value);

注意:name 和 value 中不能包含空格和以下字符:

[ ] ( ) = , " / ? @ : ;

2)写入 cookie

创建 cookie 对象后,调用 response.addCookie() 方法写入 cookie,代码如下:

response.addcookie(cookie);

3)设置 cookie 有效期

调用 setMaxAge() 方法设置 cookie 的有效期(单位:秒),如将 cookie 有效期设置为 24 小时,代码如下:

cookie.setMaxAge(60*60*24); 

4)读取cookie

调用 request.getCookies() 方法读取 cookie,该方法返回 HTTP 请求中的 cookie 对象数组,需要通过遍历进行访问。

示例

通过 HTML 表单将客户端数据提交到 index.jsp 中,并设置 cookie。login.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body>
    <form action="index.jsp" method="get">
        站点名: <input type="text" name="name"> <br />
        网址: <input type="text" name="url" />
        <input type="submit" value="提交" />
    </form>
</body>
</html>

index.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.net.*"%>
<%
    // 解决中文乱码  
    String str = URLEncoder.encode(request.getParameter("name"), "utf-8");
    // 创建cookie对象
    cookie name = new cookie("name", str);
    cookie url = new cookie("url", request.getParameter("url"));
    // 设置cookie有效期为24小时。
    name.setMaxAge(60 * 60 * 24);
    url.setMaxAge(60 * 60 * 24);
    // 在响应头部添加cookie
    response.addcookie(name);
    response.addcookie(url);
%>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body>
    <b>网站名:</b>
    <%=request.getParameter("name")%><br>
    <b>网址:</b>
    <%=request.getParameter("url")%>
</body>
</html>

运行结果如下:

login.jsp运行结果
login.jsp页面运行结果

index.jsp
index.jsp页面运行结果

读取cookie

调用 request.getcookies() 方法,在 cookie.jsp 页面中读取 cookie,cookie.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.net.*"%>
<!DOCTYPE html>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body>
    <%
        cookie cookie = null; //创建cookie对象
        cookie[] cookies = null;
        // 获取 cookie 的数据
        cookies = request.getcookies();
        if (cookies != null) {
            out.println("<h2> 获取cookie名称与对应值</h2>");
            for (int i = 0; i < cookies.length; i++) {
                cookie = cookies[i];
                out.print("参数名 : " + cookie.getName());
                out.print("<br>");
                out.print("参数值: " + URLDecoder.decode(cookie.getValue(), "utf-8") + " <br>");
                out.print("------------------------------------<br>");
            }
        } else {
            out.println("<h2>cookie为空</h2>");
        }
    %>
</body>
</html>

运行结果如下:

cookie.jsp运行结果

删除cookie

删除 cookie 步骤如下:

  • 获取 cookie
  • 将要删除的 cookie 有效期设置为 0
  • 调用 response.addCookie() 方法重新写入 cookie

删除参数名为“name”的 cookie,cookie.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.net.*"%>
<!DOCTYPE html>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body>
    <%
        cookie cookie = null; //创建cookie对象
        cookie[] cookies = null;
        // 获取 cookie 的数据
        cookies = request.getcookies();
        if (cookies != null) {
            out.println("<h2> 获取cookie名称与对应值</h2>");
            for (int i = 0; i < cookies.length; i++) {
                cookie = cookies[i];
                //删除参数名为name的cookie
                if ((cookie.getName()).compareTo("name") == 0) {
                    cookie.setMaxAge(0);
                    response.addcookie(cookie);
                    out.print("删除 cookie: " + cookie.getName() + "<br/>");
                }
                out.print("参数名 : " + cookie.getName());
                out.print("<br>");
                out.print("参数值: " + URLDecoder.decode(cookie.getValue(), "utf-8") + " <br>");
                out.print("------------------------------------<br>");
            }
        } else {
            out.println("<h2>cookie为空</h2>");
        }
    %>
</body>
</html>

刷新 cookie.jsp 页面,运行结果如下:

cookie.jsp页面运行结果

注:也可以手动在浏览器中删除 cookie。

session和cookie的区别

session 和 cookie 的区别如下:

sessioncookie
将信息保存在服务器将信息保存在客户端
保存的值是 Object 类型保存的值是 String 类型
session 存储的数据随会话的结束而结束cookie 可以长期保存在客户端
安全性高,可以保存重要的信息安全性低,通常用于保存不重要的信息

实际开发中,需要根据不同的业务需求来选择采用哪种技术,例如,用户的用户名和密码等敏感信息不能使用 cookie 存储,淘宝购物的”最近浏览过的商品“,则可以使用 cookie 存储在客户端。

JSP JavaBean的使用

JavaBean 是可以重复使用的一个组件,是遵守 JavaBean API 规范的 Java 类。

一般情况下,JavaBean 要满足以下要求:

  • JavaBean 是一个公共类,并提供无参公有的构造方法
  • 需要被序列化并且实现了 Serializable 接口
  • 属性私有化
  • 具有公共的访问属性的 getter 和 setter 方法

Java 之父 James Gosling 在设计 Java 语言,为 Java 组件中封装数据的 Java 类进行命名时,看到了桌子上的咖啡豆,于是灵机一动,就把它命名为“JavaBean”,bean 翻译为“豆、豆子”。

在程序中,开发人员所要处理的无非是业务逻辑和数据,而这两种操作都可以封装成 JavaBean,一个应用程序中会使用很多的 JavaBean。由此可见,JavaBean 组件是应用程序的重要组成部分。

JavaBean示例

下面是一个 JavaBean 的简单示例,如下:

package entity;
import java.io.Serializable;
public class User implements Serializable {
   
    private static final long serialVersionUID = 1L;
   
    private int id;
    private String name;
    public User() {
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getId() {
        return id;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

JavaBean属性

一个 JavaBean 可以有多个属性,属性应该是可以访问的,属性类型可以是任何合法的 Java 数据类型,包括自定义的类。

JavaBean 的每个属性通常都具有相应的 setter 和 getter 方法,setter 方法称为属性修改器,getter 方法称为属性访问器,如下:

1)getPropertyName( )

属性访问器以小写的 get 作为前缀,后跟属性名,且属性名的第一个字母也要改为大写。例如:属性名称为 name,则方法名称为 getName( ),用来读取该属性值。

2)setPropertyName( )

属性修改器以小写的 set 作为前缀,后跟属性名,且属性名的第一个字母也要改为大写。例如:属性名称为 name,则方法名称为 setName( ),用来设置该属性值。

JavaBean 的某个属性也可以只有 set 方法或 get 方法,这样的属性称之为只写或只读属性。

通过 getter 和 setter 方法访问 JavaBean,如下:

public static void main(String[] args) {
    User u = new User();// 创建对象
    u.setName("编程帮");// 设置对象的值
    System.out.println(u.getName());// 输出“编程帮”
}

JSP JDBC访问数据库

动态网页的主要特点就是能及时更新数据,这些更新的数据来源于数据库。学习本节内容需要您了解 JDBC,可以使用 JDBC 连接 MySQL 数据库。

本节数据库使用 MySQL 5.7,你可以点击 MySQL 官方网站 下载相应的 jar 包。

注意:MySQL 8.0 及之后的版本与之前的数据库连接有所不同:

  • 首先驱动 com.mysql.jdbc.Driver 更换为 com.mysql.cj.jdbc.Driver。
  • MySQL 8.0 及以上版本需要显式关闭 SSL 连接和指定 CST。

MySQL 8.0 及以上版本加载驱动与连接数据库方式如下:

<sql:setDataSource var="snapshot" driver="com.mysql.cj.jdbc.Driver"     url="jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8     user="root"  password="root"/>

下面使用 JSTL 对数据表中的数据进行增删改查。

示例

创建 website 数据表,并插入数据。点击下载 SQL 文件(下载后需要解压)

crud.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*,java.sql.*"%>
<%@ page import="javax.servlet.http.*,javax.servlet.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>
<!DOCTYPE html>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body>
    <%--
        JDBC驱动名、数据库 URL、数据库的用户名与密码
        useUnicode=true&characterEncoding=utf-8 防止中文乱码
     --%>
    <sql:setDataSource var="snapshot" driver="com.mysql.jdbc.Driver"
        url="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8"
        user="root" password="root" />
    <%-- 插入数据
    <sql:update dataSource="${snapshot}" var="result">
        INSERT INTO website (NAME,url,age,country) VALUES ('京东', 'https://www.jd.com/', 15, 'CN');
    </sql:update> --%>
    <%-- 删除website表中id为9数据
    <c:set var="id" value="9" />
    <sql:update dataSource="${snapshot}" var="count">
         DELETE FROM website WHERE id = ?
         <sql:param value="${id}" />
    </sql:update>--%>
    <%-- 修改website表中id为8数据
    <c:set var="id" value="8" />
    <sql:update dataSource="${snapshot}" var="count">
         UPDATE website SET name="biancheng" WHERE id = ?
         <sql:param value="${id}" />
    </sql:update>--%>
    <%-- 查询数据 --%>
    <sql:query dataSource="${snapshot}" var="result">
        SELECT * from website;
    </sql:query>
    <table border="1" width="100%">
        <tr>
            <th>id</th>
            <th>name</th>
            <th>url</th>
            <th>age</th>
            <th>country</th>
        </tr>
        <c:forEach var="row" items="${result.rows}">
            <tr>
                <td><c:out value="${row.id}" /></td>
                <td><c:out value="${row.name}" /></td>
                <td><c:out value="${row.url}" /></td>
                <td><c:out value="${row.age}" /></td>
                <td><c:out value="${row.country}" /></td>
            </tr>
        </c:forEach>
    </table>
</body>
</html>

运行结果如下:

查询数据
查询数据

添加数据
添加数据

修改数据
修改数据

删除数据
删除数据

JSP分页功能

当数据有几万、几十万甚至上百万时,用户必须要拖动页面才能浏览更多的数据,很大程度的影响了用户体验。这时可以使用分页来显示数据,能够使数据更加清晰直观,且不受数量的限制。

分页的方式主要分为两种:

  • 将查询结果以集合等形式保存在内存中,翻页时从中取出一页数据显示。该方法可能导致用户浏览到的是过期数据,且如果数据量非常大,查询一次数据就会耗费很长时间,存储的数据也会占用大量的内存开销。
  • 每次翻页时只从数据库中检索出本页需要的数据。虽然每次翻页都需要查询数据库,但查询的记录数相对较少,总体开销不大,再配以连接池等技术进行优化,可以达到比较高的效率。

实现分页步骤

实现数据的分页显示,需要以下几个关键步骤:

1)确定每页显示的数据数量

确定每页显示的记录条数,即每次从数据库中需要查询出多少条记录用于页面显示。通常这个数量可以在开发时定义好,也可以由用户来选择。

2)计算显示的总页数

根据每页显示的记录条数计算总页数,即会产生多少页数据。显示的记录数量是已知的,而数据库中符合条件的记录总数是未知的,因此想要得到总页数,需要先得到符合条件的记录总数。

3)编写SQL语句

使用相应的 SQL 语句实现分页需求。例如,MySQL 中的 LIMIT 子句,SqlServer 中的 TOP、Oracle 中的 ROWNUM 等。

注意:本节使用的是 MySQL 数据库。不同的数据库厂商实现分页的 SQL 语句会存在差异,因此在实际应用中根据数据库的不同,需要修改相应的 SQL 语句。

示例

创建 website 数据表,并插入数据。点击下载 SQL 文件(下载后需要解压)。

Website 类的代码如下:

package net.biancheng.entity;
public class Website {
    private int id;
    private String name;
    private String url;
    private int age;
    private String country;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getCountry() {
        return country;
    }
    public void setCountry(String country) {
        this.country = country;
    }
}

基于方便代码管理的考虑,将有关分页的数据封装到一个 Page 类中,其中包括每页显示的数据数量、数据的总数量、显示的总页数、当前页码、每页显示的数据集合。Page 代码如下:

package net.biancheng.utils;
import java.util.List;
import net.biancheng.entity.Website;
public class Page {
    // 总页数
    private int totalPageCount = 0;
    // 页面大小,即每页显示记录数
    private int pageSize = 3;
    // 记录总数
    private int totalCount;
    // 当前页码
    private int currPageNo = 1;
    // 每页网站集合
    private List<Website> websiteList;
    public int getTotalPageCount() {
        return totalPageCount;
    }
    public void setTotalPageCount(int totalPageCount) {
        this.totalPageCount = totalPageCount;
    }
    public int getPageSize() {
        return pageSize;
    }
    public void setPageSize(int pageSize) {
        if (pageSize > 0)
            this.pageSize = pageSize;
    }
    public int getTotalCount() {
        return totalCount;
    }
    public void setTotalCount(int totalCount) {
        if (totalCount > 0) {
            this.totalCount = totalCount;
            // 计算总页数
            totalPageCount = this.totalCount % pageSize == 0 ? (this.totalCount / pageSize)
                    : (this.totalCount / pageSize + 1);
        }
    }
    public int getCurrPageNo() {
        if (currPageNo == 0)
            return 0;
        return currPageNo;
    }
    public void setCurrPageNo(int currPageNo) {
        if (currPageNo > 0)
            this.currPageNo = currPageNo;
    }
    public List<Website> getWebsiteList() {
        return websiteList;
    }
    public void setWebsiteList(List<Website> websiteList) {
        this.websiteList = websiteList;
    }
}

在 setTotalCount() 方法中,根据记录总数和每页显示记录数计算出总页数,使用三元运算符?:进行处理。如果记录总数能被每页显示记录数整除,则总页数为两者的商,如果不能被整除,则余出的记录数单独列为一页,总页数为两者的商再加 1。

WebsiteDao 代码如下:

package net.biancheng.dao;
import java.util.List;
import net.biancheng.entity.Website;
public interface WebsiteDao {
    // 查询总条数
    public int getTotcalCount();
    //根据起始下标和每页显示数量查询数据
    public List<Website> getPageWebsiteList(int pageNo, int pagesize);
}

WebsiteDaoImpl 代码如下:

package net.biancheng.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import net.biancheng.entity.Website;
public class WebsiteDaoImpl implements WebsiteDao {
    /**
     * 连接数据库
     */
    public static Connection getConnection() {
        Connection con = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return con;
    }
    /**
     * 查询总条数
     */
    @Override
    public int getTotcalCount() {
        int count = 0;
        try {
            Connection con = getConnection();
            String sql = "SELECT COUNT(id) FROM website";
            PreparedStatement ps = con.prepareStatement(sql);
            ResultSet rs = ps.executeQuery();
            rs.next();
            count = rs.getInt(1);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return count;
    }
    @Override
    public List<Website> getPageWebsiteList(int pageNo, int pagesize) {
        PreparedStatement ps;
        ResultSet rs;
        List<Website> list = new ArrayList<Website>();
        try {
            Connection con = getConnection();
            String sql = "SELECT * FROM website LIMIT" + (pageNo - 1) * pagesize + "," + pagesize;
            ps = con.prepareStatement(sql);
            System.out.println(sql);
            rs = ps.executeQuery();
            while (rs.next()) {
                Website website = new Website();
                website.setId(rs.getInt(1));
                website.setName(rs.getString(2));
                website.setUrl(rs.getString(3));
                website.setAge(rs.getInt(4));
                website.setCountry(rs.getString(5));
                list.add(website);
            }
            con.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }
}

view.jsp 页面代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page
    import="java.util.*,net.biancheng.dao.*,net.biancheng.entity.*,net.biancheng.utils.*"%>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body>
    <%
        WebsiteDao websiteDao = new WebsiteDaoImpl();
        String pageNo = request.getParameter("page") != null ? request.getParameter("page") : "1";
        int currPageNo = Integer.parseInt(pageNo);
        Page p = new Page();
        p.setCurrPageNo(currPageNo);
        p.setPageSize(3);
        p.setTotalCount(websiteDao.getTotcalCount());
        List<Website> websiteList = websiteDao.getPageWebsiteList(p.getCurrPageNo(), p.getPageSize());
        p.setWebsiteList(websiteList);
        out.print("<h1>当前页面: " + currPageNo + "</h1>");
        out.print("<table border='1' cellpadding='4' width='60%'>");
        out.print("<tr><th>id</th><th>name</th><th>url</th><th>age</th><th>country</th></tr>");
        for (Website e : websiteList) {
            out.print("<tr><td>" + e.getId() + "</td><td>" + e.getName() + "</td><td>" + e.getUrl() + "</td><td>"
                    + e.getAge() + "</td><td>" + e.getCountry() + "</td></tr>");
        }
        out.print("</table>");
        for (int i = 1; i <= p.getTotalPageCount(); i++) {
    %>
    <a href="view.jsp?page=<%=i%>"><%=i%></a>
    <%
        }
    %>
</body>
</html>

运行结果如下:

view.jsp运行结果

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Java学习路线之JavaWeb】JSP教程 的相关文章

  • 如何写好一个数据分析报告,需要注意哪些?

    写一份好的数据分析报告的重要性不言而喻 xff08 只要我写的好 xff0c 升职加薪 年终奖就少不了我 xff09 大家都知道 xff0c 数据分析报告的输出是整个业务分析过程的成果 xff0c 是评定一条业务线的参考依据 xff0c 既
  • 任正非:全面提升软件工程能力与实践,打造可信的高质量产品

    最近看了点软件工程相关的东西 xff0c 转一下这篇文章 全面提升软件工程能力与实践 xff0c 打造可信的高质量产品 致全体员工的一封信 我今天写信 xff0c 是要和大家沟通公司如何全面提升软件工程能力和实践 二十年前的IPD变革 xf
  • 你真的会画时序图吗?

    文章目录 一 WaveDrom功能二 WaveDrom的使用三 绘制时序图四 时序图教程五 逻辑电路图教程六 Github主页七 VScode中使用Waveform 摘要 xff1a WaveDrom是一个免费开源的在线数字时序图渲染引擎
  • 【LeetCode刷题日记】1332. 删除回文子序列

    题目 给你一个字符串 s xff0c 它仅由字母 39 a 39 和 39 b 39 组成 每一次删除操作都可以从 s 中删除一个回文 子序列 返回删除给定字符串中所有字符 xff08 字符串为空 xff09 的最小删除次数 子序列 定义
  • PicGo图床与Typora(PicGo+Typora+GitHub的完整设置)以及常见错误的解决方法

    首先介绍下怎么使用PicGo 43 Typora 43 GitHub来搭建属于自己的图床 xff0c 后面介绍一下使用过程中可能产生的错误 本文主要参考下面两篇文章 xff1a PicGo图床与Typora xff08 PicGo 43 T
  • 【Python学习教程】Python编程基础

    文章目录 编程语言是什么编译型语言和解释型语言的区别编译型语言1 可执行程序不能跨平台2 源代码不能跨平台 解释型语言关于 Python总结 Python是什么 xff0c Python简介Python的特点 xff08 优点和缺点 xff
  • 【Python学习教程】Python编程环境搭建

    文章目录 Windows安装Python xff08 图解 xff09 关于 IDLE Linux xff08 Ubuntu xff09 系统安装Python更新 Python 版本重新安装 Python1 下载源代码2 编译 小技巧 Ma
  • 【Python学习教程】Python变量类型和运算符

    文章目录 Python变量的定义和使用Python 变量的赋值Python 变量的使用Python 是弱类型的语言 Python整数类型 xff08 int xff09 详解关于 Python 2 x整数的不同进制1 十进制形式2 二进制形
  • 【Python学习教程】Python列表(list)、元组(tuple)、字典(dict)和集合(set)详解

    文章目录 什么是序列 xff0c Python序列详解 xff08 包括序列类型和常用操作 xff09 序列索引序列切片序列相加序列相乘检查元素是否包含在序列中和序列相关的内置函数 Python list列表详解Python创建列表1 使用
  • 手把手教用ROS做机器人控制(二)--加速度计与陀螺仪两种融合算法:mahony 互补滤波器算法与EKF算法

    对于加速计与陀螺仪融合 xff0c 介绍两种滤波算法 xff1a 他们的核心思想不太相同 xff0c 这两种方法现在也已经有了应用 xff0c 现在你可以发现互补滤波融合在无人机上 xff0c EKF我做过在平衡车上面 mathony主要思
  • 【Python学习教程】Python模块和包

    文章目录 什么是模块 xff0c Python模块化编程 xff08 入门必读 xff09 Python导入模块 xff0c Python import用法 xff08 超级详细 xff09 import 模块名 as 别名from 模块名
  • 【Python学习教程】Python字符串常用方法详解

    文章目录 Python字符串拼接 xff08 包含字符串拼接数字 xff09 Python字符串和数字的拼接str 和 repr 的区别 Python截取字符串 xff08 字符串切片 xff09 方法详解获取单个字符获取多个字符 xff0
  • 【Python学习教程】Python流程控制

    文章目录 Python if else条件语句详解if else 如何判断表达式是否成立 Python if else对缩进的要求不要忘记缩进缩进多少合适 xff1f 所有语句都要缩进同一代码块缩进量要相同不要随便缩进 Python if语
  • 【Python学习教程】Python函数和lambda表达式

    文章目录 Python函数 xff08 函数定义 函数调用 xff09 用法详解Python函数的定义Python函数的调用为函数提供说明文档 Python函数值传递和引用传递 xff08 包括形式参数和实际参数的区别 xff09 Pyth
  • 【Python学习教程】Python类和对象

    文章目录 什么是面向对象 xff0c Python面向对象 xff08 一切皆对象 xff09 面向对象相关术语 Python class xff1a 定义类 xff08 入门必读 xff09 Python类的定义 Python init
  • 最易学和最难学的编程语言Top 5

    文 白开水不加糖 出品 OSC开源社区 xff08 ID xff1a oschina2013 xff09 在线学习平台 Springboard 罗列了一个最容易学习和最难学的编程语言 Top 5 榜单 事实上 xff0c 问一个程序员最容易
  • 【Python学习教程】Python异常处理机制

    文章目录 什么是异常处理 xff0c Python常见异常类型 xff08 入门必读 xff09 Python语法错误Python运行时错误 Python异常处理机制到底有什么用 xff1f Python try except异常处理详解
  • 【NumPy教程】(快速入门版)

    文章目录 读者阅读条件 NumPy是什么NumPy使用需求NumPy应用场景 NumPy下载与安装Windows系统安装MacOSX系统安装Linux系统安装1 Ubuntu Debian2 Redhat CentOS NumPy ndar
  • Pillow(PIL)入门教程(非常详细)

    文章目录 相关资源 教程特点读者 amp 阅读条件 Pillow是什么Pillow版本支持Pillow库特点1 支持广泛的文件格式2 提供了丰富的功能3 配合GUI工具使用 Pillow的下载与安装pip包管理器安装二进制包安装Anacon
  • Tkinter教程

    文章目录 Tkinter教程 xff08 非常详细 xff09 教程特点阅读条件 GUI是什么GUI发展史GUI应用领域GUI的优势GUI开发工具 Tkinter是什么第一个Tkinter程序1 主窗口设置2 添加文本3 添加按钮4 独立运

随机推荐

  • 成功解决卡巴斯基6莫名其妙自动关闭的问题

    卡巴斯基6确实是个不错的杀毒工具 xff0c 但是安装好后 xff0c 会有个特别烦人的问题 xff0c 老是会提示错误 xff0c 然后自动关闭 xff0c 在网上查了一下 xff0c 终于找到了解决方案 解决步骤如下 xff1a 1 进
  • Tcl和Tk教程

    在Python Tkinter中 xff0c 重新了解到TCL和Tk 想起之前在做分子动力学模拟的时候 xff0c 有用到一个软件 xff0c 其命令行好像就是支持Tcl脚本 xff0c 当时对CS没那么了解 xff0c 所以也就没有深入了
  • Gromacs安装教程及一些思考

    写这篇博客目的当然不是只安装一下GROMAC xff0c 而是想借这个机会思考一下认知的问题 想起来刚上研究生的时候 xff0c 要在Linux服务器上安装这个软件 xff0c 当时费了好大劲 xff0c 各种求助师兄 xff0c 虽然安装
  • 如何高效地学习开源项目

    转载于 xff1a https time geekbang org column article 10022 你好 xff0c 我是华仔 今天这期 特别放送 xff0c 我想和你聊聊如何高效地学习开源项目 xff0c 一方面澄清开源项目学习
  • 52个数据可视化图表鉴赏

    文章目录 1 弧线图2 面积图3 箭头图4 条形图5 布林线指标6 箱线图7 气泡地图8 子弹图9 凹凸图10 日历图11 烛台图12 卡通图13 弦图14 分级统计图15 组合图表16 连接地图17 控制图18 南丁格尔玫瑰图19 交叉表
  • 【程序员学理财】不同产业的市场规模

    程序员学理财 不同产业的市场规模 先来了解一些常识 三大产业 第一产业主要指生产食材以及其它一些生物材料的产业 xff0c 包括种植业 林业 畜牧业 水产养殖业等直接以自然物为生产对象的产业 xff08 泛指农业 xff09 第二产业主要指
  • 【程序员学理财】有哪些普通人应该知道的经济学常识?

    文章目录 一 前言二 宏观经济学1 名词定义2 主要内容 三 微观经济学1 名词定义2 研究内容3 对比区别 四 降息降准是什么意思 xff1f 五 一些常用术语1 沉没成本2 边际成本 一 前言 每天我们都在跟 经济 打交道 xff0c
  • 【程序员学理财】汽车行业、手机行业简单了解

    汽车行业 本文章不是专业的解读 xff0c 只是为了让自己对汽车行业建立一个大体的认知 先简单看两个新闻 xff1a 2021年销量出炉 xff0c 中国车企卷翻了 才一年 xff0c 智能车就不再是新势力专利 xff01 当然上面这些是从
  • 【LeetCode刷题日记】1996. 游戏中弱角色的数量

    题目 你正在参加一个多角色游戏 xff0c 每个角色都有两个主要属性 xff1a 攻击 和 防御 给你一个二维整数数组 properties xff0c 其中 properties i 61 attacki defensei 表示游戏中第
  • LEETCODE 编程训练

    转载于 xff1a https coolshell cn articles 12052 html Leetcode这个网站上的题都是一些经典的公司用来面试应聘者的面试题 xff0c 很多人通过刷这些题来应聘一些喜欢面试算法的公司 xff0c
  • 【程序员学理财】零和博弈和对股市的一些了解

    一 零和博弈 零和博弈 xff08 zero sum game xff09 xff0c 又称零和游戏 xff0c 与非零和博弈相对 xff0c 是博弈论的一个概念 xff0c 属非合作博弈 它是指参与博弈的各方 xff0c 在严格竞争下 x
  • C++11新特性之十:enable_shared_from_this

    enable shared from this是一个模板类 xff0c 定义于头文件 lt memory gt xff0c 其原型为 xff1a template lt class T gt class enable shared from
  • 【程序员学理财】曼昆:经济学十大原理,你都了解吗?

    经济学十大原理是哈佛大学经济学教授格里高利 曼昆在其著作 经济学原理 中提出 xff0c 通俗易懂 xff0c 是很多高校经济学考研的指定参考书 很多人觉得经济学一听就是高大上 xff0c 非常深奥 xff0c 其实并不是的 xff0c 今
  • 2022年java学习路线总结

    直接放两个非常好的文章 xff0c 链接如下 xff1a 2021年Java后端开发学习路线 xff08 建议收藏 xff01 xff09 Java后端学习路线图 xff0c 你真的只需要这一张 xff01 最后放一段守护石的 xff1a
  • web服务器与浏览器之间的网络通信过程

    浏览器与web服务器的交互过程 1 浏览器与web服务器的通信原理概述 网络编程 xff08 一 xff09 浅析web服务器与浏览器的实现原理
  • Tomcat部署Web项目的几种方法

    tomcat 部署web项目的四种方法 Tomcat部署Web项目的3种方式
  • 心跳机制详解

    心跳机制 心跳机制详解 什么是TCP心跳机制
  • 学习Spring之前要先学习什么?

    转载于 xff1a https zhuanlan zhihu com p 64001753 开门见山 xff0c 先放结论 要开始学习Spring xff08 以IOC和Spring MVC为核心 xff09 xff0c 只需要做好以下准备
  • 【程序员学理财】有关fd的一些了解

    https www 163 com dy article GJK2KL600535EAS7 html https www fangdaijisuanqi com https www 163 com dy article GMUC9K5805
  • 【Java学习路线之JavaWeb】JSP教程

    文章目录 为什么要学习JSP xff1f 读者阅读条件 JSP到底是什么JSP的由来Servlet与JSP异同点JSP相对于Servlet的优点1 xff09 易于维护2 xff09 快速开发 xff1a 无需重新编译和部署3 xff09