JSP基础

本文详细介绍了JSP的基础知识,包括jsp页面的生命周期,jsp注释,java代码块,声明语句块,内置对象,以及jsp指令和动作。重点讲解了EL表达式的使用,如获取数据、运算符和内置对象,并展示了如何创建自定义EL函数。此外,还介绍了JSTL的核心标签库,如forEach标签的使用。最后提到了javaBean的规范和系统开发模型,如MVC和三层架构。
摘要由CSDN通过智能技术生成

一、jsp基础

1、jsp简介

JSP即:Java Server pages(java 服务器页面),运行在服务端的页面,是sun公司和多家大公司共同开发的一种动态网页技术,它是在静态的html文件中插入java代码段和jsp标签形成的文件,后缀为.jsp

当用户第一次访问jsp页面的时候,会由tomcat服务器生成一个servelt文件,用户访问的页面其实就是访问的这个servlet

idea下jsp访问产生的路径C:\Users\79894.IntelliJIdea2019.3\system\tomcat_javeWeb\work\Catalina\localhost\JSP\org\apache\jsp

 

里面的内容

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/8.5.65
 * Generated at: 2021-04-30 06:43:43 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {

  private static final javax.servlet.jsp.JspFactory _jspxFactory =
          javax.servlet.jsp.JspFactory.getDefaultFactory();

  private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;

  private static final java.util.Set<java.lang.String> _jspx_imports_packages;

  private static final java.util.Set<java.lang.String> _jspx_imports_classes;

  static {
    _jspx_imports_packages = new java.util.HashSet<>();
    _jspx_imports_packages.add("javax.servlet");
    _jspx_imports_packages.add("javax.servlet.http");
    _jspx_imports_packages.add("javax.servlet.jsp");
    _jspx_imports_classes = null;
  }

  private volatile javax.el.ExpressionFactory _el_expressionfactory;
  private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;

  public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
    return _jspx_dependants;
  }

  public java.util.Set<java.lang.String> getPackageImports() {
    return _jspx_imports_packages;
  }

  public java.util.Set<java.lang.String> getClassImports() {
    return _jspx_imports_classes;
  }

  public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
    if (_el_expressionfactory == null) {
      synchronized (this) {
        if (_el_expressionfactory == null) {
          _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
        }
      }
    }
    return _el_expressionfactory;
  }

  public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
    if (_jsp_instancemanager == null) {
      synchronized (this) {
        if (_jsp_instancemanager == null) {
          _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
        }
      }
    }
    return _jsp_instancemanager;
  }

  public void _jspInit() {
  }

  public void _jspDestroy() {
  }

  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException, javax.servlet.ServletException {

    final java.lang.String _jspx_method = request.getMethod();
    if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
      return;
    }

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html;charset=UTF-8");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("\n");
      out.write("\n");
      out.write("<html>\n");
      out.write("  <head>\n");
      out.write("    <title>$Title$</title>\n");
      out.write("  </head>\n");
      out.write("  <body>\n");
      out.write("  这是一个jsp文件\n");
      out.write("  </body>\n");
      out.write("</html>\n");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

2、jsp注释

1.html注释

<!--这是html注释,html注释会显示在页面的源代码上-->

2.jsp注释

<%--这是jsp注释,jsp注释不显示在前台页面上,仅仅显示在jsp源码中--%>


例如:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  这是一个jsp文件
  <!--html注释-->
  <%--jsp注释,仅在这个文件下显示--%>
  </body>
</html>

前台页面源码:

<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>f
  这是一个jsp文件
  <!--html注释-->
  </body>
</html>

3、jsp的java代码块

语法:

<%
	System.out.println("java代码块");
%>

注意:不可以写方法,变量名前不可以加访问修饰符,因为这些代码都会被插入到jsp_service()方法中

4、jsp的声明语句块

语法:

<%=
	表达式,可以将变量写在这里,然后会在浏览器中显示
%>

这行代码会被插入到service方法中

6、jsp内置对象

在jsp的java代码块、表达式块等可以直接使用的被成为jsp内置对象,常用的内置对象有9个

 

1.pageContext

页面上下文,四大域中的一个,虽然是域,但一般不用,因为作用域只能在当前页面有效

但是可以通过它获取其他八个内置对象

2.out

out是JspWriter的子类,是一个输出流,可以将数据输出到浏览器

7、jsp指令

jsp指令作用:为当前页面提供一些基础属性设置,为当前页面的运行体提供基础的环境

一共有三种指令:page指令,include指令,taglib指令。这里暂时先描述前两种

语法:<%@ 指令名称 属性名=属性值 属性名=属性值 …%>

1、page指令

**pageEncoding:**指定当前页面编码方式,如果使用这个,那么contentType默认是text/html

contentType:可以指定text/html解析方式,与pageEncoding用一个就行

**import:**导包

<%@ page import="java.util.*"%>
<%@ page import="java.util.*,java.text.*"%>

errorPage:

页面出错后跳转到指定页面

<%@ page errorPage="error.jsp"%>

isErrorPage:

指定当前页面为错误处理页面,那么就会显示错误信息

<%@ page isErrorPage="true"%>
ex= <%= exception.getMessage()%>

**session:**一般读数据的时候设置成false,否则没有读取到的话就会创建一个新的session,占内存

session的使用原则:存:getSession(),取:getSession(false);有老的就用老的,没老的也不建新的

<%@ page session="false"%>
<%
    HttpSession session = request.getSession(false);    
    if(session!=null){
        String user = (String)session.getAttribute("user");
        out.print(user);
    }
%>

2、include指令

<%@ include file="/test.jsp"%>

这叫做静态联编:编译之前就将内容合并到了一起

作用:一个页面可以多次使用

8、jsp动作

由于大量的使用java代码块,表达式块等内容,使得页面杂乱无章

有些公司明文规定不可以使用java代码块和表达式块

推荐使用EL表达式 JSTL标签,jsp动作

语法:

<jsp:动作名称 属性=属性值 属性=属性值 ......></jsp:动作名称>
或者
<jsp:动作名称 属性=属性值 属性=属性值 ....../>

1、forword动作

不可以向标准输出流写入数据

<jsp:forward page="/next.jsp"/><%--会直接跳到next.jsp--%>

2、include动作

可以向标准输出流写入数据

<jsp:include page="/next.jsp"/><%--页面会合并起来--%>

动态联编:编译的时候会生成多个servlet,不可以共享变量

推荐使用静态联编,因为只会生成一个servlet,对资源的消耗比较小

二、EL表达式(重点)

定义:是一种获取数据的简单方式(只能从四大域获取)

语法:${exprition}

1、获取数据

1.从四大域中查找值

<%
    String user = "张三";
    pageContext.setAttribute("user",user);
    requset.setAttribute("user",user);
    session.setAttribute("user",user);
    application.setAttribute("user",user);
%>
user = ${user}

获取值的时候会从四大域由小到大查找

查找数据的顺序:pageContext,requset,session,application

2.从指定域获取值

${pageScope.value}<%--指定从pageContext获取值--%>
${requestScope.value}<%--指定从request获取值--%>
${sessionScope.value}<%--指定从session中获取值--%>
${applicationScope.value}<%--指定从application中获取值--%>

3.访问bean的属性

EL表达式如果使用为null的对象的属性,EL是不会抛出空指针异常的,其仅仅是不显示而已

<% page import="com.bean.*"%>
schoolName = ${student.school.schoolName}

4.EL访问数组

<%
    String[] names = ["test01","test02"];
    pageContext.setAttribute("names",names);
%>
names[0] = ${names[0]}
names[1] = ${names[1]}

若访问的数组下标超出了长度,EL不会抛出数组越界异常

5.EL访问List

<%
    List<String> names = new ArrayList<>();//jdk8支持这样写
    names.add("张三");
    names.add("李四");
    pageContext.setAttribute("names",names);
%>
names[0] = ${names[0]}

EL无法访问Set

6.EL访问Map

<%
    Map<String,Object> map = new HashMap<>();
    map.put("school",new School("河北科技大学","石家庄市"));
    map.put("age",21);
%>
school.name = ${map.school.sname}<%--这里会自动做一个向下转型--%>
age = ${map.age}

2、EL中的运算符


除了以上的运算符,还有一个重要的运算符 empty

用法:${empty 变量}

如果变量为空,空字符串,空的引用,空集合或者空数组,那么就返回true,否则返回false

<%
    String userName = "张三";
    Integer age = null;
    pageContext.setAttribute("userName",userName);
    pageContext.setAttribute("age",age);
  %>
  userName = ${userName}<br>
  age = ${(empty age)?"暂无数据":age}

3、EL内置对象

上面从指定域获取数据用到了四个,下面介绍一些其他常用的

1.pageContext

对于这个对象,用的最多的地方就是

<form action="${pageContext.request.contextPath}/registerServlet" method="GET">
    
</form>

${pageContext.request.contextPath} 获取当前网站路径

2.param

获取请求中的指定参数值,其底层调用的是request.getParamter()

可用于页面之间传值

姓名:${param.userName}

3.paramValues

获取多个值用paramValues ,其底层调用的是requset.getParamterValues()

爱好:${empty paramValues.hobby[0]?"":paramValues.hobby[0]}<br>
爱好:${empty paramValues.hobby[1]?"":paramValues.hobby[1]}<br>
爱好:${empty paramValues.hobby[2]?"":paramValues.hobby[2]}<br>

4.initParam

web.xml

<context-param>
    <param-name>company1</param-name>
    <param-value>aaa</param-value>
</context-param>
<context-param>
    <param-name>company2</param-name>
    <param-value>bbb</param-value>
</context-param>

获取初始化参数

${initParam.company1}
${initParam.company2}

其底层调用的是servletContext.getInitParamter()

4、自定义EL函数

注意:EL表达式不支持字符串的拼接

例子:

实现字符串小写变大写

步骤:

1.创建一个自定义的方法

package com.fjh.test01;

public class ElFunction {
    //将字符串小写变大写
    public static String lowerToUpper(String source){
        return source.toUpperCase();
    }
}

2.需要在在一个拓展名为.tld的xml文件中进行注册

tld tag library definition 标签库定义

xml文件是需要约束的,需要配置文件的头部,这个头部可以在tomcat中进行复制

在tomcat安装路径下E:\program\apache-tomcat-8.5.65\webapps\examples\WEB-INF\jsp2

<?xml version="1.0" encoding="ISO-8859-1"?>

<taglib 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-jsptaglibrary_2_1.xsd"
        version="2.1">

    <tlib-version>1.0</tlib-version>
    <short-name>my</short-name>
    <uri>http://mycompany.com</uri>

    <!-- Invoke 'Generate' action to add tags or functions -->
<!--    注册函数-->
    <function>
        <name>lowerToUpper</name>
        <function-class>com.fjh.test01.ElFunction</function-class>
        <function-signature>java.lang.String lowerToUpper(java.lang.String)</function-signature>
    </function>
</taglib>

3.使用函数

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib uri="http://mycompany.com" prefix="my"%>
<html>
  <head>
    <title>index</title>
  </head>
  <body>  
  ${my:lowerToUpper("ABC")}
  </body>
</html>

5、JSTL的EL函数库\

JSTL:jsp Standard tag library 这是Apache定义好的一套标准的标签库规范

需要引入jar包 jstl.jar和standard.jar

三、自定义标签

1.自定义标签的基本用法

步骤

1.定义一个类实现 javax.servlet.jsp.tagext.SimpleTag 这个类成为标签处理器类

package com.fjh.test02;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;

public class GetIp extends SimpleTagSupport {
    @Override
    public void doTag() throws JspException, IOException {
        //获取pageContext对象
        PageContext pc = (PageContext) this.getJspContext();
        //获取请求对象
        ServletRequest request = pc.getRequest();
        //获取客户端ip
        String ip = request.getRemoteAddr();
        pc.getOut().print(ip);
    }
}

2.注册

<?xml version="1.0" encoding="ISO-8859-1"?>

<taglib 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-jsptaglibrary_2_1.xsd"
        version="2.1">

    <tlib-version>1.0</tlib-version>
    <short-name>myTag</short-name>
    <uri>http://my.com</uri>

    <!-- Invoke 'Generate' action to add tags or functions -->
    <tag>
        <name>getIp</name>
        <tag-class>com.fjh.test02.GetIp</tag-class>
        <body-content>empty</body-content>
    </tag>
</taglib>

3.使用

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib uri="http://my.com" prefix="myTag"%>
<html>
  <head>
    <title>index</title>
  </head>
  <body>
  <myTag:getIp/>
  </body>
</html>

2.带标签体的标签

步骤

1定义标签处理器

public class TagTest01 extends SimpleTagSupport {
    @Override
    public void doTag() throws JspException, IOException {
        //StringWriter可以获取流中的内容
        StringWriter sw = new StringWriter();
        //获取标签体内容
        JspFragment jspBody = this.getJspBody();
        //获取标准输出流
        JspWriter out = this.getJspContext().getOut();
        //将标签体内容写入到流中
        jspBody.invoke(sw);
        //获取流中的内容
        String content = sw.toString().toUpperCase();
        //将内容用标准输出流显示在页面上
        out.print(content);
    }
}

2注册标签

<tag>
        <name>show</name>
        <tag-class>com.fjh.test02.TagTest01</tag-class>
        <!--
         empty:表示当前没有标签体
         scriptless:表示有标签体,但是该标签体不会出现java代码块,jsp表达式,但是可以出现EL表达式
         jsp:已经弃用,具有标签体,会将标签体内容原样显示在浏览器
         tagdependent:表示当前标签具有标签体,将标签内容原样显示在浏览器中,但是不会对EL表达式进行计算
         -->
        <body-content>scriptless</body-content>
    </tag>

3使用标签

<%
    pageContext.setAttribute("content","zhangsan");
  %>
  <myTag:show>${content}</myTag:show>

3.带属性的标签

1.定义标签处理器类

public class TagTest02 extends SimpleTagSupport {
    private boolean test;

    public void setTest(boolean test) {
        this.test = test;
    }

    @Override
    public void doTag() throws JspException, IOException {
        if (test) {
//            //获取标签体
//            JspFragment jf = this.getJspBody();
//            //将标签体写入到标准输出流
//            jf.invoke(this.getJspContext().getOut());

        this.getJspBody().invoke(null);
        //这一句等价于上面,参数为空的时候自动会有一个标准的输出流
        }
    }
}

2.注册

<!--    带属性的标签-->
    <tag>
        <name>if</name>
        <tag-class>com.fjh.test02.TagTest02</tag-class>
        <body-content>tagdependent</body-content>
        <attribute>
            <name>test</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
            <!--
                runtime expression value
                若为true 则属性支持EL和jsp表达式
            -->
        </attribute>
    </tag>

3.使用

<%
    pageContext.setAttribute("gender",true);
  %>
  <myTag:if test="${gender}">男</myTag:if>
  <myTag:if test="${not gender}">女</myTag:if>

4.自定义标签遍历所有类型的集合和数组

1.标签处理器

package com.fjh.test02;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.*;

public class ForEach extends SimpleTagSupport {
    private Object items;
    private String var;

    public void setItems(Object items) {
        this.items = items;
    }

    public void setVar(String var) {
        this.var = var;
    }
    //可以处理任何集合或者数组
    public Collection getColl(){
        if(items instanceof List){
            return (List)items;
        }else if(items instanceof Set){
            return (Set)items;
        }else if(items instanceof Map){
            return ((Map) items).entrySet();
        }else if(items.getClass().isArray()){
            List nums = new ArrayList();
            for(int i = 0;i< Array.getLength(items);i++){
                    nums.add(Array.get(items,i));
            }
            return nums;
        }
        return null;
    }

    @Override
    public void doTag() throws JspException, IOException {
        for(Object obj:getColl()){
            this.getJspContext().setAttribute(var,obj);
            this.getJspBody().invoke(null);
        }
    }
}

2.注册

<tag>
        <name>forEach</name>
        <tag-class>com.fjh.test02.ForEach</tag-class>
        <body-content>scriptless</body-content>
        <attribute>
            <name>items</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>var</name>
            <required>true</required>
            <rtexprvalue>false</rtexprvalue>
        </attribute>
    </tag>

3.使用

----------遍历List------------
  <br>
  <%
    List users = new ArrayList();
    users.add("张三");
    users.add("李四");
    users.add("王五");
    pageContext.setAttribute("users",users);
  %>
  <myTag:forEach items="${users}" var="user">
    ${user}<br>
  </myTag:forEach>

  ----------遍历Set------------
  <br>
  <%
    Set set = new HashSet();
    set.add("张三");
    set.add("李四");
    set.add("王五");
    pageContext.setAttribute("set",set);
  %>
  <myTag:forEach items="${set}" var="s">
    ${s}<br>
  </myTag:forEach>
  ----------遍历Map------------
  <br>
  <%
    Map map = new HashMap();
    map.put("name","123");
    map.put("age",12);
    pageContext.setAttribute("map",map);
  %>
  <myTag:forEach items="${map}" var="m">
    ${m}<br>
  </myTag:forEach>
  ----------遍历数组------------
  <br>
  <%
    int[] age = {12,13,14};
    pageContext.setAttribute("age",age);
  %>
  <myTag:forEach items="${age}" var="a">
    ${a}<br>
  </myTag:forEach>

4.结果

----------遍历List------------
张三
李四
王五
----------遍历Set------------
李四
张三
王五
----------遍历Map------------
name=123
age=12
----------遍历数组------------
12
13
14

四、JSTL核心标签库

1.五大标签库

核心标签库:完成基本的逻辑运算,重点

格式化标签库:主要用于日期和数字的格式化

EL函数标签库:定义了若干EL函数

SQL函数标签库:完成SQL操作,不使用了,现在使用java代码完成

XML操作标签库:完成XML操作,不使用了,现在使用java代码完成

最近时间比较紧,而且jsp编程用的不是很多了,所以后面的就省略了

放个链接,可以看看

click这儿

五、javaBean

分类

广义javaBean

​ 数据承载bean

​ 业务处理bean

狭义javaBean

​ 狭义的javaBean是指符合sun公司提出的javaBean规范的java类,javaBean规范规定,满足以下四点的java类称为javaBean

1.该类需要时公共的

2.该类需要实现Serilizable接口

3.该类需要具备无参构造器

4.该类有成员变量,这些成员变量必须是私有的,且需要提供这些属性的setter和getter方法

在实际项目中,实体类一般会被定义为狭义的javaBean,即广义的javaBean的数据承载Bean一般会被定义为满足JavaBean规范的狭义javaBean

六、系统开发模型

1.纯JSP开发

2.JSP+JavaBean的Model1

3.MVC的Model2

 

MVC,即mode模型,View视图,Controller控制器

View:视图,为用户提供界面,与用户进行交互.

Model:模型,承载数据,并对用户提交的请求进行计算的模块,其分为两类,一类称为数据承载Bean,一类称为业务处理Bean.所谓的数据承载Bean是指实体类,专门用于承载业务数据的,而业务处理Bean则书指Serbice或者Dao对象,专门用于处理用户提交的请求的.

Controller:控制器,用户将用户请求转发给相应的Model处理,指Servlet

4.三层架构

 

三层架构是指:视图层View,服务层Service,持久层Dao,它们分别完成不同的功能

View层:表现层,视图层,对于Web开发,也称为Web层,用于接收用户提交的代码

Service层:服务层,逻辑层,系统的业务逻辑主要在这里完成

Dao层,持久层,数据访问层,直接操作数据库的代码在这里编写DAO即Data Access Object,数据访问对象

为了更好的降低各层之间的耦合度,在三层架构的设计中,采用面向抽象编程,即上层对下层调用是通过接口实现的,而下层对上层是真正的服务提供者,是下层接口的实现类.

5.MVC+三层架构

 注意:MVC和三层架构是不同的不要混淆

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

mizui_i

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

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

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

打赏作者

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

抵扣说明:

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

余额充值