<二> Google Gson 转换Json字符串和对象(日期,枚举的转化)

例子肯定能运行成功,考虑到面向对象,所以多写了几个类。

 

一、日期的转换需要在Create GsonBuilder时注册日期的格式。

 

二、对于枚举类,如果是默认转换,则不需要做任何操作,Gson会将枚举类转换为字符串。但如果需要自定义规则来进行枚举类和字符串的转换,则需要自定义相关的类实现JsonSerializer和JsonDeserializer类。

 

三、含有枚举类型的Java Object:NucleonEvent

 

/**
 * 
 */
package com.ebay.montage.pm.model;

import java.util.List;
import java.util.Map;

/**
 * @author Josh Wang(Sheng)
 *
 * @email  swang6@ebay.com
 */
public class NucleonEvent {
	
	private String id;
	
	private String host;
	
	private String odbFunction;
	
	private String source;
	
	private String format;
	
	private String classification;
	
	private long detectionTime;
	
	private long reportedTime;
	
	private Severity severity;
	
	private NucleonEventType type;
	
	private NucleonMetadata metadata;

	public String getId() {
		return id;
	}

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

	public NucleonEventType getType() {
		return type;
	}

	public void setType(NucleonEventType type) {
		this.type = type;
	}
	
	public enum NucleonEventType {
		
		nwmon_checkMem,nwmon_checkCPU_busyio;

	}
	
	public enum Severity {
		low;
	}
	
	public static class NucleonMetadata {
		private boolean passed;
		
		private String name;
		
		private List<Map<String, String>> msgs;
		
		private Map<String , Object> resultDataMap;

		public boolean isPassed() {
			return passed;
		}

		public void setPassed(boolean passed) {
			this.passed = passed;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public List<Map<String, String>> getMsgs() {
			return msgs;
		}

		public void setMsgs(List<Map<String, String>> msgs) {
			this.msgs = msgs;
		}

		public Map<String, Object> getResultDataMap() {
			return resultDataMap;
		}

		public void setResultDataMap(Map<String, Object> resultDataMap) {
			this.resultDataMap = resultDataMap;
		}
		
		
	}

	public String getHost() {
		return host;
	}

	public void setHost(String host) {
		this.host = host;
	}

	public String getOdbFunction() {
		return odbFunction;
	}

	public void setOdbFunction(String odbFunction) {
		this.odbFunction = odbFunction;
	}

	public String getSource() {
		return source;
	}

	public void setSource(String source) {
		this.source = source;
	}

	public String getClassification() {
		return classification;
	}

	public void setClassification(String classification) {
		this.classification = classification;
	}

	public long getDetectionTime() {
		return detectionTime;
	}

	public void setDetectionTime(long detectionTime) {
		this.detectionTime = detectionTime;
	}

	public long getReportedTime() {
		return reportedTime;
	}

	public void setReportedTime(long reportedTime) {
		this.reportedTime = reportedTime;
	}

	public Severity getSeverity() {
		return severity;
	}

	public void setSeverity(Severity severity) {
		this.severity = severity;
	}

	public String getFormat() {
		return format;
	}

	public void setFormat(String format) {
		this.format = format;
	}

	public NucleonMetadata getMetadata() {
		return metadata;
	}

	public void setMetadata(NucleonMetadata metadata) {
		this.metadata = metadata;
	}

	@Override
	public String toString() {
		return "NucleonEvent [id=" + id + ", host=" + host + ", odbFunction="
				+ odbFunction + ", source=" + source + ", format=" + format
				+ ", classification=" + classification + ", detectionTime="
				+ detectionTime + ", reportedTime=" + reportedTime
				+ ", severity=" + severity + ", type=" + type + ", metadata="
				+ metadata.getName() + ":" + metadata.isPassed() + metadata.getMsgs() + "]";
	}

	

	
}

 

 

四、抽象的转换类: EventDataparser

 

/**
 * 
 */
package com.ebay.montage.pm.handler;

import com.ebay.montage.pm.model.NucleonEvent;
import com.ebay.montage.pm.model.NucleonEvent.NucleonEventType;
import com.ebay.montage.pm.utils.DateUtils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

/**
 * @author Josh Wang(Sheng)
 *
 * @email  swang6@ebay.com
 */
public abstract class EventDataParser {
	
	public static Gson createGson() {
		GsonBuilder builder = new GsonBuilder();
		builder.setDateFormat("yyyy-MM-dd HH:mm:ss");
		builder.registerTypeAdapter(NucleonEventType.class, new NucleonEventTypeSerializer());
		
		Gson gson = builder.create();
		return gson;
	}

	/**
	 * Parse the given JSON String to NucleonEvent
	 * @param jsonStr
	 * @return
	 */
	public abstract NucleonEvent fromGson(String jsonStr);
	
	/**
	 * Parse the NucleonEvent to JSON String
	 * @return
	 */
	public abstract String toGson(NucleonEvent event);
}

 

如果需要使用自定义的日期转换器,需要自定义相应的Adapter 并注册相关的Adapter,如下面的Adapter将会处理所有的类型为Calendar的字段:

public static Gson createGson() {
		GsonBuilder builder = new GsonBuilder();
		builder.registerTypeAdapter(NucleonEventType.class, new NucleonEventTypeAdapter());
		builder.registerTypeAdapter(Calendar.class, new NucleonEventCalendarAdapter());
		builder.setDateFormat(DateUtils.MIDDLE_LINE_TIMESTAMP);
		
		Gson gson = builder.create();
		return gson;
	}

 

package com.ebay.montage.pm.handler;

import java.lang.reflect.Type;
import java.util.Calendar;

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

/**
 * @author Josh Wang(Sheng)
 *
 * @email  swang6@ebay.com
 */
public class NucleonEventCalendarAdapter implements JsonSerializer<Calendar>,
		JsonDeserializer<Calendar> {

	public Calendar deserialize(JsonElement json, Type arg1,
			JsonDeserializationContext arg2) throws JsonParseException {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(json.getAsJsonPrimitive().getAsLong());
		return calendar;
	}

	public JsonElement serialize(Calendar calendar, Type arg1,
			JsonSerializationContext arg2) {
		return new JsonPrimitive(Long.valueOf(calendar.getTimeInMillis()));
	}

	

}

 

五、实际进行转换的类

 

/**
 * 
 */
package com.ebay.montage.pm.handler;

import com.ebay.montage.pm.model.NucleonEvent;

/**
 * @author Josh Wang(Sheng)
 *
 * @email  swang6@ebay.com
 */
public class NucleonEventDataParser extends EventDataParser {

	@Override
	public NucleonEvent fromGson(String jsonStr) {
		return NucleonEventDataParser.createGson().fromJson(jsonStr, NucleonEvent.class);
	}

	@Override
	public String toGson(NucleonEvent event) {
		return NucleonEventDataParser.createGson().toJson(event);
	}

}

 

六、 上面的NucleonEvent中有两个枚举类:NucleonEventType 和 NucleonMetadata

我们只对NucleonEventType进行自定义的枚举类和json的转换,而对NucleonMetadata采用默认的转换。

package com.ebay.montage.pm.handler;

import java.lang.reflect.Type;

import com.ebay.montage.pm.model.NucleonEvent.NucleonEventType;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

/**
 * 
 * @author Josh Wang(Sheng)
 *
 * @email  swang6@ebay.com
 */
public class NucleonEventTypeSerializer implements JsonSerializer<NucleonEventType>,
		JsonDeserializer<NucleonEventType> {

	/**
	 * JSON to Object
	 */
	public NucleonEventType deserialize(JsonElement json, Type arg1,
			JsonDeserializationContext arg2) throws JsonParseException {
        return NucleonEventType.valueOf(json.getAsString()) ; 
	}

	/**
	 * Object to JSON
	 */
	public JsonElement serialize(NucleonEventType type, Type arg1,
			JsonSerializationContext arg2) {
		return new JsonPrimitive(type.name());
	}


}

 

 

七、Unit Test类

 

/**
 * 
 */
package com.ebay.montage.pm;


import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import com.ebay.montage.pm.handler.NucleonEventDataParser;
import com.ebay.montage.pm.model.NucleonEvent;
import com.ebay.montage.pm.model.NucleonEvent.NucleonEventType;

/**
 * @author Josh Wang(Sheng)
 *
 * @email  swang6@eaby.com
 */
public class TestNucleonEventParser {

	private static String json;
	
	@BeforeClass
	public static void init() {
		json = "{\"id\": \"eventId\", \"type\":\"nwmon_checkCPU_busyio\", "
				+ "\"format\" : \"normalizedEvent\", \"detectionTime\": \"23424234234\", "
				+ " \"severity\":\"low\", "
				+ "\"metadata\":{\"passed\": true,\"name\": \"Recent Changes Check\", \"msgs\": [{\"data\": \"<HTML Allowed>\"}, {\"eve\": \"<Pdf Allowed>\"}]}}";
	}
	
	@Test
	public void fromGson() {
		NucleonEvent event = new NucleonEventDataParser().fromGson(json);
		
		Assert.assertEquals("eventId", event.getId());
		Assert.assertEquals("nwmon_checkCPU_busyio", event.getType().toString());
		
		System.out.println(event.toString());
	}
	
	@Test 
	public void toGson() {
		NucleonEvent event = new NucleonEvent();
		
		event.setId("eventId2");
		event.setType(NucleonEventType.nwmon_checkCPU_busyio);
		
		Assert.assertTrue(new NucleonEventDataParser().toGson(event).contains("eventId2"));
	}
}

 

 

 

 

Gson单元测试实战:3步构建健壮的JSON序列化测试体系 JSON序列化与反序列化是现代Java应用开发中的基础技术,它实现了数据在对象与字符串格式间的转换,是前后端通信和数据持久化的核心。其原理在于通过反射或自定义适配器,将Java对象属性映射为JSON键值对。这项技术的价值在于确保数据在传输和存储过程中的一致性、完整性和正确性,广泛应用于API接口、配置文件解析和缓存数据处理等场景。在Java生态中,Gson作为广泛使用的JSON库,其灵活配置和自定义适配器功能尤其强大,但也带来了测试复杂性。通过结合JUnit 5的参数化测试和AssertJ的递归比较,开发者 阅读详情

相关推荐

Java Map与String互转全解析:从基础到JSON序列化实战

在Java开发中,数据结构的序列化与反序列化是核心技术之一,它涉及将内存中的对象转换为可存储或传输的格式,反之亦然。其核心原理是通过特定的编码规则,实现数据在结构化对象(如Map)与字符串之间的无损转换。这项技术的价值在于保障数据在跨系统交互、持久化存储和网络传输中的一致性与可靠性。常见的应用场景包括构建HTTP请求参数、处理配置文件、缓存数据序列化以及日志记录等。本文将深入探讨Java中Map与String互转的多种方案,重点分析JSON序列化库(如Jackson)的使用技巧与性能优化,并涵盖Proper

weixin_30475039的博客 303

JSON字符串与对象,日期对象的转换工具类实现

代码如下: package com.chuang.utils; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import java.text.SimpleDateFormat; /** * JSON工具类:提供

m0_55796087的博客 531

Moshi:Kotlin 原生 JSON 库的序列化与反序列化实战指南

JSON 序列化与反序列化是现代软件开发中处理数据交换的核心技术,尤其在移动端和后端服务开发中至关重要。其原理是通过特定的库将内存中的对象转换为 JSON 格式的字符串进行传输或存储,反之亦然。这项技术的价值在于实现跨平台、跨语言的数据结构化通信,是构建 RESTful API 和微服务架构的基础。在 Kotlin 开发领域,传统的 JSON 库如 Gson 在处理 Kotlin 语言特性(如空安全和数据类)时存在局限,因此出现了对 Kotlin 提供一等公民支持的解决方案。本文聚焦于 **Moshi**

weixin_30786657的博客 383

json字符串转化为对象集合(包含Date类型字段处理)

json字符串转对象List package com.xxxxx.emis.base.util; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.List; /** * @author Q * .

QWQ19980801的博客 1059

Java实体与Map转换全解析:从反射、序列化库到性能优化实践

在Java开发中,对象与字典结构的相互转换是数据处理的基础操作,涉及序列化、ORM映射和动态配置等核心场景。其原理在于桥接强类型的对象世界与弱类型的字典世界,需要在类型安全、性能与灵活性之间取得平衡。这项技术的价值在于提升代码的通用性和动态处理能力,是构建灵活数据管道的关键。实践中,开发者常面临反射性能陷阱、类型转换异常等挑战。通过对比手动编码、反射工具、Jackson/Gson等序列化库以及Spring/Hutool框架方案的优劣,可以针对不同场景选择最优解。例如,在需要处理JSON交互和高性能序列化的微

weixin_33965305的博客 513

Kotlin JSON序列化实战:Moshi核心优势与迁移指南

JSON序列化是现代应用开发中处理网络通信和数据持久化的基础技术,其核心原理是将内存中的对象结构转换为可传输或存储的文本格式。在Kotlin生态中,传统的Gson或Jackson库常因对空安全、数据类等语言特性支持不足而引发运行时异常。Moshi作为专为Kotlin设计的序列化方案,通过编译时代码生成机制,在保证类型安全的同时实现了零反射开销,显著提升了代码健壮性和运行性能。其模块化的适配器系统与一流的Kotlin语言特性支持,使其在Android和Kotlin后端项目中能高效处理字段映射、多态类型等复杂场

weixin_30458043的博客 319

自定义枚举 --- Gson转换

通过Restful接口返回的JSON数据默认是枚举的名字,但是使用自定义枚举时,一般统一使用自定义的code来代表。所以需要自定义HttpMessageConverter CodedTypeTypeAdapter import com.google.gson.*; impor...

chijue3990的博客 579

Gson最新版本gson-2.2.3.jar详解与实战应用

Gson是Google开源的一款高性能Java库,用于在Java对象与JSON数据之间进行便捷的序列化与反序列化操作。其核心设计理念是“简单易用、无依赖、高性能”,通过反射机制自动映射字段,无需额外配置即可实现基本转换。相比Jackson的复杂配置和Fastjson的安全隐患,Gson以线程安全、泛型支持完善和API简洁著称。最新版本进一步优化了泛型解析性能,并强化了对Kotlin数据类的支持。

weixin_42097508的博客 699

解决gson解析时将数字类型(int、double、float、long等)全部转为double的问题

gson解析补充

учёба 3519

Gson 枚举类型的统一序列化/反序列化处理

实现了通过gson对enum的自定义转化过程,不需要预先定义enmu,并且不需要修改gson源码,在框架顶层处理基本可以达到对enum的抽象管理。

6.5 构网型储能系统的协同控制策略

本文系统阐述了构网型储能系统的协同控制策略,重点分析了多机组群协同运行面临的功率分配不均、动态响应失配等挑战。研究提出了改进型下垂控制与虚拟阻抗法、基于一致性算法的分布式协同控制等解决方案,探讨了构网型储能与同步发电机在惯性响应、一次调频等方面的协同机制,以及与跟网型电源在电压支撑、阻抗重塑等方面的互补作用。文章构建了分层控制架构,为实现多类型电源的全局优化运行提供了技术路径,对提升高比例新能源电力系统的稳定性具有重要意义。

技术工作者 1002

使用Gson对多个枚举类型的统一序列化/反序列化处理

关于源码,已经迁移到GitHub上,地址https://github.com/google/gson 也可以直接在这个地址下载,已集成下面文章中的方法 -------------------------------------------------------------------------------------以下正文 看文章前请先下载最新Gson代码,地址: https://

atm008的专栏 4521

从Gotham到Foundry:一文读懂Palantir三大产品线(Gotham/Foundry/Apollo)的核心差异与适用场景

本文深度解析Palantir三大产品线Gotham、Foundry和Apollo的核心差异与适用场景。Gotham专为国防与情报设计,提供军事级安全分析;Foundry是企业数字化转型的通用平台,支持低代码开发;Apollo则是云原生基石,确保系统可靠运行。通过对比产品架构与典型应用,帮助技术决策者根据需求做出明智选择。

weixin_42524499的博客 840

Gson-Fire 项目推荐

Gson-Fire 项目推荐 gson-fire A java library that adds some very useful features to Gson, like Date serializing to unix timestamp or RFC3339, method (getters) seriali...

gitblog_00004的博客 1082

SocraticLM: Exploring Socratic Personalized Teaching with Large Language Models

大型语言模型(LLM)被认为是推进智能教育的一项关键技术,因为它们展示了深入理解教学场景和为学生提供个性化指导的潜力。然而,当前个性化教学中基于LLM的应用主要遵循“问答”范式,学生被动地获得答案和解释。在本文中,我们提出了苏格拉底式教学模式(SocraticLM ),它实现了一种苏格拉底式的“发人深省”的教学范式,实现了真正的课堂教师的角色,让学生积极参与到真正掌握解决问题所需的思考过程中。

weixin_43961909的博客 2883

多智能体强化学习论文——SEAC(NIPS 2020)

存在的问题&研究动机&研究思路 在稀疏奖励的环境下,多智能体的exploration存在效率不足等问题。 在IAC的基础上尝试加入重要性采样,使得每次更新智能体iii的参数时,不再仅仅使用智能体iii的数据,而是使用所有智能体的数据进行智能体iii数据的更新。 对于原始的IAC算法是on-policy的,而SEAC则是off-poligy的。 创新点 在每个智能体iii的actoriactor_iactori​和criticicritic_icritici​的更新过程中,都加入了重要性

我的AI笔记 1207

Java JSON处理实战:深度解析与双向转换核心技术详解

JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,已成为现代应用开发中数据交互的通用标准。其核心原理在于通过键值对和数组结构,实现跨语言、跨平台的数据序列化与反序列化。在Java开发领域,掌握JSON处理技术对于构建高性能、可维护的后端服务具有重要价值,尤其在微服务架构、API接口开发和数据持久化等场景中不可或缺。本文聚焦于Jackson库的深度应用,通过对比Gson与Fastjson的特性差异,系统讲解如何实现复杂嵌套JSON的精准解析与Java对象的高效转换。

weixin_33984032的博客 398

Windows下QT5.15.2安装MQTT模块全攻略(附分支选择避坑指南)

本文详细介绍了在Windows环境下为QT5.15.2安装MQTT模块的完整流程,包括环境准备、源码获取、编译配置及项目集成等关键步骤。特别针对分支选择、依赖项处理和常见错误提供了实用解决方案,帮助开发者高效完成MQTT模块的安装与调试,适用于物联网开发场景。

weixin_29224589的博客 466

Gson学习

package com.bh.test;import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Date; import java.util.LinkedList; import java.util.List;import com.google.gson.Gson; import com.google.g

cuiyaoqiang的博客 594

Pyinstaller 打包 Pyzbar 时缺失 DLL 文件的排查与修复指南

本文详细解析了使用Pyinstaller打包Pyzbar库时,因缺失关键DLL文件导致程序闪退的常见问题。文章提供了从问题复现、错误诊断到最终修复的完整解决方案,核心在于通过修改.spec配置文件,手动将缺失的libzbar-64.dll等文件添加到打包过程中,确保生成的可执行文件能独立运行。

wdx012345的博客 504

Zipformer实战:5分钟快速搭建语音识别模型(附LibriSpeech测试结果)

本文提供了一份详细的Zipformer语音识别模型实战指南。通过清晰的步骤,指导读者在5分钟内完成从环境配置、LibriSpeech数据集准备到模型训练与测试的全过程。文章重点解析了关键配置参数,并分享了在LibriSpeech测试集上的性能结果,帮助开发者快速评估和应用这一高效的语音识别架构。

weixin_35578748的博客 161

Gson高级特性:自定义序列化与反序列化

Gson高级特性:自定义序列化与反序列化 【免费下载链接】gson A Java serialization/deserialization library to convert Java Objects into JSON and back ...

gitblog_00333的博客 782

SAP CAP core data service 里 association 和 composition 的区别

我们进行 SAP CAP 开发时,在schema.cds里进行数据建模,可以使用 association 和 composition,来描述两个 entity 之间的关联关系。在 SAP BTP 的 Cloud Application Programming Model (CAP) 中,cds文件定义了数据模型,而和是用于建立实体关系的两种关键机制。理解它们的区别对于构建高效、清晰的 CAP 数据模型至关重要。下面,我们将通过严谨的逻辑推理,结合代码示例,深入分析和之间的核心差异。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 322

Java架构师实战:大模型结构化输出与Prompt工程,打造稳定AI集成

在AI工程化实践中,大语言模型(LLM)的非结构化文本输出常难以被后端系统直接消费。为解决此问题,结构化输出技术应运而生,其核心原理是通过Prompt工程,将自然语言的模糊性转化为程序可处理的确定性数据格式,如JSON。这项技术的核心价值在于极大提升了AI能力集成的稳定性和程序可处理性,使得大模型的输出能像传统API一样被Java等强类型语言直接解析为对象。在应用场景上,它广泛适用于智能客服分类、合同信息抽取、动态问卷分析等需要从非结构化文本中提取规整数据的领域。本文聚焦于**Prompt工程**与**JS

weixin_30765577的博客 344

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Java开发从入门到精通:环境配置与核心概念解析

Java作为面向对象的编程语言,其'一次编写,到处运行'的特性使其成为企业级开发的首选。理解Java运行原理需要从JVM虚拟机机制入手,掌握环境变量配置、基础语法和面向对象特性是开发者的基本功。在实际工程中,合理使用集合框架和并发编程能显著提升系统性能,而Java 8引入的Lambda和Stream API则大大简化了数据处理。对于初学者而言,正确配置JAVA_HOME环境变量和掌握数据类型转换是快速入门的关键,这些基础技能也为后续学习Spring等框架打下坚实基础。

weixin_30587927的博客 380

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

SDK的设计哲学

本文摘要:SDK开发的核心原则是维护高内聚低耦合的模块化设计。文章重点强调了接口契约与向后兼容性的重要性,指出SDK必须使用语义化版本号(SemVer)并严格遵守主版本内的兼容承诺。作者通过实际案例(如TSMaster API的兼容性问题)展示了破坏契约的危害,同时给出了正确实践建议:使用@since文档注释标注版本信息、保留旧接口并引导迁移、通过版本号明确传达变更风险等。这些规范能帮助开发者建立可靠的技术契约,保障下游项目的稳定性与可维护性。(149字)

qq_42095554的博客 396

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

上一篇: <一> Google Gson 转换Json字符串和对象(对象中还有内嵌对象,Map,数组)
下一篇: Eclipse中Git的安装、配置、使用
iteye_4921
博客等级 码龄8年 25粉丝 59原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值