Java Smile和JSON之间的高效转换

Java Smile和JSON之间的高效转换,java,json,serialization,jackson,Java,Json,Serialization,Jackson,我已经了解到,微笑和JSON之间的转换可以通过以下几个来源高效完成: 这意味着JSON和Smile之间的转换可以高效地完成,并且不会丢失信息。(); 这两种格式是兼容的:通过包装适当的解码器,您可以发送Smile并将其解码为JSON。() 甚至:。。。这意味着在JSON上运行的工具也可以与Smile一起使用,只要存在合适的编码器/解码器供工具使用 不幸的是,除了关于编码器/解码器的信息外,我在任何源代码中都没有找到任何有用的东西 因此,一般的问题是如何做到这一点 有什么内在的方法可以做到这

我已经了解到,微笑和JSON之间的转换可以通过以下几个来源高效完成:

  • 这意味着JSON和Smile之间的转换可以高效地完成,并且不会丢失信息。();
  • 这两种格式是兼容的:通过包装适当的解码器,您可以发送Smile并将其解码为JSON。()
甚至:。。。这意味着在JSON上运行的工具也可以与Smile一起使用,只要存在合适的编码器/解码器供工具使用

不幸的是,除了关于编码器/解码器的信息外,我在任何源代码中都没有找到任何有用的东西

因此,一般的问题是如何做到这一点

  • 有什么内在的方法可以做到这一点吗
  • 如果没有,是否有一些定制的和已经实施的解决方案
  • 如果没有,请给我一些关于编写编码器/解码器的提示

我无法评估此MO的效率,但是,这种简单直接的方法效果很好:从SmileFactory创建jackson映射器,给它一个JsonNode实例,并让它将输入映射到字节[]smile数据:

public static void main(String[] args)
{
    ObjectMapper jsonMapper = new ObjectMapper();  // just for testing!
    ObjectMapper smileMapper = new ObjectMapper(new SmileFactory());

    // create json test data
    SmileDemo sd = new SmileDemo();
    System.out.println("ORIGINAL " + sd.str + " " + sd.i + " " + sd.flt + " " + sd.dbl  + " " + sd.bool + " " + sd.date);
    JsonNode json = jsonMapper.valueToTree(sd);
    try {
        // the following line is the actual conversion
        byte[] smileData = smileMapper.writeValueAsBytes(json);
        // test the conversion
        sd = smileMapper.readValue(smileData, SmileDemo.class);
        System.out.println("CONVERTED " + sd.str + " " + sd.i + " " + sd.flt + " " + sd.dbl  + " " + sd.bool + " " + sd.date);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static class SmileDemo
{
    public String str = "Hello World";
    public int i = 1000;
    public float flt = 1000.34F;
    public double dbl = 1000.34D;
    public boolean bool = false;
    public java.util.Date date = new Date(2016, 1, 1);
}

谷歌找到了这个包含从json字节数组到smile字节数组的转换(搜索
convertToSmile
)。也许这会有所帮助?

没有直接的代码转换,但相对有效的方法是使用特定于格式的映射器读取
JsonNode
;使用“另一个”映射器写出。像这样:

public class JsonSmileMigrationService
{
    private static final Logger log = LoggerFactory.getLogger(JsonSmileMigrationService.class);

    public static byte[] convertToSmile(byte[] json, JsonFactory jsonFactory, SmileFactory smileFactory)
    {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        try // try-with-resources
        (
            JsonGenerator jg = smileFactory.createGenerator(bos);
            JsonParser jp = jsonFactory.createParser(json)
        )
        {
            while (jp.nextToken() != null)
            {
                jg.copyCurrentEvent(jp);
            }
        }
        catch (Exception e)
        {
            log.error("Error while converting json to smile", e);
        }

        return bos.toByteArray();
    }

    public static byte[] convertToJson(byte[] smile, JsonFactory jsonFactory, SmileFactory smileFactory)
    {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        try // try-with-resources
        (
            JsonParser sp = smileFactory.createParser(smile);
            JsonGenerator jg = jsonFactory.createGenerator(bos)
        )
        {
            while (sp.nextToken() != null)
            {
                jg.copyCurrentEvent(sp);
            }
        }
        catch (Exception e)
        {
            log.error("Error while converting smile to json", e);
        }

        return bos.toByteArray();
    }
}
final SmileMapper SMILE_MAPPER = new SmileMapper();
final JsonMapper JSON_MAPPER = new JsonMapper();

public byte[] smileBytesFromJson(byte[] json) throws IOException
{
  JsonNode tree = JSON_MAPPER.readTree(json);
  return SMILE_MAPPER.writeValueAsBytes(tree);
}

public byte[] jsonBytesFromSmile(byte[] smile) throws IOException
{
  JsoNode tree = SMILE_MAPPER.readTree(smile);
  return JSON_MAPPER.writeValueAsBytes(tree);
}
// can also take/produce String for JSON

但是如果性能真的很重要,您可以选择使用公认答案所示的
JsonParser
/
JsonGenerator
方法;想法是正确的,创建
SmileFactory
JsonFactory
,解析器/生成器对,迭代令牌,使用
JsonGenerator.copyCurrentEvent(sourceParser)

您能澄清一下它是如何解决我的问题的吗?我没有看到任何东西,除了序列化/反序列化到/从微笑。。。让我进一步说明一下我的问题:我有一个字节数组,是在序列化要微笑的对象时得到的(
smileData
)。我想把这个字节数组转换成JSON字符串。当然,最简单的解决方案是将其反序列化,然后序列化为JSON。看起来效率不高……你是对的。这确实是建议的,我没有更好的解决方案。+1,但实际上它进行单向转换。在双方转换后,我将接受它作为答案。否则我会做的。