2015-07-15 3 views
1

Есть ли способ сделать Джексон сериализацией некоторого объекта потока (и закрыть после него)? как это:Jackson JSON - сериализовать потоки

class TextFile{ 
    String fileName; 
    StringReader content; 
    //ByteArrayInputStream content; 
} 

Update

Разъяснение: Я хочу, чтобы поток контента, а не просто сериализовать его к одному объекту String.

+0

Какой контент действительно содержит поток? Вы хотите написать его как base64? Или вы сначала разобрали его, а затем напишите какое-нибудь представление о нем? –

+0

Base64 - это вариант, но не требование. Я просто не хочу держать всю строку в памяти. – kromit

ответ

1

Реализация пользовательских JsonSerializer:

public class StreamSerializer extends JsonSerializer<ByteArrayInputStream> { 

    @Override 
    public void serialize(ByteArrayInputStream content, 
          JsonGenerator jsonGenerator, 
          SerializerProvider serializerProvider) 
          throws IOException, JsonProcessingException { 
     jsonGenerator.writeBinary(content, -1); 
} 

И использовать его как это:

public class TextFile { 
    String fileName; 
    @JsonSerialize(using=StreamSerializer.class, as=byte[].class) 
    ByteArrayInputStream content; 
} 
+0

Я не хочу держать весь строковый объект в памяти. Для этого я бы использовал 'String content'. вопрос заключается в том, как сериализовать поток. – kromit

+1

@kromit Этого не было в исходном вопросе! Однако я обновил свой ответ. – hzpz

+0

Это то, что я хотел. Спасибо. – kromit

0

Ваш вопрос похож на: Jackson JSON custom serialization for certain fields

Что такое желаемое поведение? Вы хотите, чтобы поток был сериализован как строка, как двоичный контент, проанализирован и сериализовался как объект и т. Д.

Предполагая, что данные, сериализованные как строка, можно использовать аннотацию, чтобы рассказать Джексону о том, как сериализовать это:

public class TextFile { 
    String fileName; 
    @JsonSerialize(using=ReaderToStringSerializer.class, as=String.class) 
    StringReader content; 
} 


public class ReaderToStringSerializer extends JsonSerializer<Reader> { 

@Override 
public void serialize(Reader contents, 
         JsonGenerator jsonGenerator, 
         SerializerProvider serializerProvider) 
         throws IOException, JsonProcessingException { 
    StringBuilder buffer = new StringBuilder(); 
    char[] array = new char[8096]; 
    int len = 0; 
    while (-1 != (len = contents.read(array))) { 
     buffer.append(array,0,len); 
    } 
    contents.close(); 
    jsonGenerator.writeString(buffer.toString()); 
} 

выходной сигнал будет что-то вроде:

{ 
    "fileName": "foo.bar", 
    "content": "the quick brown fox..." 
} 
+1

Не заново изобретайте колодец, используйте 'IOUtils # toString (Reader)' commons-io ', чтобы получить содержимое' Reader' как 'String'. – hzpz

+1

это не «потоковое» содержимое. 'buffer.toString()' создает целую строку в памяти и пропускает всю суть использования потока на первом месте. – kromit

+0

Я предположил, что у вас есть все данные в памяти, потому что вы задали * StringReader * в своем вопросе. Правильно потоковый вывод JSON сложнее, чем просто чтение байтов и запись байтов, так как вам нужно правильно учитывать экранирование символов и непечатаемых символов. Если вы хотите получить base64, то решение writeBinary (см. Выше) будет правильным. – tombrown52

Смежные вопросы