栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

部分GSON反序列化

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

部分GSON反序列化

…但是我希望图书馆尽其所能。

好吧,只需使用Gson。

有数据传输对象模式,尤其是Gson映射类,可以完美地解决您的问题。默认情况下,如果Gson能够满足内置功能的映射,并且除了特殊情况外,您不必自己完成工作。此类映射类仅旨在存在于JSON内容和您的业务对象类之间,以便对数据进行(反)序列化(简单地说,DTO仅为此目的而存在,并且与Gson相关的注释不得散布到您的业务类中-
只需将DTO转换为业务对象)。

对应

final class Wrapper {    @SerializedName("id")    @Expose    private final String id = null;    @SerializedName("games")    @Expose    private final List<String> games = null;    @SerializedName("definition")    @Expose    private final FormulaDefinition formulaDefinition = null;    private Wrapper() {    }    @Override    public String toString() {        return new StringBuilder("Wrapper{")     .append("id='").append(id)     .append("', games=").append(games)     .append(", formulaDefinition=").append(formulaDefinition)     .append('}')     .toString();    }}package q41323887;import java.util.List;import com.google.gson.annotations.Expose;import com.google.gson.annotations.SerializedName;final class FormulaDefinition {    @SerializedName("count")    @Expose    private  int count ; // Gson works with final primitives like `int` strangely    @SerializedName("operatorDefinitions")    @Expose    private final List<OperatorDefinition> operatorDefinitions = null;    private FormulaDefinition() {    }    @Override    public String toString() {        return new StringBuilder("FormulaDefinition{")     .append("count=").append(count)     .append(", operatorDefinitions=").append(operatorDefinitions)     .append('}')     .toString();    }}final class OperatorDefinition {    @SerializedName("operators")    @Expose    private final Operator operators = null;    @SerializedName("first")    @Expose    private final String first = null;    @SerializedName("second")    @Expose    private final String second = null;    @SerializedName("result")    @Expose    private final String result = null;    private OperatorDefinition() {    }    @Override    public String toString() {        return new StringBuilder("OperatorDefinition{")     .append("operators=").append(operators)     .append(", first='").append(first)     .append("', second='").append(second)     .append("', result='").append(result)     .append("'}")     .toString();    }}enum Operator {    PLUS("+"),    MINUS("-"),    ASTERISK("*"),    SLASH("/");    private static final Map<String, Operator> tokenToOperatorIndex = createTokenToOperatorIndexInJava8();    private final String token;    Operator(final String token) {        this.token = token;    }    static Operator resolveOperator(final String token) throws NoSuchElementException {        final Operator operator = tokenToOperatorIndex.get(token);        if ( operator == null ) { throw new NoSuchElementException("Cannot resolve operator by " + token);        }        return operator;    }    private static Map<String, Operator> createTokenToOperatorIndex() {        final Map<String, Operator> index = new HashMap<>();        for ( final Operator operator : values() ) { index.put(operator.token, operator);        }        return unmodifiableMap(index);    }    private static Map<String, Operator> createTokenToOperatorIndexInJava8() {        final Map<String, Operator> index = Stream.of(values())     .collect(toMap(operator -> operator.token, identity()));        return unmodifiableMap(index);    }}

反序列化

然后,由于您本

operators
打算成为有效的枚举,因此这是您真正需要自定义JSON反序列化器的唯一地方,仅因为Gson默认规则不了解这些规则。

final class OperatorJsonDeserializer        implements JsonDeserializer<Operator> {    private static final JsonDeserializer<Operator> operatorJsonDeserializer = new OperatorJsonDeserializer();    private OperatorJsonDeserializer() {    }    static JsonDeserializer<Operator> getOperatorJsonDeserializer() {        return operatorJsonDeserializer;    }    @Override    public Operator deserialize(final JsonElement json, final Type type, final JsonDeserializationContext context) throws JsonParseException {        try { final String token = json.getAsJsonPrimitive().getAsString(); return resolveOperator(token);        } catch ( final NoSuchElementException ex ) { throw new JsonParseException(ex);        }    }}

演示版

现在,您可以使用

Wrapper
该类反序列化JSON:

// Gson instances are thread-safe and can be easily instantiated onceprivate static final Gson gson = new GsonBuilder()        .registerTypeAdapter(Operator.class, getOperatorJsonDeserializer())        .create();public static void main(final String... args)        throws IOException {    try ( final Reader reader = new InputStreamReader(EntryPoint.class.getResourceAsStream("/test.json")) ) {        final Wrapper wrapper = gson.fromJson(reader, Wrapper.class);        out.println(wrapper);        // ... convert the wrapper DTO above to your target business object    }}

输出:

包装器{id = ‘10’,游戏= [PZ],FormulaDefinition = FormulaDefinition {count =
10,operatorDefinitions = [OperatorDefinition {operators = PLUS,first
=‘1-5’,second =‘1-5’,result =’ 2-5’}]}}


编辑

我在以下代码片段中对Gson的理解是错误的:

    @SerializedName("count")    @Expose    private  int count ; // Gson works with final primitives like `int` strangely

实际上,Gson 确实
工作正常。我忘记了Java常量内联。使用获得

count
通孔反射
Field
效果完美。但是,由于内联,返回了contant值。与相似的普通对象
javap-p -c

final class ext.Test$Immutable {  private final int foo;  private ext.Test$Immutable();    Code:       0: aload_0       1: invokespecial #1       // Method java/lang/Object."<init>":()V       4: aload_0       5: iconst_0       6: putfield      #2       // Field foo:I       9: return  private int getFoo();    Code:       0: iconst_0       1: ireturn  public java.lang.String toString();    Code:       0: ldc#4       // String (IMMUTABLE:0)       2: areturn}

在这种情况下,甚至

toString()
返回一个常数。是的,这就是Java和
javac
工作方式。为了禁用这种内联并将
final
修饰符添加到该字段,就像周围的所有字段一样,应添加一个非编译时值:

    @SerializedName("count")    @Expose    private final int count = constOf(0);

哪里

constOf(int)
仅仅是:

private static int constOf(final int value) {    return value;}

现在,所有传入的DTO字段都可以轻松声明

final



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/440804.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号