Json解析之Gson的使用

1.实现原理

        基于事件驱动

2.JsonElement

          抽象类,代表json中的某一个元素(jsonObject/jsonArray/null/基本类型)

3.Json解析流程

解析流程

4.Gson反射解析流程

在这里插入图片描述

5.解析流程

  • 根据所需要的数据建立一个对应json数据的java bean类 ,即可通过简单的操作解析出需要的数据

6.Gson的使用

通过new Gson() 来创建对象

          static  class  GsonBean{
                  public int age;

                  public String name;

           }


 			public static void main(String[] args) {
  			  //创建gson对象
  			  Gson gson=new Gson();
		     //将数据转换为json字符串
		      System.out.println(gson.toJson(1));

 		      System.out.println(gson.toJson("zeo"));

 		      int[] values={1,2,3};
   		System.out.println( gson.toJson(values));

              int  i=gson.fromJson("1",Integer.class);
              System.out.println("i:"+i);


	        //将java bean 转换为json字符串
	        GsonBean bean=new GsonBean();
	        bean.name="java";
	        bean.age=20;
	        String  json=  gson.toJson(bean);
	        System.out.println(json);
	        //将 json字符串转换为java bean
	        GsonBean bean1=gson.fromJson(json,GsonBean.class);
	        System.out.println("bean1:"+bean1);

        }
        
        
        
        
        //打印信息  我们可以看到gson可以将任意类型的数据转换为json字符串
			1
			"zeo"
			[1,2,3]
			i:1
			{"age":20,"name":"java"}
			bean1:com.example.gson.GsonExample$GsonBean@14514713

说明

  • 1.Gson可以将任意的数据转换为json字符串
  • 2.toJson()用于将Java Object转换为json字符串
  • 3.fromJson()用于将json字符串转换为Java Object

通过构建者模式创建对象

	    static class  Foo{
	
	        private String s;
	
	        private int     i;
	
	        public Foo() {
	            this(null,5);
	        }
	
	        public Foo(String s, int i) {
	            this.s = s;
	            this.i = i;
	        }
	    }
	
	    public static void main(String[] args) {
	
	        System.out.println("传统解析方式如下");

	        Gson gson = new GsonBuilder()
	                .setPrettyPrinting()//设置以json的格式输出字符串,默认就是输出一个json字符串
	                .serializeNulls()//对空字段的数据进行序列化 默认对空数据字段是省略的
	                .create();
	
	        Foo foo=new Foo();
	        String  json= gson.toJson(foo);
	        System.out.println(json);
	
	        System.out.println("自定义解析器如下");
	        Gson gson2 = new GsonBuilder().registerTypeAdapter(Foo.class, new TypeAdapter<Foo>() {
	            @Override
	            public void write(JsonWriter out, Foo value) throws IOException {
	               out.beginObject();
	               out.name("s").value(value.s);
	               out.name("i").value(value.i+1);
	               out.endObject();
	            }
	
	            @Override
	            public Foo read(JsonReader in) throws IOException {
	                Foo foo1=new Foo();
	                in.beginObject();
	                while (in.hasNext()){
	                    switch (in.nextName()){
	                        case "s":
	                            foo1.s=in.nextString();
	                            break;
	                        case  "i":
	                            foo1.i=in.nextInt();
	                            break;
	
	                    }
	
	                }
	                in.endObject();;
	                return foo1;
	            }
	        }.nullSafe()).setPrettyPrinting().serializeNulls().create();
	        Foo foo1=new Foo();
	        String json1= gson2.toJson(foo1);
	        System.out.println(json1);
      }    

      //打印日志
      传统解析方式如下
	{
	  "s": null,
	  "i": 5
	}
	自定义解析器如下
	{
	  "s": null,
	  "i": 6
	}

说明

  • 1.通过GsonBuilder().create()创建gson对象
  • 2.setPrettyPrinting() 调用该方法后,打印json字符串将使用一种漂亮的方式,默认就是一行json字符串
  • 3.serializeNulls() 默认gson不对空数据字段进行序列化,设置该方法后,对空数据字段也会进行序列化
  • 4.registerTypeAdapter 自定义一个解析器,可以对数据进行写入和读取,并在这个过程中可以进行一些额外的操作
  • 5.nullSafe() 调用该方法之后gson会对字段数据进行空检查,外部无序进行空检查
  • 6.JsonWriter/JsonReader就是输出/输入流,用于写入和读取数据

Gson注解使用之SerializeName

       static  class  SerializedNameBean {
        @SerializedName("name")
        public String a;

        @SerializedName(value = "name1")
        public String b;

        public String c;

        public SerializedNameBean(String a, String b, String c) {
            this.a = a;
            this.b = b;
            this.c = c;
        }

        @Override
        public String toString() {
            return "SerializedNameBean{" +
                    "a='" + a + '\'' +
                    ", b='" + b + '\'' +
                    ", c='" + c + '\'' +
                    '}';
        }
    }
	  public static void main(String[] args) {
	        System.out.println("gson注解之SerializedName");
	        SerializedNameBean data=new SerializedNameBean("v1","v2","v3");
	        Gson gson=new GsonBuilder()
	                .setPrettyPrinting()
	                .create();
	        String json= gson.toJson(data);
	        System.out.println(json);
	
	
	        SerializedNameBean data1=gson.fromJson(json,SerializedNameBean.class);
	        System.out.println(data1.a);
	        System.out.println(data1.b);
	        System.out.println(data1.c);
	        System.out.println(data1.toString());
	        }
    
    

        //打印信息
       {
		  "name": "v1",
		  "name1": "v2",
		  "c": "v3"
		}
		v1
		v2
		v3
		SerializedNameBean{a='v1', b='v2', c='v3'}

说明

  • SerializedName:用于将json字符串中的字段和java对象中的字段相匹配,也就是说即使java 中的字段和json中的字段名不相同也可以 可以通过注解进行匹配

Gson注解使用之Until

         static  class UntilBean{
        //一直参与序列化和反序列化
        private String firstName;
        //一直参与序列化和反序列化
        private String lastName;
        //版本<=1.1时 参与序列化和反序列化
        @Until(1.1) private String emailAddress;
        //版本<=1.1时 参与序列化和反序列化
        @Until(1.1) private String password;

        @Override
        public String toString() {
            return "UntilBean{" +
                    "firstName='" + firstName + '\'' +
                    ", lastName='" + lastName + '\'' +
                    ", emailAddress='" + emailAddress + '\'' +
                    ", password='" + password + '\'' +
                    '}';
        }
    }
        public static void main(String[] args) {
        //Util注解
        System.out.println("Util注解 <=");
        UntilBean untilBean=new UntilBean();
        untilBean.firstName="jing";
        untilBean.lastName="java";
        untilBean.emailAddress="123@qq.com";
        untilBean.password="123";
        System.out.println("until 原数据:"+untilBean.toString());
        Gson untilGson=new GsonBuilder().setVersion(1.2).create();
         String  untilJson=untilGson.toJson(untilBean);
        System.out.println("until version 1.2 java bean 转 json:"+untilJson);

        UntilBean untilBean1 = untilGson.fromJson(untilJson, UntilBean.class);
         System.out.println("until version 1.2 json 转 java bean:"+untilBean1.toString());


    }
    
    //打印信息
    //当我们设置version为1.2的时候的打印信息
	until 原数据:UntilBean{firstName='jing', lastName='java', emailAddress='123@qq.com', password='123'}
	until version 1.2 java bean 转 json:{"firstName":"jing","lastName":"java"}
	until version 1.2 json 转 java bean:UntilBean{firstName='jing', lastName='java', emailAddress='null', password='null'}
    //当我们设置version为1.1的时候的打印信息
    until 原数据:UntilBean{firstName='jing', lastName='java', emailAddress='123@qq.com', password='123'}
	until version 1.2 java bean 转 json:{"firstName":"jing","lastName":"java"}
	until version 1.2 json 转 java bean:UntilBean{firstName='jing', lastName='java', emailAddress='null', password='null'}

说明

  • 1.Until:标识属性在什么版本下可以参与序列化和反序列化,
  • 2.我们可以看到 当在属性上面标记Until注解中设置为1.1,即表示在版本小于等于1.1条件下都可以参与序列化和反序列,若设置版本大于1.1,则属性不参与序列化和反序列化
  • 3.若属性不设置注解,默认参与序列化和反序列

Gson注解使用之Since

	    static  class SinceBean{
	        //一直参与序列化和反序列化
	        private String firstName;
	        //一直参与序列化和反序列化
	        private String lastName;
	        //版本>=1.1时 参与序列化和反序列化
	        @Since(1.1) private String emailAddress;
	        //版本>=1.1时 参与序列化和反序列化
	        @Since(1.1) private String password;
	
	        @Override
	        public String toString() {
	            return "SinceBean{" +
	                    "firstName='" + firstName + '\'' +
	                    ", lastName='" + lastName + '\'' +
	                    ", emailAddress='" + emailAddress + '\'' +
	                    ", password='" + password + '\'' +
	                    '}';
	        }
	    }
	
	    public static void main(String[] args) {
        	//Since注解
	        System.out.println("Since注解 >=");
	        SinceBean sinceBean=new SinceBean();
	        sinceBean.firstName="jing";
	        sinceBean.lastName="java";
	        sinceBean.emailAddress="123@qq.com";
	        sinceBean.password="123";
	        System.out.println("Since 原数据:"+sinceBean.toString());
	        Gson untilGson=new GsonBuilder().setVersion(1.0).create();
	        String  untilJson=untilGson.toJson(sinceBean);
	        System.out.println("Since version 1.5 java bean 转 json:"+untilJson);
	
	        SinceBean sinceBean1 = untilGson.fromJson(untilJson, SinceBean.class);
	        System.out.println("Since version 1.5 json 转 java bean:"+sinceBean1.toString());
	
	
    }
    
    
    //打印信息
    //当版本大于等于1.1 为1.5的时候
    Since 原数据:SinceBean{firstName='jing', lastName='java', emailAddress='123@qq.com', password='123'}
	Since version 1.5 java bean 转 json:{"firstName":"jing","lastName":"java"}
	Since version 1.5 json 转 java bean:SinceBean{firstName='jing', lastName='java', emailAddress='null', password='null'}
     //当版本小于1.1 为1.0的时候
	Since 原数据:SinceBean{firstName='jing', lastName='java', emailAddress='123@qq.com', password='123'}
	Since version 1.0 java bean 转 json:{"firstName":"jing","lastName":"java"}
	Since version 1.0 json 转 java bean:SinceBean{firstName='jing', lastName='java', emailAddress='null', password='null'}

说明

  • 1.Since:标识属性在什么版本下可以参与序列化和反序列化,
  • 2.我们可以看到 当在属性上面标记Since注解中设置为1.1,即表示在版本大于等于1.1条件下都可以参与序列化和反序列,若设置版本小于1.1,则属性不参与序列化和反序列化
  • 3.若属性不设置注解,默认参与序列化和反序列

Gson注解之JsonAdapter

	  //通过注解设置一个解析器
	    @JsonAdapter(CustomJsonAdapter.class)
	    static class JsonAdapterBean {
	        //一直参与序列化和反序列化
	        private String firstName;
	        //一直参与序列化和反序列化
	        private String lastName;
	
	
	        public JsonAdapterBean(String firstName, String lastName) {
	            this.firstName = firstName;
	            this.lastName = lastName;
	        }
	
	        @Override
	        public String toString() {
	            return "JsonAdapterBean{" +
	                    "firstName='" + firstName + '\'' +
	                    ", lastName='" + lastName + '\'' +
	                    '}';
	        }
	    }
	
	    static class CustomJsonAdapter extends TypeAdapter<JsonAdapterBean> {
	
	        @Override
	        public void write(JsonWriter out, JsonAdapterBean value) throws IOException {
	             //写入json数据 name为"name" value为value.firstName + " " + value.lastName
	             //最终的json字符串为{"name":"java php"}
	            out.beginObject();
	            out.name("name");
	            out.value(value.firstName + " " + value.lastName);
	            out.endObject();
	
	        }
	
	        @Override
	        public JsonAdapterBean read(JsonReader in) throws IOException {
	            //读取数据  指针指向有效数据  然后获取对应的value 将其进行拆分
	            //最总将数组的值进行赋值 JsonAdapterBean{firstName='java', lastName='php'}
	            in.beginObject();
	            in.nextName();
	            String[] nameParts = in.nextString().split(" ");
	            in.endObject();
	            return new JsonAdapterBean(nameParts[0], nameParts[1]);
	        }
	    }
	
	    public static void main(String[] args) {
	         //JsonAdapter
	        JsonAdapterBean jsonAdapterBean = new JsonAdapterBean("java", "php");
	        System.out.println("JsonAdapter 原数据:" + jsonAdapterBean.toString());
	        Gson jsonAdapterGson = new GsonBuilder().setVersion(1.0).create();
	        String untilJson = jsonAdapterGson.toJson(jsonAdapterBean);
	        System.out.println("JsonAdapter 自定义解析器 java bean 转 json:" + untilJson);
	
	        JsonAdapterBean  jsonAdapterBean1 = jsonAdapterGson.fromJson(untilJson, JsonAdapterBean.class);
	        System.out.println("JsonAdapter 自定义解析器  json 转 java bean:" + jsonAdapterBean1.toString());


    	    }
    	    
    	  //打印信息
       	  JsonAdapter 原数据:JsonAdapterBean{firstName='java', lastName='php'}
		  JsonAdapter 自定义解析器 java bean 转 json:{"name":"java php"}
		  JsonAdapter 自定义解析器  json 转 java bean:JsonAdapterBean{firstName='java', lastName='php'}

说明

  • JsonAdapter: 给java bean设置一个自定义解析器

  • 在CustomJsonAdapter中我们继承TypeAdapter类,并重写了write和read方法

  • 在write中写入json数据 name为"name" value为value.firstName + " " + value.lastName,最总的json字符串为:{“name”:“java php”}

  • 在read中读取json数据。首先指针指向有效数据 获取对应的value 将其进行拆分,最后将数组的值赋值到java bean中,最终java bean为:JsonAdapterBean{firstName=‘java’, lastName=‘php’}

Gson注解之Expose

	  static class ExposeBean {
	        //参与序列化和反序列化
	        @Expose
	        private String firstName;
	        //参与序列化 但不参与反序列化
	        @Expose(serialize = true, deserialize = true)
	        private String lastName;

    //不参与序列化和反序列化
    @Expose(serialize = false, deserialize = true)
    private String emailAddress;

    //不参与序列化和反序列化
    private String password;

    public ExposeBean(String firstName, String lastName, String emailAddress, String password) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.emailAddress = emailAddress;
        this.password = password;
    }

    @Override
    public String toString() {
        return "ExposeBean{" +
                "firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", emailAddress='" + emailAddress + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
     }
    
        public static void main(String[] args) {

      System.out.println("gson注解之Expose");

    Gson gson1=new GsonBuilder()
            .excludeFieldsWithoutExposeAnnotation()
            .setPrettyPrinting()
            .create();

    ExposeBean mExposeBean=new ExposeBean("jing","mei","779889045@qq.com","1333");
    String json1=gson1.toJson(mExposeBean);

    System.out.println(json1);



    ExposeBean data2=gson1.fromJson(json1,ExposeBean.class);
    System.out.println(data2.firstName);
    System.out.println(data2.lastName);
    System.out.println(data2.emailAddress);
    System.out.println(data2.password);
    System.out.println(data2.toString());
    }


      //打印信息
           gson注解之Expose
		{
		  "firstName": "jing",
		  "lastName": "mei"
		}
		jing
		mei
		null
		null
		ExposeBean{firstName='jing', lastName='mei', emailAddress='null', password='null'}

说明

  • 1.Expose:标识属性是否可以被序列化和反序列化
  • 2.Expose里面有两个属性可以配置:serialize表示是否可以序列化(true可以 false不可以); deserialize表示是否可以反序列化(true可以,false不可以)
  • 3.Expose注解的使用必须要excludeFieldsWithoutExposeAnnotation()的配合,否则无效,所以需要通过GsonBuilder来构建Gson对象
  • 4.从打印信息我们可以看出若java bean转换为json过程中属性不能序列化,那么反序列化也是空的;若需要反序列化有效,必须是序列化有效的

Gson之自定义反序列

		    public class GsonDeserializer {
		
		    private String name;
		
		    private List<AuthorsBean> authors;
		
		    public String getName() {
		        return name;
		    }
		
		    public void setName(String name) {
		        this.name = name;
		    }
		
		    public List<AuthorsBean> getAuthors() {
		        return authors;
		    }
		
		    public void setAuthors(List<AuthorsBean> authors) {
		        this.authors = authors;
		    }
		
		    @Override
		    public String toString() {
		        return "GsonDeserializer{" +
		                "name='" + name + '\'' +
		                ", authors=" + authors +
		                '}';
		    }
		
		    static  class AuthorsBean{
		        private String id;
		
		        private String name;
		
		        public String getId() {
		            return id;
		        }
		
		        public void setId(String id) {
		            this.id = id;
		        }
		
		        public String getName() {
		            return name;
		        }
		
		        public void setName(String name) {
		            this.name = name;
		        }
		
		        @Override
		        public String toString() {
		            return "AuthorsBean{" +
		                    "id='" + id + '\'' +
		                    ", name='" + name + '\'' +
		                    '}';
		        }
		    }
		       public static void main(String[] args) {
		         String json = "{\n" +
		                "    \"name\": \"java\",\n" +
		                "    \"authors\": \"\"\n" +
		                "}";
		        Gson gson = new Gson();
		        GsonDeserializer gsonError1 = gson.fromJson(json, GsonDeserializer.class);
		
		        System.out.println(gsonError1);
		    }
		    
		    //打印信息
		    GsonDeserializer{name='java', authors=[AuthorsBean{id='1'', name='Joshua Bloch''}, AuthorsBean{id='2'', name='Tom'}]}

说明

从例子中我们可以看到 json字符串的格式和java bean的格式相对应的时候,反序列化是正常的

		    public class GsonDeserializer {
		
		    private String name;
		
		    private List<AuthorsBean> authors;
		
		    public String getName() {
		        return name;
		    }
		
		    public void setName(String name) {
		        this.name = name;
		    }
		
		    public List<AuthorsBean> getAuthors() {
		        return authors;
		    }
		
		    public void setAuthors(List<AuthorsBean> authors) {
		        this.authors = authors;
		    }
		
		    @Override
		    public String toString() {
		        return "GsonDeserializer{" +
		                "name='" + name + '\'' +
		                ", authors=" + authors +
		                '}';
		    }
		
		    static  class AuthorsBean{
		        private String id;
		
		        private String name;
		
		        public String getId() {
		            return id;
		        }
		
		        public void setId(String id) {
		            this.id = id;
		        }
		
		        public String getName() {
		            return name;
		        }
		
		        public void setName(String name) {
		            this.name = name;
		        }
		
		        @Override
		        public String toString() {
		            return "AuthorsBean{" +
		                    "id='" + id + '\'' +
		                    ", name='" + name + '\'' +
		                    '}';
		        }
		    }
		       public static void main(String[] args) {
				           String json = "{\n" +
	                "    \"name\": \"java\",\n" +
	                "    \"authors\": \"\"\n" +
	                "}";
	        Gson gson = new Gson();
	        GsonDeserializer gsonError1 = gson.fromJson(json, GsonDeserializer.class);
	
	        System.out.println(gsonError1);
		    }
		    
		    //打印信息
	        Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 3 column 17 path $.authors
		      at   com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:226)
		at com.google.gson.Gson.fromJson(Gson.java:932)
		at com.google.gson.Gson.fromJson(Gson.java:897)
		at com.google.gson.Gson.fromJson(Gson.java:846)
		at com.google.gson.Gson.fromJson(Gson.java:817)  

说明

从实例中我们看到json字符串中author字段为空,但是java bean中author字段时集合,所以在反序列化过程中会报错

					  public class GsonDeserializer {
			
			    private String name;
			
			    private List<AuthorsBean> authors;
			
			    public String getName() {
			        return name;
			    }
			
			    public void setName(String name) {
			        this.name = name;
			    }
			
			    public List<AuthorsBean> getAuthors() {
			        return authors;
			    }
			
			    public void setAuthors(List<AuthorsBean> authors) {
			        this.authors = authors;
			    }
			
			    @Override
			    public String toString() {
			        return "GsonDeserializer{" +
			                "name='" + name + '\'' +
			                ", authors=" + authors +
			                '}';
			    }
			
			    static  class AuthorsBean{
			        private String id;
			
			        private String name;
			
			        public String getId() {
			            return id;
			        }
			
			        public void setId(String id) {
			            this.id = id;
			        }
			
			        public String getName() {
			            return name;
			        }
			
			        public void setName(String name) {
			            this.name = name;
			        }
			
			        @Override
			        public String toString() {
			            return "AuthorsBean{" +
			                    "id='" + id + '\'' +
			                    ", name='" + name + '\'' +
			                    '}';
			        }
			    }
			
			    /**
			     * 自定义json反序列化
			     */
			    static  class CustomDeserializer  implements JsonDeserializer<GsonDeserializer>{
			
			
			
			        @Override
			        public GsonDeserializer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
			            //获取JsonObject
			            JsonObject jsonObject = json.getAsJsonObject();
			            //通过jsonObject获取name元素
			            JsonElement jsonTitle = jsonObject.get("name");
			            //获取name元素的值
			            String name=jsonTitle.getAsString();
			
			            //通过jsonObject获取authors元素
			            JsonElement jsonAuthors=jsonObject.get("authors");
			
			            GsonDeserializer gsonDeserializer=new GsonDeserializer();
			            //authors的值是否是数组
			            if(jsonAuthors.isJsonArray()){//若authors是数组类型 是我们需要的
			                GsonDeserializer.AuthorsBean[]   authors= context.deserialize(jsonAuthors,GsonDeserializer.AuthorsBean[].class);
			                gsonDeserializer.setAuthors(Arrays.asList(authors));
			            }else{
			                gsonDeserializer.setAuthors(null);
			            }
			
			            gsonDeserializer.setName(name);
			
			            return gsonDeserializer;
			        }
			    }
			
			    static  class  AuthorDeserializer implements JsonDeserializer{
			
			        @Override
			        public Object deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
			            JsonObject jsonObject = json.getAsJsonObject();
			
			            GsonDeserializer.AuthorsBean authorsBean=new GsonDeserializer.AuthorsBean();
			            authorsBean.setId(jsonObject.get("id").getAsString());
			            authorsBean.setName(jsonObject.get("name").getAsString());
			            return  authorsBean;
			        }
			    }
			
			    public static void main(String[] args) {
			              String json = "{\n" +
			                  "    \"name\": \"java\",\n" +
			                  "    \"authors\": \"\"\n" +
			                  "}";
			
			          Gson gson = new GsonBuilder().registerTypeAdapter(GsonDeserializer.class, new GsonDeserializer.CustomDeserializer())
			                  .registerTypeAdapter(GsonDeserializer.AuthorsBean.class, new AuthorDeserializer())
			                  .setPrettyPrinting()
			                  .create();
			
			          GsonDeserializer mGsonDeserializer = gson.fromJson(json, GsonDeserializer.class);
			          System.out.println(mGsonDeserializer);
             }


              //打印信息
              GsonDeserializer{name='java', authors=null}

说明

  • 1.从实例中我们看到 json字符串的author字段时空,但是java bean中author时list集合,按照正常模式的话时会报错的,但是我们通过registerTypeAdapter 设置自定义反序列化器,从而避免的报错。
  • 2.registerTypeAdapter()需要两个参数,第一个参数时反序列化的类型,第二参数是反序列化对象
  • 3.反序列化类需要实现JsonDeserializer接口,重写deserialize方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值