JSP文件上传与AJAX JSON数据交互实践指南

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:文件上传和AJAX获取JSON是Web开发中的基础功能,尤其在实现用户交互和数据交换方面非常重要。本文将通过一个基于JSP的示例,展示如何使用Servlet和Apache Commons FileUpload库来处理文件上传,同时结合AJAX技术实现从前端到后端的异步通信,获取并处理JSON格式数据。通过实践案例,学习者将掌握文件上传和JSON数据获取的完整流程,以及如何在前端页面上利用这些技术实现动态更新。 文件上传和ajax获取json的小示例

1. 文件上传在Web应用中的作用和实现方式

简介

在现代Web应用中,文件上传是一种常见的功能,它允许用户通过浏览器上传图片、文档、视频等文件到服务器。对于企业而言,提供文件上传功能可以增加交互性,方便用户上传个人资料、产品信息、技术报告等重要信息。对于社交平台、在线协作工具和电子商务网站等来说,文件上传功能是不可或缺的。

文件上传的作用

文件上传有多种作用,关键包括但不限于以下几点:

  • 用户交互 :用户可以通过上传文件来分享个人资料、图片、视频等内容,提高了用户与网站之间的互动性。
  • 数据收集 :企业或组织通过文件上传收集用户反馈、产品规格书、技术文档等重要信息。
  • 在线协作 :文档编辑和分享功能,让用户可以实时协作,共同完成项目工作。

实现方式

文件上传在Web应用中的实现方式主要有两种:

  1. 传统表单上传 :用户在表单中选择要上传的文件,提交到服务器,服务器通过解析表单数据来获取文件内容。这种方式简单直观,适合大多数文件上传场景。

  2. 利用AJAX技术上传 :通过AJAX技术可以无刷新地上传文件,提升用户体验。结合一些JavaScript库如 Fine-Uploader Plupload ,可以实现更复杂的文件上传功能,如上传进度显示、断点续传等。

在接下来的章节中,我们将更深入地探讨使用Servlet和Apache Commons FileUpload库在JSP中实现文件上传的详细步骤和代码示例。这将帮助理解在后端服务器中处理文件上传的逻辑,以及如何优化这一过程以提高效率和安全性。

2. JSP中Servlet的使用以及Apache Commons FileUpload库的集成

2.1 Servlet技术概述

2.1.1 Servlet的基本概念和生命周期

Servlet是一个运行在服务器端的Java类,用于生成动态的网页内容。它响应客户端的请求,处理并返回HTTP响应。Servlet的基本生命周期涉及三个主要阶段:加载和实例化、初始化、请求处理和服务以及销毁。

加载和实例化发生在Servlet类被加载至JVM后,并且一个Servlet实例被创建。初始化则是在Servlet创建后调用init()方法进行初始化工作。请求处理和服务是Servlet的主要功能,每当一个客户端请求到达时,Servlet调用service()方法处理这个请求。销毁阶段则是在Web容器关闭或者需要释放资源时,调用destroy()方法执行清理操作。

2.1.2 Servlet的配置与部署

Servlet可以通过web.xml文件进行配置,也可以使用注解进行配置。在web.xml中配置Servlet通常包括Servlet的名称、类名、初始化参数和映射的URL模式。部署Servlet时,需要将编译后的.class文件放到正确的目录,并且在web.xml文件中进行相应的配置。使用注解配置Servlet则简化了这个过程。

<web-app>
    <servlet>
        <servlet-name>MyServlet</servlet-name>
        <servlet-class>com.example.MyServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/my-servlet</url-pattern>
    </servlet-mapping>
</web-app>

以上是一个简单的Servlet配置实例,它将类 com.example.MyServlet 映射到了URL模式 /my-servlet

2.2 Apache Commons FileUpload库

2.2.1 FileUpload库的结构和特性

Apache Commons FileUpload是一个用于处理HTTP文件上传的Java库。它支持单部分和多部分文件上传,并且能够处理大型文件上传,避免了内存溢出的问题。它还提供了方便的API来解析上传的数据,同时允许开发者轻松地获取文件信息,如文件名、大小以及类型。

FileUpload库包含以下两个主要组件: - DiskFileItemFactory :用于处理文件存储的工厂类。 - FileUpload :核心上传处理类,用于解析请求并提取文件。

2.2.2 集成FileUpload库到项目中

要将FileUpload库集成到项目中,首先需要将其依赖添加到项目的构建路径中。如果你使用Maven进行项目管理,可以在pom.xml文件中添加以下依赖:

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>

接下来,你需要编写代码来解析多部分请求。以下是使用FileUpload库解析上传文件请求的基本步骤:

// 创建DiskFileItemFactory对象
DiskFileItemFactory factory = new DiskFileItemFactory();

// 创建ServletFileUpload对象,用于解析请求
ServletFileUpload upload = new ServletFileUpload(factory);

// 解析请求并获取文件列表
List<FileItem> items = upload.parseRequest(request);

// 遍历文件列表处理上传的文件
for (FileItem item : items) {
    if (item.isFormField()) {
        // 处理表单字段
    } else {
        // 处理上传的文件
    }
}

2.3 文件上传的实现流程

2.3.1 文件上传的表单结构

在HTML页面中,文件上传通常通过一个表单来实现。表单需要设置 enctype 属性为 multipart/form-data ,这样表单数据才能被编码为多个部分,每一个部分对应一个表单字段。 <input type="file"> 标签用于选择文件。

以下是一个简单的文件上传表单的例子:

<form action="uploadServlet" method="post" enctype="multipart/form-data">
    <input type="file" name="file" />
    <input type="submit" value="Upload" />
</form>

2.3.2 服务器端的文件接收逻辑

在服务器端,使用Servlet来处理文件上传请求。通常需要重写 doPost() 方法来处理表单提交的数据。使用FileUpload库解析请求并处理文件上传逻辑。

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // ...初始化FileUpload的配置...

    try {
        // 解析请求并获取文件列表
        List<FileItem> items = upload.parseRequest(request);

        // 处理文件列表...
        for (FileItem item : items) {
            if (!item.isFormField()) {
                // 处理上传的文件
                String fileName = new File(item.getName()).getName();
                File storeFile = new File("upload", fileName);
                item.write(storeFile);
                // 可以添加文件信息到数据库或其他存储系统...
            }
        }

        // 上传成功后,返回成功信息
        response.getWriter().print("Upload succeeded");
    } catch (Exception ex) {
        // 上传异常处理
        response.getWriter().print("Upload failed: " + ex.getMessage());
    }
}

以上代码展示了文件上传的基本逻辑,包括处理文件上传的请求、保存文件到服务器以及处理异常情况。通过这个示例,我们可以看到使用Servlet和FileUpload库实现文件上传功能的完整流程。

[下接第三章:AJAX技术在Web开发中的应用]

3. AJAX技术在Web开发中的应用

3.1 AJAX技术简介

3.1.1 AJAX的定义和核心组成

AJAX(Asynchronous JavaScript and XML)是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。其核心由以下几个组件构成:

  1. 浏览器内置的 XMLHttpRequest 对象 :用于在客户端和服务器之间异步传输数据。
  2. JavaScript 和 HTML DOM :利用 JavaScript 操作 HTML 文档对象模型(DOM),以实现动态更新网页内容。
  3. CSS :用于定义和更改文档的呈现样式。
  4. 可选的 XML :XML 被用作数据交换格式,但也可以使用 JSON 或其他数据格式。

3.1.2 AJAX的工作原理

AJAX 的工作原理是通过 JavaScript 创建 XMLHttpRequest 对象,然后调用其 open() 方法配置请求, send() 方法发送请求。服务器返回的数据可以是 XML、JSON、HTML 或纯文本等格式。当服务器响应时,会触发 onreadystatechange 事件处理器,JavaScript 在该处理器中可以读取响应数据并进行处理。

3.2 AJAX与传统Web交互的对比

3.2.1 传统Web交互模式的局限性

传统 Web 应用通常采用同步的请求-响应模式,即每个用户操作都会引起页面的全面刷新。这不仅导致了不必要的数据加载,还影响了用户体验,因为每次刷新都会导致页面状态重置。

3.2.2 AJAX带来的改进和优势

AJAX技术的使用让Web应用能够实现异步通信,这样在进行数据交换时无需重新加载整个页面,因此提升了用户交互的流畅性和应用的响应速度。此外,AJAX可以减少服务器负载,因为它只需要发送或接收必要的数据,而不是整个HTML页面。

3.3 AJAX技术的实现要点

3.3.1 XMLHttpRequest对象的使用

XMLHttpRequest 对象是实现AJAX通信的核心。下面是一个基本的请求创建和发送过程:

// 创建一个 XMLHttpRequest 实例
var xhr = new XMLHttpRequest();

// 配置请求类型、URL以及是否异步
xhr.open('GET', 'data.txt', true);

// 当请求成功返回时触发
xhr.onload = function () {
  if (xhr.status >= 200 && xhr.status < 300) {
    // 处理响应数据
    console.log(this.responseText);
  } else {
    // 处理错误情况
    console.error('The request failed!');
  }
};

// 发送请求
xhr.send();

3.3.2 同步与异步请求的区别和选择

XMLHttpRequest 请求可以是同步也可以是异步:

  • 同步请求 :会阻塞 JavaScript 的执行,直到请求完成。
  • 异步请求 :允许 JavaScript 继续执行,当服务器响应到达时,会触发 onreadystatechange 事件处理器。

一般情况下,推荐使用异步请求,因为它不会阻塞用户界面,提升用户体验。而同步请求可能会导致用户体验下降,因为它会暂停所有其他操作直到请求完成。

3.3.3 实际应用案例

在实际应用中,使用AJAX获取数据,然后用JavaScript更新DOM是一种常见的模式。例如,下面的代码展示了如何使用AJAX获取JSON数据并动态更新网页内容:

document.getElementById('loadData').addEventListener('click', function() {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'data.json', true);
  xhr.responseType = 'json'; // 设置响应类型为 JSON,便于直接获取 JSON 数据
  xhr.onload = function() {
    if (xhr.status === 200) {
      var data = xhr.response; // 直接使用 JavaScript 对象形式的数据
      document.getElementById('output').innerHTML = JSON.stringify(data, null, 2);
    } else {
      console.error('Request failed. Returned status of ' + xhr.status);
    }
  };
  xhr.onerror = function() {
    console.error('Request failed to send.');
  };
  xhr.send();
});

此代码段展示了在用户点击按钮后如何异步加载数据,并将返回的 JSON 数据格式化为字符串输出到页面上。使用 responseType 将响应类型设置为 json 可以让浏览器自动将JSON字符串转换成JavaScript对象,简化数据处理过程。

4. JSON数据格式及其在前后端通信中的重要性

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。它是基于JavaScript的一个子集。数据格式简洁且易于理解,目前已成为互联网应用中前后端通信时使用最广泛的数据格式之一。

4.1 JSON数据格式介绍

4.1.1 JSON的基本结构和类型

JSON的基本数据结构包括对象、数组、字符串、数值、布尔值和null。对象是键值对的集合,可以包含多个键值对。数组是值的有序集合,可以包含多个值。字符串是以双引号包围的零个或多个Unicode字符的序列。数值是表示一个数字的字符串。布尔值有两个值true和false。null用于表示空值。

JSON的基本格式如下:

{
    "key": "value",
    "key1": {
        "key2": "value2",
        "key3": "value3"
    },
    "key4": ["value4", "value5", "value6"],
    "key5": true,
    "key6": null
}

4.1.2 JSON与XML的对比

JSON与XML都是用于数据交换的格式,但JSON具有更简洁的语法和更小的体积,这使得JSON在数据交换过程中加载速度更快,解析效率更高。JSON是轻量级的,不像XML那样包含很多额外的标记,这使得它在Web应用中更为流行。

4.2 JSON在前后端通信中的角色

4.2.1 前后端数据交互的需求

在Web应用中,前后端之间需要频繁地进行数据交互。前端页面需要向服务器请求数据,后端需要向前端返回数据。数据交互应尽可能地减少网络带宽的使用,并提高数据传输的效率。

4.2.2 JSON作为数据交换格式的优势

JSON格式的数据具有轻量级和易读性的优点,它可以直接被JavaScript解析和使用,无需进行转换。在前后端通信中,使用JSON作为数据交换格式,可以降低服务器和客户端的负载,提高数据交换的效率。JSON的结构简单,使得数据结构易于理解和处理。

4.3 JSON数据处理工具和库

4.3.1 JSON解析和生成的方法

在Web开发中,经常需要处理JSON数据。JavaScript提供了 JSON.parse() JSON.stringify() 这两个内置方法,分别用于解析JSON字符串和将对象转换成JSON字符串。

// JSON字符串解析成JavaScript对象
var obj = JSON.parse('{"name":"John", "age":30, "city":"New York"}');

// JavaScript对象转换成JSON字符串
var jsonString = JSON.stringify({name: "John", age: 30, city: "New York"});

4.3.2 常用的JSON处理库

除了原生的JSON处理方法外,还有一些常用的JSON处理库,例如jQuery的AJAX方法。jQuery的 $.parseJSON() $.toJSON() 方法可以用来解析JSON字符串和生成JSON字符串。

// 使用jQuery的$.parseJSON方法解析JSON字符串
var obj = $.parseJSON('{"name":"John", "age":30, "city":"New York"}');

// 使用jQuery的$.toJSON方法生成JSON字符串
var jsonString = $.toJSON({name: "John", age: 30, city: "New York"});

在实际开发中,可以根据具体需求选择合适的JSON处理方法和库。使用原生方法具有更好的兼容性,而使用库则可能提高开发效率。

通过本章节的介绍,我们了解了JSON数据格式的基本结构和类型,以及它在前后端通信中的重要性。JSON的数据处理方法和常用库的使用,为我们开发Web应用提供了便利。下一章节我们将继续深入探讨,如何使用JavaScript进行异步请求的发送与响应处理。

5. 使用JavaScript进行异步请求发送与响应处理

在现代Web开发中,异步通信已成为不可或缺的一部分。JavaScript是实现异步通信的主角之一,它通过AJAX技术与服务器进行交互,从而实现实时数据处理和动态页面更新。本章将深入探讨如何在JavaScript中使用AJAX进行异步请求的发送与处理。

5.1 JavaScript中的AJAX请求

5.1.1 创建AJAX请求的方法

在JavaScript中创建AJAX请求的基本方法是使用XMLHttpRequest对象。随着技术的发展,现在更常用的是 fetch API,它提供了更简洁的接口来发送网络请求。

// 使用传统的 XMLHttpRequest 对象
function traditionalAjax(url) {
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function() {
    if (xhr.readyState == 4 && xhr.status == 200) {
      console.log(xhr.responseText);
    }
  };
  xhr.open('GET', url, true);
  xhr.send();
}

// 使用现代的 fetch API
function fetchAjax(url) {
  fetch(url)
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error('Error:', error));
}

traditionalAjax 函数创建了一个XMLHttpRequest对象,并设置了状态变化的回调函数。当请求完成时,通过检查 readyState status 来确定是否成功接收响应,并输出响应文本。而 fetchAjax 函数使用了 fetch API来发送请求,它返回一个Promise对象,允许我们使用 .then .catch 来处理成功和错误情况。

5.1.2 发送请求到服务器并接收响应

无论是使用 XMLHttpRequest 还是 fetch ,发送请求的步骤都涉及指定请求的方法(如GET或POST)、URL以及必要时发送数据到服务器。然后,开发者可以处理来自服务器的响应。

// 使用传统的 XMLHttpRequest 对象发送POST请求
function postTraditionalAjax(url, data) {
  var xhr = new XMLHttpRequest();
  xhr.open('POST', url, true);
  xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  xhr.onreadystatechange = function() {
    if (xhr.readyState == 4 && xhr.status == 200) {
      console.log(xhr.responseText);
    }
  };
  xhr.send(data);
}

// 使用 fetch API 发送 POST 请求
function postFetchAjax(url, data) {
  fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
  })
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));
}

postTraditionalAjax 函数通过设置 Content-Type 头部并使用 .send(data) 发送数据,实现了POST请求。 postFetchAjax 函数则更为简洁,通过传递一个配置对象来指定请求方法、头部和请求体。

5.2 数据的解析与处理

5.2.1 JSON数据在JavaScript中的解析

接收数据后,经常需要将其转换为JavaScript对象,以便于使用。大多数AJAX方法返回的数据是JSON格式的字符串,需要解析才能使用。

// 使用传统方式解析JSON
function parseJson的传统方式(jsonString) {
  var jsonObj = JSON.parse(jsonString);
  return jsonObj;
}

// 使用现代方法解析JSON
function parseJson现代方式(jsonString) {
  return JSON.parse(jsonString);
}

5.2.2 基于数据动态更新页面内容

解析数据后,下一步是根据解析后的数据更新页面。这通常涉及DOM操作,如插入、修改或删除页面元素。

function updatePageWithJson(jsonData) {
  var content = document.getElementById('content');
  content.innerHTML = jsonData.htmlContent; // 假设JSON数据包含htmlContent字段
}

5.3 错误处理与用户交互

5.3.1 AJAX请求的错误处理机制

错误处理是任何异步通信不可或缺的一部分。错误可能是由于网络问题、服务器错误或其他问题引起的。

// 添加错误处理的 fetch 示例
function fetchAjaxWithErrorHandling(url) {
  fetch(url)
    .then(response => {
      if (!response.ok) {
        throw new Error('Network response was not ok ' + response.statusText);
      }
      return response.json();
    })
    .then(data => console.log(data))
    .catch(error => console.error('Error:', error));
}

5.3.2 向用户提供请求进度和状态反馈

在某些情况下,向用户反馈请求的进度和状态是非常重要的。例如,在文件上传或大型数据下载时,进度条或状态信息可以帮助用户了解当前状态。

// 使用XMLHttpRequest对象处理文件上传进度
function uploadFileWithProgress(url, file) {
  var xhr = new XMLHttpRequest();
  xhr.upload.onprogress = function(event) {
    if (event.lengthComputable) {
      var percentComplete = event.loaded / event.total * 100;
      console.log('Upload progress: ' + percentComplete + '%');
    }
  };
  // 完成进度监听后发送请求
  xhr.open('POST', url, true);
  xhr.send(file);
}

以上章节详细介绍了如何在JavaScript中使用AJAX发送异步请求,并处理返回的数据。从创建请求到解析数据再到错误处理和用户反馈,每一个环节都至关重要,共同确保了Web应用的动态交互和实时响应能力。

6. 数据的异步获取与前端页面的实时更新技术

6.1 实时数据更新的技术实现

6.1.1 轮询技术

轮询技术是最基础的实时数据更新方法,通过定时向服务器发送请求来检查数据变化。使用JavaScript的 setInterval 函数可以实现定时任务,达到周期性发送请求的目的。轮询虽然简单,但在数据变化不频繁的情况下会造成服务器资源的浪费。

setInterval(function() {
    // 使用AJAX向服务器请求最新数据
    $.ajax({
        url: '/data-update', // 服务器端更新数据接口
        type: 'GET',
        dataType: 'json',
        success: function(response) {
            // 将获取的数据更新到页面中
            updatePage(response);
        }
    });
}, 5000); // 每5秒轮询一次

6.1.2 WebSockets和Server-Sent Events

WebSockets提供了一个持久连接的通道,服务器可以实时向客户端发送数据。而Server-Sent Events(SSE)是一种单向服务器推送技术,允许服务器向客户端推送新数据。

WebSockets的使用示例:

const socket = new WebSocket('ws://example.com/data');

socket.onmessage = function(event) {
    const data = JSON.parse(event.data);
    // 当服务器发送数据时,更新页面内容
    updatePage(data);
};

function updatePage(data) {
    // 更新逻辑...
}

Server-Sent Events的使用示例:

const evtSource = new EventSource('http://example.com/sse');
evtSource.onmessage = function(event) {
    const data = JSON.parse(event.data);
    // 当服务器推送数据时,更新页面内容
    updatePage(data);
};

function updatePage(data) {
    // 更新逻辑...
}

6.2 前端页面动态内容的渲染

6.2.1 动态内容的DOM操作技术

动态更新页面内容通常涉及到DOM操作,通过JavaScript来增删改查DOM元素。使用jQuery等库可以简化操作。

function updatePage(data) {
    // 清空现有内容
    $('#content').empty();
    // 遍历数据对象数组,动态添加元素到页面
    data.forEach(function(item) {
        const itemElement = $('<div>').addClass('data-item');
        itemElement.append($('<p>').text(item.title));
        itemElement.append($('<p>').text(item.description));
        $('#content').append(itemElement);
    });
}

6.2.2 利用模板引擎提升渲染效率

模板引擎如Mustache、Handlebars能够将数据和模板分离,提高页面渲染效率。模板定义在服务器端或者客户端,通过数据填充模板,生成最终的HTML内容。

<script id="item-template" type="text/template">
  <div class="data-item">
    <h3>{{title}}</h3>
    <p>{{description}}</p>
  </div>
</script>

<script>
const template = Handlebars.compile($('#item-template').html());

function updatePage(data) {
    $('#content').html(template({data: data}));
}
</script>

6.3 实际项目中技术的综合运用

6.3.1 文件上传和JSON数据获取的代码示例分析

在实现文件上传功能的同时,往往需要处理服务器返回的JSON格式数据。以下是使用HTML表单上传文件,并在上传成功后使用AJAX获取服务器反馈的JSON数据。

<form id="uploadForm" enctype="multipart/form-data">
    <input type="file" name="file" />
    <input type="button" value="上传" onclick="uploadFile()" />
</form>

<script>
function uploadFile() {
    var formData = new FormData(document.getElementById('uploadForm'));
    $.ajax({
        url: '/upload', // 服务器端文件上传接口
        type: 'POST',
        data: formData,
        processData: false,  // 告诉jQuery不要去处理发送的数据
        contentType: false,  // 告诉jQuery不要去设置Content-Type请求头
        success: function(response) {
            // 假设服务器返回的是JSON格式数据
            processServerResponse(JSON.parse(response));
        }
    });
}

function processServerResponse(data) {
    // 处理服务器返回的数据,如显示上传成功消息
    console.log(data);
}
</script>

6.3.2 项目中遇到的挑战与解决方案讨论

在项目实施过程中,挑战之一是如何有效处理大文件上传,特别是当用户上传大视频或图片文件时。解决方案之一是使用分块上传技术,将大文件分块,逐一上传,最后在服务器端进行组装。

另一个挑战是实时数据更新中的实时性问题。传统的轮询机制难以满足低延迟的要求。解决方案可以是结合使用WebSocket和轮询技术,在必要时使用WebSockets保持实时通信,而在无数据变化时使用轮询以节省服务器资源。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:文件上传和AJAX获取JSON是Web开发中的基础功能,尤其在实现用户交互和数据交换方面非常重要。本文将通过一个基于JSP的示例,展示如何使用Servlet和Apache Commons FileUpload库来处理文件上传,同时结合AJAX技术实现从前端到后端的异步通信,获取并处理JSON格式数据。通过实践案例,学习者将掌握文件上传和JSON数据获取的完整流程,以及如何在前端页面上利用这些技术实现动态更新。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值