- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
有没有通用的方法告诉 Gson 不要写空字符串?
我非常不喜欢必须实现一个 TypeAdapter 来处理每个字段作为 answer here有点暗示。
最佳答案
有点。据我所知,Gson 不会让您对对象字段进行太多控制,而且我知道唯一的控制方式是 @JsonAdapter
。例如,
import com.google.gson.annotations.JsonAdapter;
final class Pack {
@JsonAdapter(EmptyStringTypeAdapter.class)
final String foo;
@JsonAdapter(EmptyStringTypeAdapter.class)
final String bar;
private Pack(final String foo, final String bar) {
this.foo = foo;
this.bar = bar;
}
static Pack of(final String foo, final String bar) {
return new Pack(foo, bar);
}
@Override
public String toString() {
return foo + " " + bar;
}
}
尽管它对某些人来说可能看起来很乏味,但它可以让您完全控制数据传输对象,让您可以选择如何处理这个或那个字符串。示例类型适配器可能如下所示:
final class EmptyStringTypeAdapter
extends TypeAdapter<String> {
private EmptyStringTypeAdapter() {
}
@Override
@SuppressWarnings("resource")
public void write(final JsonWriter jsonWriter, @Nullable final String s)
throws IOException {
if ( s == null || s.isEmpty() ) {
jsonWriter.nullValue();
} else {
jsonWriter.value(s);
}
}
@Override
@Nonnull
@SuppressWarnings("EnumSwitchStatementWhichMissesCases")
public String read(final JsonReader jsonReader)
throws IOException {
final JsonToken token = jsonReader.peek();
switch ( token ) {
case NULL:
return "";
case STRING:
return jsonReader.nextString();
default:
throw new IllegalStateException("Unexpected token: " + token);
}
}
}
这里需要注意的是,它无法从 null 中恢复空字符串(不幸的是,您在这里遇到了不可逆的转换),因此您可能还想看看 https://github.com/google/gson/blob/master/extras/src/main/java/com/google/gson/typeadapters/PostConstructAdapterFactory.java恢复 @JsonAdapter(EmptyStringTypeAdapter.class)
- 读取时带注释的字段。示例测试:
private static final Gson gson = new Gson();
private static final Type listOfStringType = new TypeToken<List<String>>() {
}.getType();
public static void main(final String... args) {
// Single elements
ImmutableList.of(Pack.of("", ""), Pack.of("foo", ""), Pack.of("", "bar"), Pack.of("foo", "bar"))
.stream()
.peek(pack -> System.out.println("Pack before: " + pack))
.map(gson::toJson)
.peek(json -> System.out.println("JSON: " + json))
.map(json -> gson.fromJson(json, Pack.class))
.peek(pack -> System.out.println("Pack after: " + pack))
.forEach(pack -> System.out.println());
// Multiple elements
final List<String> stringsBefore = ImmutableList.of("", "foo", "bar");
System.out.println(stringsBefore);
final String stringsJson = gson.toJson(stringsBefore, listOfStringType);
System.out.println(stringsJson);
final List<String> stringsAfter = gson.fromJson(stringsJson, listOfStringType);
System.out.println(stringsAfter);
}
输出:
Pack before:
JSON: {}
Pack after: null null -- [!] not "" '"Pack before: foo
JSON: {"foo":"foo"}
Pack after: foo null -- [!] not foo ""Pack before: bar
JSON: {"bar":"bar"}
Pack after: null bar -- [!] not "" barPack before: foo bar
JSON: {"foo":"foo","bar":"bar"}
Pack after: foo bar[, foo, bar]
["","foo","bar"]
[, foo, bar]
但是,我认为编写复杂的(反)序列化策略不是一个好的选择,您可能对重新设计 DTO 和数据(反)序列化感兴趣。此外,""
是一个值,而 null
不是——我永远不会混合它们,我会修改为什么你的系统是这样设计的方式(它真的看起来像一个空值/空值混合问题)。
关于java - Gson序列化一般忽略空字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48437735/
我正在尝试创建一个程序,其中字符串的前三个字符重复给定次数,如下所示: foo('Chocolate', 3) # => 'ChoChoCho' foo('Abc', 3) # => 'AbcAbcA
我有以下字符串: std::string str = "Mode:AAA:val:101:id:A1"; 我想分离一个位于 "val:" 和 ":id" 之间的子字符串,这是我的方法: std::st
DNA 字符串可以是任意长度,包含 5 个字母(A、T、G、C、N)的任意组合。 压缩包含 5 个字母(A、T、G、C、N)的 DNA 字母串的有效方法是什么?不是考虑每个字母表 3 位,我们可以使用
是否有一种使用 levenstein 距离将一个特定字符串与第二个较长字符串中的任何区域进行匹配的好方法? 例子: str1='aaaaa' str2='bbbbbbaabaabbbb' if str
使用 OAuth 并使用以下函数使用我们称为“foo”(实际上是 OAuth token )的字符串加密 key public function encrypt( $text ) { // a
我是一名优秀的程序员,十分优秀!