创建REST服务,消费REST服务(含JS和JQ调用REST端点示例)

目录

一、使用spring提供REST API

1. 项目准备

2. 生成数据库用户表实体

3. 使用Spring MVC的控制器创建RESTful端点

二、Spring 消费REST服务 API

1. 项目准备

2. 创建消费端用户领域类

3. 使用RestTemplate消费REST API

三. 使用原生 javascript 和 jquery js库消费REST API

1. 使用原生 js 消费REST API

2. 使用jquery js库消费REST API

总结


一、使用spring提供REST API

1. 项目准备

  • 创建springboot项目
  • 引入spring web、spring data-jpa等起步依赖
  • 配置web端口、数据库连接

2. 生成数据库用户表实体

package readinglist.entity;

import javax.persistence.*;
import java.util.Date;

@Entity
@Table(name = "ATBL_USER_LV", schema = "PRODUCTION", catalog = "")
public class AtblUserLv {
    private long id;
    private String password;
    private String username;
    private Date addtime;

    @SequenceGenerator(name = "generator", sequenceName = "SEQ_A_TBL", allocationSize = 1)
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "generator")
    @Column(name = "ID", unique = true, nullable = false, scale = 0)
    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    @Basic
    @Column(name = "PASSWORD")
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Basic
    @Column(name = "USERNAME")
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @Basic
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "ADDTIME")
    public Date getAddtime() {
        return addtime;
    }

    public void setAddtime(Date addtime) {
        this.addtime = addtime;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        AtblUserLv that = (AtblUserLv) o;

        if (id != that.id) return false;
        if (password != null ? !password.equals(that.password) : that.password != null) return false;
        if (username != null ? !username.equals(that.username) : that.username != null) return false;
        if (addtime != null ? !addtime.equals(that.addtime) : that.addtime != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = (int) (id ^ (id >>> 32));
        result = 31 * result + (password != null ? password.hashCode() : 0);
        result = 31 * result + (username != null ? username.hashCode() : 0);
        result = 31 * result + (addtime != null ? addtime.hashCode() : 0);
        return result;
    }
}

3. 使用Spring MVC的控制器创建RESTful端点

创建RESTful控制器需要使用@RestController注解,此注解会告诉Spring,控制器中的所有处理器方法的返回值都要直接写入响应体中,而不是将值放到模型中并传递给一个视图以便于进行渲染。

package readinglist.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import readinglist.entity.AtblUserLv;
import readinglist.repository.UserRepository;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * Rest端点定义类
 * 2022年5月6日11:41:44
 */
@RestController //注解为REST控制器类
@CrossOrigin(origins = "*") //允许跨域请求
@RequestMapping(path = "/jsondata")
public class JsonRestController {

    @Autowired  //自动装备DB数据层类
    private UserRepository userRepository;

    @GetMapping("/getjData")
    public String getjData(){
        String jsonStr = "{\"id\": 2, \"title\": \"json title标题\", \"concf\": {\"width\": 34,\"height\": 35}, \"arrlist\": [\"JAVA\", \"JavaScript\", \"PHP\"]}";
        //String jsonStr = "{\"id\": 2, \"title\": \"json title标题\", \"arrlist\": [\"JAVA\", \"JavaScript\", \"PHP\"]}";
        //String jsonStr="{\"aaname\": \"兮动人\",\"aaid\":22,\"sex\": \"男\",\"xueli\": \"本科\"}";
        return jsonStr;
    }

    /**
     * 获得用户列表
     * @return
     */
    @GetMapping("/getuserlist")
    public List<AtblUserLv> getusers(){
        System.out.println("进入getuserlist请求...");
        PageRequest page=PageRequest.of(0,2, Sort.by("addtime").descending());
        return userRepository.findAll(page).getContent();
    }

    /**
     * 根据ID查询用户信息
     * {id}这个表示占位符,传入一个id值:http://localhost:8080/jsondata/getuser/1
     * @PathVariable("id")这个注解中的id接收{id}的值,赋值给Long id参数
     * @param id
     * @return
     */
    @GetMapping("/getuser/{id}")
    public AtblUserLv userById(@PathVariable("id") Long id){
        System.out.println("id===="+id);
        Optional<AtblUserLv> optUser=userRepository.findById(id);
        if(optUser.isPresent()){
            return optUser.get();
        }
        return null;
    }

    /**
     * 根据ID查询用户信息,使用ResponseEntity对象
     * 如果查到用户,则返回ResponseEntity<AtblUserLv>对象,且HTTP状态为0K
     * 如果查不到用户,则ResponseEntity放入null,且HTTP状态返回NOT_FOUND(404)
     * @param id
     * @return
     */
    @GetMapping("/findUser/{id}")
    public ResponseEntity<AtblUserLv> userByIdEntity(@PathVariable("id") Long id){
        System.out.println("userByIdEntity--id:"+id);
        Optional<AtblUserLv> optUser=userRepository.findById(id);
        if(optUser.isPresent()){
            return new ResponseEntity<>(optUser.get(), HttpStatus.OK);
        }
        return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
    }

    /**
     * 添加新用户到数据库
     * @param atbluserlv
     * @param request
     * @return
     */
    @PostMapping(path = "/addpostusr")
    @ResponseStatus(HttpStatus.CREATED)
    public AtblUserLv postAddUser(@RequestBody AtblUserLv atbluserlv,HttpServletRequest request) {
        System.out.println("进入方法:postAddUser---request.getMethod():"+request.getMethod());
        System.out.println("request.getQueryString():"+request.getQueryString());
        System.out.println("request.getRequestURI():"+request.getRequestURI());
        System.out.println("===---------"+atbluserlv.getUsername()+atbluserlv.getPassword());
        atbluserlv.setAddtime(new Date());
        return userRepository.save(atbluserlv);
    }
}

二、Spring 消费REST服务 API

1. 项目准备

  • 创建消费端springboot项目
  • 引入spring web等起步依赖

2. 创建消费端用户领域类

package com.sbootwo.resttemplate.entity;

import java.util.Date;

public class AtblUserLv {
    private long id;
    private String password;
    private String username;
    private Date addtime;


    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Date getAddtime() {
        return addtime;
    }

    public void setAddtime(Date addtime) {
        this.addtime = addtime;
    }

}

3. 使用RestTemplate消费REST API

Spring 应用可以采用多种方式来消费 REST API,包括以下几种方式。

  • RestTemplate:Spring 核心框架提供的简单、同步 REST 客户端。
  • Traverson:Spring HATEOAS 提供的支持超链接、同步的 REST 客户端,其灵感来源于同名的 JavaScript 库。
  • WebClient:Spring 5 所引用的反应式、异步 REST 客户端。

本节主要讲解使用 RestTemplate 消费 REST 端点,创建 Rest 端点 API 消费类

package com.sbootwo.resttemplate;

import com.sbootwo.resttemplate.entity.AtblUserLv;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;

/**
 * Rest端点API消费类
 * 2022年5月6日11:40:37
 */
public class RestConsume {
    /**
     * 用户RestTemplate消费REST端点。
     * 实例化一个RestTemplate对象调用方法 也可以 声明成一个bean注入需要的地方
     */
    RestTemplate rest=new RestTemplate();

    /**
     * 消费服务端REST端点,获取单个用户信息
     * @param id 传递给getForObject方法中的id,并填充到URL中的{id}占位符
     * @return
     */
    public AtblUserLv getIdUserOne(String id){
        return rest.getForObject("http://localhost:8080/jsondata/getuser/{id}",AtblUserLv.class,id);
    }

    /**
     * 消费服务端REST端点,获取单个用户信息
     * URI对象通过String规范定义的
     * @param uid 参数传入Map中,Map中的健id填充到URI中的{id}占位符,且Map中的健名称和id}占位符取名一致
     * @return
     */
    public AtblUserLv getIdUserTwo(String uid){
        Map<String,String> mapurl=new HashMap<>();
        mapurl.put("id",uid);
        URI url= UriComponentsBuilder.fromHttpUrl("http://localhost:8080/jsondata/getuser/{id}").build(mapurl);
        return rest.getForObject(url,AtblUserLv.class);
    }

    /**
     * 消费服务端REST端点,获取单个用户信息
     * getForEntity()方法和getForObject()方法不同的是,getForEntity()返回的并不是代表响应载荷的领域对象,
     * 而是一个包裹领域对象的ResponseEntity对象。ResponseEntity对象能够访问很多的响应细节,比如响应头信息
     * @param uid 传递给getForEntity方法中的uid,并填充到URL中的{id}占位符
     * @return
     */
    public AtblUserLv getIdUserThree(String uid){
        ResponseEntity<AtblUserLv> responseEntity= rest.getForEntity("http://localhost:8080/jsondata/getuser/{id}",AtblUserLv.class,uid);
        System.out.println("获得响应头信息:"+responseEntity.getHeaders().getDate());
        return responseEntity.getBody();
    }

    /**
     * 消费服务端REST端点,添加一个新用户信息
     * @param atblUserLv 将atblUserLv领域类绑定到AtblUserLv.class上
     * @return
     */
    public AtblUserLv addAtblUserLvOne(AtblUserLv atblUserLv){
        return rest.postForObject("http://localhost:8080/jsondata/addpostusr",atblUserLv,AtblUserLv.class);
    }

    /**
     * 费服务端REST端点,添加一个新用户信息
     * postForEntity()方法可以同时获得需要的地址和响应载体
     * @param atblUserLv 将atblUserLv领域类绑定到AtblUserLv.class上
     * @return
     */
    public AtblUserLv addAtblUserLvTwo(AtblUserLv atblUserLv){
        ResponseEntity<AtblUserLv> responseEntity=rest.postForEntity("http://localhost:8080/jsondata/addpostusr",atblUserLv,AtblUserLv.class);
        System.out.println("获得响应头信息:"+responseEntity.getHeaders().getDate()+"--"+responseEntity.getHeaders().getLocation());
        return responseEntity.getBody();
    }

    public static void main(String[] args) {
        RestConsume restConsume=new RestConsume();

        //-------------GET资源获取信用户信息-------------
        AtblUserLv tuserone=restConsume.getIdUserOne("8");
        System.out.println("----"+tuserone.getId()+"||"+tuserone.getUsername()+"||"+tuserone.getPassword()+"||"+tuserone.getAddtime());

        AtblUserLv tusertwo=restConsume.getIdUserTwo("7");
        System.out.println("=========="+tusertwo.getId()+"||"+tusertwo.getUsername()+"||"+tusertwo.getPassword()+"||"+tusertwo.getAddtime());

        AtblUserLv tuserThree=restConsume.getIdUserThree("9");
        System.out.println("====---===---"+tuserThree.getId()+"||"+tuserThree.getUsername()+"||"+tuserThree.getPassword()+"||"+tuserThree.getAddtime());

        //-------------POST资源添加新用户-------------
        AtblUserLv userObj=new AtblUserLv();
        userObj.setUsername("nuser4");
        userObj.setPassword("new123");
        AtblUserLv newUserOne=restConsume.addAtblUserLvOne(userObj);
        System.out.println("打印出新增用户的ID值:"+newUserOne.getId());

        AtblUserLv userObj2=new AtblUserLv();
        userObj2.setUsername("nuser5");
        userObj2.setPassword("new123");
        AtblUserLv newUserTwo=restConsume.addAtblUserLvTwo(userObj2);
        System.out.println("打印出新增用户的ID值:"+newUserTwo.getId());
    }
}

三. 使用原生 javascript 和 jquery js库消费REST API

1. 使用原生 js 消费REST API

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <script type="text/javascript">
    //使用原生javaScript请求服务端获取数据,查询数据库用户信息。2022年5月6日11:51:57

    // 在这里使用 javaScript 语言发起 Ajax 请求,访问服务器 AjaxServlet 中 javaScriptAjax
    function ajaxRequest() {
      // 1 、我们首先要创建 XMLHttpRequest
      var xmlhttprequest = new XMLHttpRequest();
      // 2 、调用 open 方法设置请求参数
      xmlhttprequest.open("GET","http://localhost:8080/jsondata/getjData",true)
      // 4 、在 send 方法前绑定 onreadystatechange 事件,处理请求完成后的操作。
      xmlhttprequest.onreadystatechange = function(){
        if (xmlhttprequest.readyState == 4 && xmlhttprequest.status == 200) {
          console.log("-----"+xmlhttprequest.responseText.length);
          var jsonObj = JSON.parse(xmlhttprequest.responseText);
            //var objeval = eval("("+xmlhttprequest.responseText+")");
          console.log(jsonObj);
          var htmlStr = "";
          htmlStr+="<table border=\"1\" width=\"50%\" cellSpacing=\"0\" cellPadding=\"0\">";
            htmlStr+="<tr>";
            htmlStr+="<td>ID</td>";
            htmlStr+="<td>标题</td>";
            htmlStr+="<td>宽</td>";
            htmlStr+="<td>高</td>";
            htmlStr+="<td>列表</td>";
            htmlStr+="</tr>";
          htmlStr+="<tr>";
          htmlStr+="<td>"+jsonObj.id +"</td>";
          htmlStr+="<td>"+jsonObj.title+"</td>";
          htmlStr+="<td>"+jsonObj.concf.width+"</td>";
          htmlStr+="<td>"+jsonObj.concf.height+"</td>";
          htmlStr+="<td>"+jsonObj.arrlist+"</td>";
          htmlStr+="</tr>";
          htmlStr+="</table>";
          document.getElementById("div01").innerHTML=htmlStr;
          // 把响应的数据显示在页面上
          // document.getElementById("div01").innerHTML = " 编号:" + jsonObj.id + " , 姓名:" + jsonObj.name;
        }
      }
      // 3 、调用 send 方法发送请求
      xmlhttprequest.send();
    }



    //从数据库获取用户列表数据
    function ajaxReqbtnTwo() {
        // 1 、我们首先要创建 XMLHttpRequest
        var xmlhttprequest = new XMLHttpRequest();
        // 2 、调用 open 方法设置请求参数
        xmlhttprequest.open("GET","http://localhost:8080/jsondata/getuserlist",true) //获得用户列表
        // 4 、在 send 方法前绑定 onreadystatechange 事件,处理请求完成后的操作。
        xmlhttprequest.onreadystatechange = function(){
            console.log("status:"+xmlhttprequest.status+xmlhttprequest.responseText);
            if (xmlhttprequest.readyState == 4 && xmlhttprequest.status == 200) {
                var jsonObj = JSON.parse(xmlhttprequest.responseText.toString());
                //var objeval = eval("("+xmlhttprequest.responseText+")");
                //var arrayobj=xmlhttprequest.responseText;
                console.log("-----"+jsonObj.length);
                console.log(jsonObj);
                var htmlStr = "";
                htmlStr+="<table border=\"1\" width=\"50%\" cellSpacing=\"0\" cellPadding=\"0\">";
                htmlStr+="<tr>";
                htmlStr+="<td>ID</td>";
                htmlStr+="<td>用户名</td>";
                htmlStr+="<td>密码</td>";
                htmlStr+="<td>添加时间</td>";
                htmlStr+="</tr>";
                for(var i = 0;i < jsonObj.length;i++) {
                    console.log(jsonObj[i]);
                    var userobj=jsonObj[i];
                    htmlStr+="<tr>";
                    htmlStr+="<td>"+userobj.id +"</td>";
                    htmlStr+="<td>"+userobj.username+"</td>";
                    htmlStr+="<td>"+userobj.password+"</td>";
                    htmlStr+="<td>"+formatTime(userobj.addtime)+"</td>";
                    htmlStr+="</tr>";
                }
                htmlStr+="</table>";
                document.getElementById("div01").innerHTML=htmlStr;
                // 把响应的数据显示在页面上
                // document.getElementById("div01").innerHTML = " 编号:" + jsonObj.id + " , 姓名:" + jsonObj.name;
            }
        }
        // 3 、调用 send 方法发送请求
        xmlhttprequest.send();
    }


    //从数据库获取单个用户数据
    function ajaxReqbtnThree() {

        // 1 、我们首先要创建 XMLHttpRequest
        var xmlhttprequest = new XMLHttpRequest();
        // 2 、调用 open 方法设置请求参数
        xmlhttprequest.open("GET","http://localhost:8080/jsondata/getuser/3",true) //根据ID查询
        //xmlhttprequest.open("GET","http://localhost:8080/jsondata/findUser/8",true) //根据ID查询,返回ResponseEntity<AtblUserLv>对象
        // 4 、在 send 方法前绑定 onreadystatechange 事件,处理请求完成后的操作。
        xmlhttprequest.onreadystatechange = function(){
            console.log("status:"+xmlhttprequest.status+xmlhttprequest.responseText);
            if (xmlhttprequest.readyState == 4 && xmlhttprequest.status == 200) {
                var jsonObj = JSON.parse(xmlhttprequest.responseText.toString());
                //var objeval = eval("("+xmlhttprequest.responseText+")");
                //var arrayobj=xmlhttprequest.responseText;
                console.log(jsonObj);
                var htmlStr = "";
                htmlStr+="<table border=\"1\" width=\"50%\" cellSpacing=\"0\" cellPadding=\"0\">";
                htmlStr+="<tr>";
                htmlStr+="<td>ID</td>";
                htmlStr+="<td>用户名</td>";
                htmlStr+="<td>密码</td>";
                htmlStr+="<td>添加时间</td>";
                htmlStr+="</tr>";

                    htmlStr+="<tr>";
                    htmlStr+="<td>"+jsonObj.id +"</td>";
                    htmlStr+="<td>"+jsonObj.username+"</td>";
                    htmlStr+="<td>"+jsonObj.password+"</td>";
                    htmlStr+="<td>"+formatTime(jsonObj.addtime)+"</td>";
                    htmlStr+="</tr>";

                htmlStr+="</table>";
                document.getElementById("div01").innerHTML=htmlStr;
                // 把响应的数据显示在页面上
                // document.getElementById("div01").innerHTML = " 编号:" + jsonObj.id + " , 姓名:" + jsonObj.name;
            }else{
                document.getElementById("div01").innerHTML=xmlhttprequest.readyState+"------"+xmlhttprequest.status;
            }
        }
        // 3 、调用 send 方法发送请求
        xmlhttprequest.send();
    }

    //格式化时间
    function formatTime(time) {
        let date = new Date(time).toJSON()
        return new Date(+new Date(date) + 8 * 3600 * 1000)
            .toISOString()
            .replace(/T/g, ' ')
            .replace(/\.[\d]{3}Z/, '')
    }
  </script>
</head>
<body>
<button id="btnone" onclick="ajaxRequest()">查询数据one</button>
<button id="bentwo" onclick="ajaxReqbtnTwo()">查询用户列表</button>
<button id="benthree" onclick="ajaxReqbtnThree()">根据ID查询单个用户</button>
<hr>
<div id="div01">
</div>
</body>
</html>

2. 使用jquery js库消费REST API

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="../static/jq/jquery-3.6.0.js"></script>
  <script>
    //入口函数放在html页面head部分必须加。
    // 防止文档在完全加载(就绪)之前运行 jQuery 代码,即在 DOM 加载完成后才可以对 DOM 进行操作。
    // 如果在文档没有完全加载之前就运行函数,操作可能失败。
    // jQuery 入口函数:
    // $(document).ready(function(){
    //   // jQuery执行代码
    // });
    // 或者
    // $(function(){
    //   // jQuery执行代码
    // });
    //
    // JavaScript 入口函数:
    // window.onload = function () {
    // // js 执行代码
    // }

    //使用jquery查询,添加用户信息,2022年5月6日11:48:08

    $(function(){

      //从数据库获取单个用户信息
      $("#ajaxBtn").click(function(){

        $.ajax({
          url:"http://localhost:8080/jsondata/getuser/8",
          //data:"",
          //data:{action:"jQueryAjax"},
          type:"GET",
          success:function (data) {
            alert(" 服务器返回的数据是: " + data);
            // var jsonObj = JSON.parse(data);
            $("#div01").html(" 编号:" + data.id + " , 姓名:" + data.username);
          },
          dataType : "json"
        });


        // $.getJSON("http://localhost:8080/jsondata/getjData", function(data) {
        //   alert(" 服务器返回的数据是: " + data.arrlist);
        // });

        // $.get("http://localhost:8080/jsondata/getuser/8",function(data,status){
        //   alert("数据: " + data.username + "\n状态: " + status);
        //   $("#div01").html(" 编号:" + data.id + " , 姓名:" + data.username);
        // },"json"); //get方法加上第三个参数数据类型json时,data返回的就是一个json对象。不加时返回的是一个json格式的字符串

        });

      //获得json格式对象
      function GetJsonData() {
        var json = {
          "username": $("#username").val(),
          "password": $("#pwd").val()
        };
        return json;
      }

      //提交新用户信息,保存到数据库
      $("#ajaxsubmit").click(function(){

        $.ajax({
          url:"http://localhost:8080/jsondata/addpostusr",
          contentType: "application/json",
          data:JSON.stringify(GetJsonData()),
          type:"post",
          success:function (data) {
            alert(" 服务器返回的数据是: " + data);
          },
          dataType : "json"
        });

      });



    });
  </script>
</head>
<body>
<button id="ajaxBtn">ajaxBtn jquery查询用户数据</button>
<hr>
<div id="div01">
</div>
<br>
<br>

<button id="ajaxBtn22">获取数据getjData</button>
<hr>
<div id="div02">
</div>
<br>
<br>

<b>添加用户</b>
<br>
<br>
用户名:<input type="text" name="uname" id="username" style="width: 150px;">
<br>
<br>
密&nbsp;&nbsp;&nbsp;&nbsp;码:<input type="password" name="upwd" id="pwd" style="width: 150px;">
<br>
<br>
<button id="ajaxsubmit">jquery提交 添加用户</button>
<hr>

<script type="text/javascript">
    $("#ajaxBtn22").click(function(){
      $.ajax({
        url:"http://localhost:8080/jsondata/getjData",
        // data:"action=jQueryAjax",
        //data:{action:"jQueryAjax"},
        type:"GET",
        success:function (data) {
          alert(" 服务器返回的数据是: " + data);
          // var jsonObj = JSON.parse(data);
          $("#div02").html(" 编号:" + data.id + " , 姓名:" + data.title);
        },
        dataType : "json"
      });
    });

</script>
</body>
</html>

总结

创建RESTful控制器需要使用@RestController注解,此注解会告诉Spring,控制器中的所有处理器方法的返回值都要直接写入响应体中,而不是将值放到模型中并传递给一个视图以便于进行渲染。@RestController注解相当于@ResponseBody + @Controller合在一起的作用,方法返回字符串值。

@Controller 这个注解可返回显示视图页面,将值放到模型中并传递给一个视图以便于进行渲染。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值