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

本文深入探讨了JSP(JavaServerPages)技术,从其基本概念到实际应用,包括JSP页面结构、JSP指令、内置对象、表达式、脚本元素、动作标签等。通过实例展示了JSP如何处理HTTP请求、响应,以及如何与Servlet、JavaBean、数据库和Cookie交互。此外,还讲解了JSP生命周期、错误处理、分页和数据访问。

转载于: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 也用于生成动态网页。

不同点如下:

序号 Servlet JSP
1 Servlet 在 Java 内添加 HTML 代码 JSP 在 HTML 内添加 Java 代码
2 Servlet 是一个 Java 程序,支持 HTML 标签 JSP 是一种 HTML 代码,支持 Java 语句
3 Servlet 一般用于开发程序的业务层(做一些复杂的逻辑处理) JSP 一般用于开发程序的表示层(显示数据)
4 Servlet 由 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 page 指令用来定义当前页面的相关属性。page 指令可以在 JSP 页面的任意位置编写,通常放在 JSP 页面的顶部。

page 指令的语法如下:

<%@ page attribute = “value” %>

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

属 性 取 值 说 明 举 例
buffer none、缓冲区大小(默认值为 8kb) 指定输出流是否有缓冲区 <%@ page buffer=“16kb” %>
autoFlush true(默认值)、false 指定缓冲区是否自动清除 <%@ page autoFlush=“true” %>
contentType text/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
isErrorpage true、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=“这里是编程帮的页面信息”%>
isThreadSafe true(默认值)、false 是否允许多线程使用 <%@ page isThreadSafe=“false” %>
language 脚本语言 指定页面中使用的脚本语言 <%@ page language= “java” %>
session true(默认值)、false 指定页面是否使用 session <%@ page session=“false” %>
isELIgnored true(默认值)、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九大内置对象一览表

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

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

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

九大内置对象

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

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

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

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

四大域对象

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

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

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

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

作用域 描述 作用范围
page 如果把属性保存到 pageContext 中,则它的作用域是 page。 该作用域中的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机载软件与适航

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值