JSP技术

1、什么是JSP

1JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术。

2JSP这门技术的最大的特点在于,写jsp就像在写html,但它相比html而言,html只能为用户提供静态数据,而Jsp技术允许在页面中嵌套java代码,为用户提供动态数据。

3Jsp快速入门:在jsp页面中输出当前时间。

2、JSP原理

1Web服务器是如何调用并执行一个jsp页面的?

答:翻译成一个Servlet

Jsp页面中的html排版标签是如何被发送到客户端的?

答:调用out.write()方法

Jsp页面中的java代码服务器是如何执行的?

答:翻译成一个Servlet,然后在里面执行Java代码

Web服务器在调用jsp时,会给jsp提供一些什么java对象?

答:九大对象

3、JSP运行原理

4、JSP语法

1JSP模版元素 

2JSP表达式 

3JSP脚本片断 

4JSP注释

5JSP指令

6JSP标签 

7JSP内置对象

8如何查找JSP页面中的错误 

5、JSP模版元素 

1JSP页面中的HTML内容称之为JSP模版元素。 

2JSP模版元素定义了网页的基本骨架,即定义了页面的结构和外观。

3直接书写在JSP中的HTML内容,看起来就像写HTML一样的方便,但是最终会在被翻译成Servlet的过程中 out.write()直接输出

6、JSP脚本表达式 

1JSP脚本表达式(expression)用于将程序数据输出到客户端

语法:<%= 变量或表达式 %>

举例:当前时间:<%= new java.util.Date() %> 

2JSP引擎在翻译脚本表达式时,会将程序数据转成字符串,然后在相应位置用out.print(将数据输给客户端。

3JSP脚本表达式中的变量或表达式后面不能有分号(;)。

7、JSP脚本片断

1JSP脚本片断(scriptlet)用于在JSP页面中编写多行Java代码。语法:

<% 

多行java代码 

%> 

2注意:JSP脚本片断中只能出现java代码,不能出现其它模板元素, JSP引擎在翻译JSP页面中,会将JSP脚本片断中的Java代码将被原封不动地放到Servlet_jspService方法中。 

3JSP脚本片断中的Java代码必须严格遵循Java语法,例如,每执行语句后面必须用分号(;)结束。

4在一个JSP页面中可以有多个脚本片断,在两个或多个脚本片断之间可以嵌入文本、HTML标记和其他JSP元素。

举例:

<%

int x = 10;

out.println(x);

%>

<p>这是JSP页面文本</p>

<%

int y = 20;

out.println(y);

%>

5多个脚本片断中的代码可以相互访问,犹如将所有的代码放在一对<%%>之中的情况。如:out.println(x);

6单个脚本片断中的Java语句可以是不完整的,但是,多个脚本片断组合后的结果必须是完整的Java语句,例如:

%

for (int i=1; i<5; i++) 

{

%>

<H1>www.it315.org</H1>

<%

}

%> 

8JSP声明 

1JSP页面中编写的所有代码,默认会翻译到servletservice方法中, 而Jsp声明中的java代码被翻译到_jspService方法的外面。语法:

<%! 

java代码

%>

2所以,JSP声明可用于定义JSP页面转换成的Servlet程序的静态代码块、成员变量和方法 。 

3多个静态代码块、变量和函数可以定义在一个JSP声明中,也可以分别单独定义在多个JSP声明中。

4JSP隐式对象的作用范围仅限于Servlet_jspService方法,所以在JSP声明中不能使用这些隐式对象。 

5<%! %>在其中可以写java代码,其中的源代码会被拷贝到servlet中的service方法之外,可以利用它来为servlet增加成员方法、成员变量、静态代码块

9、JSP声明案例 

<%!

static 

System.out.println("loading Servlet!"); 

}

private int globalVar = 0;

public void jspInit()

{

System.out.println("initializing jsp!");

}

%>

<%!

public void jspDestroy()

{

System.out.println("destroying jsp!");

}

%>

10、JSP注释 

1JSP注释的格式:

<%-- 注释信息 --%>

2JSP引擎在将JSP页面翻译成Servlet程序时,忽略JSP页面中被注释的内容。 

示例:

<hr><h1>jsp注释:在被翻译成Servlet 的过程中jsp注释消失</h1>

   <%-- 

  itheima

  --%>

  <hr><h1>java注释:在翻译过来的Servlet中有,但是是被注释的,在.java文件被编译的过程中会丢失java注释</h1>

   <%

   //out.write("it315");

   %>

  <hr><h1>HTML注释:被当作模版元素直接被输出到浏览器,浏览器看到html注释,不予显示</h1>

  <!-- itcast -->

3<%-- --%>jsp注释包围起来的内容将不会被服务器翻译到servlet之中,要注意区分html注释和java注释的区别

jsp注释不会被翻译到servlet中,会在翻译时遗弃

java注释不会被编译到class文件中,会在编译时遗弃

html注释将会当作模版元素,直接输出到浏览器中,浏览器将不会显示html注释中的内容

11、JSP指令 

JSP指令(directive)是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分。在JSP 2.0规范中共定义了三个指令:

page指令

Include指令

taglib指令

12JSP指令简介

1page指令用于定义JSP页面的各种属性,无论page指令出现在JSP页面的什么地方,它作用的都是整个JSP页面,为了保持程序的可读性和遵循良好的编程习惯,page指令最好是放在整个JSP页面的起始位置

2JSP 2.0规范中定义的page指令的完整语法:

用来通知翻译引擎,如果翻译当前的JSP

[ language="java" ] 当前JSP使用的开发语言

[ extends="package.class" ] 当前jsp翻译成servlet后要继承的类,注意此值必须是一个servlet的子类,一般情况下不要改

[ import="{package.class | package.*}, ..." ] 导入需要使用到的包 java.lang.*;javax.servlet.*;javax.servlet.jsp.*;javax.servlet.http.*;

[ session="true | false" ] 用来指定当前页面是否使用session,如果设置为true,则翻译过来的servlet中将会有对session对象的引用,于是可以直接在jsp中使用session隐式对象。但是这将导致一旦访问jsp就会调用request.getSession()方法,可能导致不必要的空间浪费。如果确定jsp中不需要session可以设为false

[ buffer="none | 8kb | sizekb" ] out隐式对象所使用的缓冲区的大小

[ autoFlush="true | false" ] out隐式对象是否自动刷新缓冲区,默认为true,不需要更改

[ isThreadSafe="true | false" ] 翻译过来的servlet是否实现SingleThreadModel(其实一点也不好用,没有太大的用处)

[ errorPage="relative_url" ] 如果页面出错,将要跳转到的页面,除了在jsp中使用此属性指定错误页面外也可以在web.xml中配置整个web应用的错误页面,如果两个都设置则jsp中的此属性起作用

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8" errorPage="/exe/error.jsp"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<title>Insert title here</title>

</head>

<body><br>

<%

   int x=1/0;

   out.print(x);

 %>

</body>

</html>

<error-page>

<exception-type>java.lang.Throwable</exception-type>

<location>/commonError.jsp</location>

</error-page>

[ isErrorPage="true | false" ] 如果设置此属性为true,翻译过来的servlet中将含有Exception隐式对象,其中封装的就是上一个页面中抛出的异常对象

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8" isErrorPage="true"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<title>Insert title here</title>

</head>

<body><br>

<%

   int x=1/0;

   System.out.println(exception.getMessage());

 %>

</body>

</html>

[ contentType="mimeType [ ;charset=characterSet ]" | "text/html ; charset=ISO-8859-1" ] jsp乱码相关的指令,用来指定jsp输出时,设置的Content-Type响应头用来指定浏览器打开的编码

[ pageEncoding="characterSet | ISO-8859-1" ] 服务器翻译jsp时使用的编码集.如果向防止jsp乱码,应该保证文件的保存编码和jsp翻译成servlet用的编码以及输出到浏览器后浏览器打开的编码一致.此属性一旦设置好,翻译引擎会间接帮我们设置content-type属性.

[ isELIgnored="true | false" ] 当前页面是否使用el表达式,设置为false时表示启用el,j2ee4.0开始默认支持,j2ee4.0一下做开发时,如果要使用el表达式,需将此属性设置为false

13、使用page指令解决JSP中文乱码

1JSP程序存在有与Servlet程序完全相同的中文乱码问题

输出响应正文时出现的中文乱码问题 

读取浏览器传递的参数信息时出现的中文乱码问题

2JSP引擎将JSP页面翻译成Servlet源文件时也可能导致中文乱码问题 

JSP引擎将JSP源文件翻译成的Servlet源文件默认采用UTF-8编码,而JSP开发人员可以采用各种字符集编码来编写JSP源文件,因此,JSP引擎将JSP源文件翻译成Servlet源文件时,需要进行字符编码转换。 

如果JSP文件中没有说明它采用的字符集编码,JSP引擎将把它当作默认的ISO8859-1字符集编码处理。

3如何解决JSP引擎翻译JSP页面时的中文乱码问题 

通过page指令的contentType属性说明JSP源文件的字符集编码

page指令的pageEncoding属性说明JSP源文件的字符集编码

14、include指令 

1include指令用于引入其它JSP页面,如果使用include指令引入了其它JSP页面,那么JSP引擎将把这两个JSP翻译成一个servlet。所以include指令引入通常也称之为静态引入。

2语法:

<%@ include file="relativeURL"%>

其中的file属性用于指定被引入文件的路径。路径以“/”开头,表示代表当前web应用。

3细节:

被引入的文件必须遵循JSP语法。

被引入的文件可以使用任意的扩展名,即使其扩展名是htmlJSP引擎也会按照处理jsp页面的方式处理它里面的内容,为了见明知意,JSP规范建议使用.jspfJSP fragments)作为静态引入文件的扩展名。 

由于使用include指令将会涉及到2JSP页面,并会把2JSP翻译成一个servlet,所以这2JSP页面的指令不能冲突(除了pageEncoding和导包除外)。 

4<%@ incluede file=""%> 静态引入其他页面的内容

*静态引入:在源文件级别进行合并,多个jsp生成一个servlet,最终由这一个servlet生成响应。推荐使用。

*动态引入:在运行时将多个输出进行合并,多个jsp分别生成多个servlet,最终由这多个servlet生成响应,组成一个输出流,提供响应。执行效

 15taglib指令

Taglib指令用于在JSP页面中导入标签库,讲自定义标签技术时讲。

<%@ taglib uri="" prefix=""%>用来引入标签库。

uri指定被引入.tld文件的名称空间

prefix 对该名称空间的一个缩写

16、JSP运行原理和九大隐式对象

1每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理。JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet) ,然后按照servlet的调用方式进行调用。

2由于JSP第一次访问时会翻译成servlet,所以第一次访问通常会比较慢,但第二次访问,JSP引擎如果发现JSP没有变化,就不再翻译,而是直接调用,所以程序的执行效率不会受到影响。

3JSP引擎在调用JSP对应的_jspServlet时,会传递或创建9个与web开发相关的对象供_jspServlet使用。JSP技术的设计者为便于开发人员在编写JSP页面时获得这些web对象的引用,特意定义了9个相应的变量,开发人员在JSP页面中通过这些变量就可以快速获得这9大对象的引用。

49个对象分别是哪些,以及作用也是笔试经常考察的知识点。

17JSP九大隐式对象

1request

2response

3config

4application

5exception

6Session

7page

8out

9pageContext

18、out隐式对象

1out隐式对象用于向客户端发送文本数据。 

2out对象是通过调用pageContext对象的getOut方法返回的,其作用和用法与ServletResponse.getWriter方法返回的PrintWriter对象非常相似。 

3JSP页面中的out隐式对象的类型为JspWriterJspWriter相当于一种带缓存功能的PrintWriter,设置JSP页面的page指令的buffer属性可以调整它的缓存大小,甚至关闭它的缓存。 

4只有向out对象中写入了内容,且满足如下任何一个条件时,out对象才去调用ServletResponse.getWriter方法,并通过该方法返回的PrintWriter对象将out对象的缓冲区中的内容真正写入到Servlet引擎提供的缓冲区中:

设置page指令的buffer属性关闭了out对象的缓存功能

out对象的缓冲区已满

整个JSP页面结束

19、out隐式对象的工作原理图

 20out隐式对象的注意事项

(1)同时使用outresponse.getwriter()输出数据。

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>

  </head>

  <body>

   <%

   response.getWriter().write("aaa");

   out.write("bbb");

   response.getWriter().write("ccc");

   out.write("ddd");

    %>

  </body>

</html>

2JSP实现文件下载。

21pageContext对象 

1pageContext对象是JSP技术中最重要的一个对象,它代表JSP页面的运行环境,这个对象不仅封装了对其它8大隐式对象的引用,它自身还是一个域对象,可以用来保存数据。并且,这个对象还封装了web开发中经常涉及到的一些常用操作,例如引入和跳转其它资源、检索其它域对象中的属性等。 

2)获取其它八大隐式对象,可以认为是一个入口对象。

22、通过pageContext获得其他对象 

1getException方法返回exception隐式对象 

getPage方法返回page隐式对象

getRequest方法返回request隐式对象 

getResponse方法返回response隐式对象 

getServletConfig方法返回config隐式对象

getServletContext方法返回application隐式对象

getSession方法返回session隐式对象 

getOut方法返回out隐式对象

pageContext封装其它8大内置对象的意义,思考:如果在编程过程中,把pageContext对象传递给一个普通java对象,那么这个java对象将具有什么功能? 

23、pageContext作为域对象 

1pageContext对象的方法 

public void setAttribute(java.lang.String name,java.lang.Object value)

public java.lang.Object getAttribute(java.lang.String name)

public void removeAttribute(java.lang.String name)

2pageContext对象中还封装了访问其它域的方法

public java.lang.Object getAttribute(java.lang.String name,int scope)

public void setAttribute(java.lang.String name, java.lang.Object value,int scope)

public void removeAttribute(java.lang.String name,int scope)

3代表各个域的常量

PageContext.APPLICATION_SCOPE

PageContext.SESSION_SCOPE

PageContext.REQUEST_SCOPE

PageContext.PAGE_SCOPE 

findAttribute方法    (*重点,查找各个域中的属性) EL表达式

findAttribute方法,在四大域中搜寻属性,搜寻的顺序是page域、request域、session域、application域,从小域到大域开始搜索,如果搜索到就直接获取该值,如果所有域中都找不到,返回一个null(el表达式不同,此处返回null,对网页是不友好的

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<title>Insert title here</title>

</head>

<body>

<%

pageContext.setAttribute("name""丁岩");

request.setAttribute("name""彭波");

session.setAttribute("name""张帆");

application.setAttribute("name""李欣");

String name=(String)pageContext.findAttribute("name");

String name2=(String)pageContext.findAttribute("name2");

out.println(name+"<br/>");

out.println(name2+"<br/>");

 %>

</body>

</html>

4作用的范围:真个jsp页面,是四大作用域中最小的一个。

5生命周期:当对jsp的请求开始时生成,当响应结束时销毁。

24引入和跳转到其他资源

1PageContext类中定义了一个forward方法和两个include方法来分别简化和替代RequestDispatcher.forward方法和include方法。

2方法接收的资源如果以“/”开头, “/”代表当前web应用。

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>

  </head>

  <body>

   <%

   //request.getRequestDispatcher("/index.jsp").forward(request,response);

   //pageContext.forward("/index.jsp");

   //request.getRequestDispatcher("/index.jsp").include(request,response);

   pageContext.include("/index.jsp");

    %>

    xxxx

  </body>

</html>

25、JSP标签

JSP标签也称之为Jsp Action(JSP动作)元素,它用于在Jsp页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护。

26、JSP常用标签

JSP标签:由sun公司提供,属于jsp规范中的内容,不需要引入第三方标签库

1<jsp:inclue>用来替代request.getRequestDispatcher().include()

2<jsp:forward>用来替代request.getRequestDispatcher().forward()

3<jsp:param>配合前两个标签使用,可以在包含或转发时,带一些参数过去

4JSP既可以用来生成HTML页面,也可以直接书写java源码处理逻辑,这就导致了很多开发者在JSP出现初期,只用JSP做开发,这个JSP页面十分庞大、充满了java源码和HTML标签、许多百分号,逻辑结构混乱,不宜调试程序和页面美化。于是人们希望将java源码从JSP页面中尽量抽离,但是把所有java源码都抽走是不现实的,最基本的获取属性、简单的页面逻辑还是需要的,于是,sun公司就提供了JSP中的标签开发技术,以一个标签代表一种功能的java代码,是整个jsp看起来更像一个HTML,并且不丢失JSP进行逻辑处理的功能。

5<jsp:useBean id="beanName" class="package.class"  scope="page|request|session|application"/>在指定域中搜寻名字为id设置值的bean,如果没有就在该域中创建一个

<jsp:setProperty name="beanName" 

property="propertyName" value="{string | <%= expression %>}" |

property="propertyName" [ param="parameterName" ] | 

property= "*" 

}/> 用于为bean的属性负值name指定bean的名字,property指定要设定的属性的名字,value指定设定的属性的值,param用来指定使用哪个请求参数设定该属性,property可以设置为*,用来将所有的请求参数自动设置懂啊bean对应的属性上

<jsp:getProperty name="beanInstanceName" property="PropertyName" />用于获取属性的值输出到输出流中,其中name指定bean的名字,property指定bean上属性的名字

27、<jsp:include>标签 

<jsp:include>标签用于把另外一个资源的输出内容插入进当前JSP页面的输出内容之中,这种在JSP页面执行时的引入方式称之为动态引入。

语法:

<jsp:include page="relativeURL | <%=expression%>" flush="true|false" />

 

page属性用于指定被引入资源的相对路径,它也可以通过执行一个表达式来获得。

flush属性指定在插入其他资源的输出内容时,是否先将当前JSP页面的已输出的内容刷新到客户端。  

28、<jsp:include>include指令的比较

1<jsp:include>标签是动态引入, <jsp:include>标签涉及到的2JSP页面会被翻译成2servlet,这2servlet的内容在执行时进行合并。 

2include指令是静态引入,涉及到的2JSP页面会被翻译成一个servlet,其内容是在源文件级别进行合并。

3不管是<jsp:include>标签,还是include指令,它们都会把两个JSP页面内容合并输出,所以这两个页面不要出现重复的HTML全局架构标签,否则输出给客户端的内容将会是一个格式混乱的HTML文档。

29、<jsp:forward>标签

<jsp:forward>标签用于把请求转发给另外一个资源。

语法:

<jsp:forward page="relativeURL | <%=expression%>" /> 

page属性用于指定请求转发到的资源的相对路径,它也可以通过执行一个表达式来获得。

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>

  </head>

  <body>

   <%

   //request.getRequestDispatcher("/index.jsp").forward(request,response);

   //pageContext.forward("/index.jsp");

   //request.getRequestDispatcher("/index.jsp").include(request,response);

   pageContext.include("/index.jsp");

    %>

    xxxx

  </body>

</html>

30、<jsp:param>标签 

当使用<jsp:include><jsp:forward>标签引入或将请求转发给其它资源时,可以使用<jsp:param>标签向这个资源传递参数。

语法1

<jsp:include page="relativeURL | <%=expression%>">

<jsp:param name="parameterName" value="parameterValue|<%= expression %>" />

</jsp:include>

语法2

<jsp:forward page="relativeURL | <%=expression%>">

<jsp:param name="parameterName" value="parameterValue|<%= expression %>" />

</jsp:include>

<jsp:param>标签的name属性用于指定参数名,value属性用于指定参数值。在<jsp:include><jsp:forward>标签中可以使用多个<jsp:param>标签来传递多个参数。

<%@ page language="java" pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<title>Insert title here</title>

</head>

<body>

<jsp:forward page="/exe/Test5.jsp">

<jsp:param value="丁岩" name="name"/>

<jsp:param value="22" name="age"/>

</jsp:forward>

</body>

</html>

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

<%

String name=request.getParameter("name");

String age=request.getParameter("age");

name=new String(name.getBytes("iso8859-1"),"Utf-8");

out.print("姓名:"+name+"<br/>年龄:"+age);

 %>

</body>

</html>

????

31、映射JSP

<servlet>

<servlet-name>SimpleJspServlet</servlet-name>

<jsp-file>/jsp/simple.jsp</jsp-file>

<load-on-startup>1</load-on-startup >

</servlet>

……

<servlet-mapping>

<servlet-name>SimpleJspServlet</servlet-name>

<url-pattern>/xxx/yyy.html</url-pattern>

</servlet-mapping>

32、如何查找JSP页面中的错误 

1JSP页面中的JSP语法格式有问题,导致其不能被翻译成Servlet源文件,JSP引擎将提示这类错误发生在JSP页面中的位置(行和列)以及相关信息。

2JSP页面中的JSP语法格式没有问题,但被翻译成的Servlet源文件中出现了Java语法问题,导致JSP页面翻译成的Servlet源文件不能通过编译,JSP引擎也将提示这类错误发生在JSP页面中的位置(行和列)以及相关信息。

3JSP页面翻译成的Servlet程序在运行时出现异常,这与普通Java程序的运行时错误完全一样,Java虚拟机将提示错误发生在Servlet源文件中的位置(行和列)以及相关信息。   

33、JSP最佳实践

1不管是JSP还是Servlet,虽然都可以用于开发动态web资源。但由于这2门技术各自的特点,在长期的软件实践中,人们逐渐把servlet作为web应用中的控制器组件来使用,而把JSP技术作为数据显示模板来使用。

2其原因为,程序的数据通常要美化后再输出:

jsp既用java代码产生动态数据,又做美化会导致页面难以维护。

servlet既产生数据,又在里面嵌套html代码美化数据,同样也会导致程序可读性差,难以维护。

因此最好的办法就是根据这两门技术的特点,让它们各自负责各的,servlet只负责响应请求产生数据,并把数据通过转发技术带给jsp,数据的显示jsp来做。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值