Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 获取同一对象的不同JSON表示_Java_Json_Jackson - Fatal编程技术网

Java 获取同一对象的不同JSON表示

Java 获取同一对象的不同JSON表示,java,json,jackson,Java,Json,Jackson,给定一个java对象,该对象通过Jackson序列化为JSON字符串。 是否可以控制序列化过程以从同一对象生成不同的JSON输出 压缩: { "a":"123", "s":"100" } 或正常: { "altitude":"123", "speed":"100" } 编辑: 我想用它实现的目标是有一个长的JSON格式,这有利于调试(人类可读),并有一个压缩格式,提供最小的占用空间。看看谷歌的库。它非常快速和灵活,可以在表示中排除(请参见)或重命名字段(请参见) 只是一个提议

给定一个java对象,该对象通过Jackson序列化为JSON字符串。 是否可以控制序列化过程以从同一对象生成不同的JSON输出

压缩:

{
  "a":"123",
  "s":"100"
}
或正常:

{
  "altitude":"123",
  "speed":"100"
}
编辑: 我想用它实现的目标是有一个长的JSON格式,这有利于调试(人类可读),并有一个压缩格式,提供最小的占用空间。

看看谷歌的库。它非常快速和灵活,可以在表示中排除(请参见)或重命名字段(请参见)

只是一个提议……:)

p.s.:如果您想使用多个表示,请使用Michael建议的
字段命名策略,例如:

GsonBuilder gsonBuilder = new GsonBuilder();

if (format == "compressed") 
    gsonBuilder.setFieldNamingStrategy(new CompressedFieldNamingStrategy());

Gson gson = gsonBuilder.create();

...

class CompressedFieldNamingStrategy implements FieldNamingStrategy
{
  private static HashTable translations = new HashMap<String, String>() {
      { put("altitude", "a"); put("speed", "s"); ...}
  };

  @Override
  public String translateName(Field field)
  {
    String name = field.getName();

    return translation.get(name);
  }
}
GsonBuilder GsonBuilder=new GsonBuilder();
如果(格式==“压缩”)
gsonBuilder.setFieldNamingStrategy(新的CompressedFieldNamingStrategy());
Gson-Gson=gsonBuilder.create();
...
类CompressedFieldNamingStrategy实现FieldNamingStrategy
{
私有静态HashTable translations=newhashmap(){
{put(“高度”、“a”);put(“速度”、“s”);…}
};
@凌驾
公共字符串translateName(字段)
{
字符串名称=field.getName();
返回translation.get(name);
}
}

您可以通过多种方式完成。这取决于你的要求。我建议您实施自己的财产命名策略。请参见以下示例:

class CompressedPropertyNamingStrategy extends PropertyNamingStrategyBase {

    private static final long serialVersionUID = 1L;

    @Override
    public String translate(String name) {
        return String.valueOf(name.charAt(0));
    }
}
您可以这样使用它:

ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new CompressedPropertyNamingStrategy());
String json = mapper.writeValueAsString(new Pojo());
如果不想压缩属性名,只需删除行号2即可

编辑1
在@aumand comment之后,我想通知您,此解决方案将不适用于包含多个属性(从同一字母开始)的实体。我们必须写出非常复杂的解决方案。例如:

class CompressedPropertyNamingStrategy extends PropertyNamingStrategyBase {

    private static final long serialVersionUID = 1L;

    private final int length;

    public CompressedPropertyNamingStrategy(int length) {
        this.length = length;
    }

    @Override
    public String translate(String name) {
        if (name.length() < length) {
            return name;
        }

        return name.substring(0, length);
    }
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(value = { ElementType.METHOD, ElementType.FIELD })
@Retention(value = RetentionPolicy.RUNTIME)
public @interface CompressedName {
    String value();
}
在本例中,您的命名策略可能如下所示:

class CompressedPropertyNamingStrategy extends PropertyNamingStrategy {

    private static final long serialVersionUID = 1L;

    @Override
    public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method,
            String defaultName) {
        CompressedName compressedProperty = method.getAnnotation(CompressedName.class);
        if (compressedProperty != null) {
            return compressedProperty.value();
        }

        // Implement default value: first letter, or something else
        return defaultName;
    }
}
{"a":123,"sp":100}
在此场景示例中,JSON可能如下所示:

class CompressedPropertyNamingStrategy extends PropertyNamingStrategy {

    private static final long serialVersionUID = 1L;

    @Override
    public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method,
            String defaultName) {
        CompressedName compressedProperty = method.getAnnotation(CompressedName.class);
        if (compressedProperty != null) {
            return compressedProperty.value();
        }

        // Implement default value: first letter, or something else
        return defaultName;
    }
}
{"a":123,"sp":100}

但是请注意,两个以同一个字母开头的属性使用这种方法可能会导致问题。是的,你是对的。我只给出了想法和默认实现。每个人都可以用非常复杂的方式实现它。带有注释的解决方案看起来不错,只是我仍然不知道如何控制生成标准JSON还是压缩的JSON。正如我所看到的,如果我添加
@CompressedName
,那么我将无法以编程方式选择长(标准)格式。默认情况下,
ObjectMapper
使用默认的完整属性名约定。如果不想使用自定义命名策略,请不要在
ObjectMapper
对象上调用
SetPropertyNameingStrategy
方法。使用
CompressedPropertyNameingStrategy
(或使用Gson的
CompressedFieldNameingStrategy
)非常有效!非常感谢。我正在使用Gson图书馆。但是,我不知道如何通过编程选择从同一对象生成压缩的或标准的JSON格式。您可以像在Jackson中一样使用它。请参阅此URL: