java jackson json процессор - использование в RestTemplate на Android и автоматическое преобразование типов - PullRequest
0 голосов
/ 22 июля 2011

Мне нужно написать прокси-клиент на Java для подключения к JSON WebService. У меня есть только текстовое описание методов и типов WebService. Например, результат одного метода

Params { байт [] вызов; byte [] proff; }

Если я создаю класс Params в Java с обоими полями как byte [], Джексон Маппер обрабатывает их как двоичные массивы и кодирует, как показано в следующем примере

{"id":2,"method":"Authenticate","params":["bSwY+kKRO7sIJNZFG/L3dK2ke1kIDwzyK5n717MyBG1pnRhjqSF0kRMAyEqLYKA6VBwujaR8K/wr98+G1Av9vQ12soFi+3DViPN4YDguqF0=","2iNJ5UEK3eVxFTEUHMN04QM8WtNrwGSIu1hKVXFMVvQ="]}

WebService использует эти параметры в виде неотрицательных значений байтов, разделенных запятыми, таких как

[truncated] {"id":2,"method":"Authenticate","params":[[114,109,104,101,70,88,16,32,102,17,117,3,105,104,112,4,39,103,11,54,90,106,90,69,26,20,5,10,121,52,108,64,106,102,52,124,87,8,21,29,28,119,110,70,122,33,105, ...............

Я пришел к выводу, что картограф Джексона использует какое-то автоматическое распознавание типов Java и выбирает соответствующий тип JSON. Есть ли способ управлять им и т. Е. Изменять тип, который сериализатор должен использовать для конкретной сериализации типа Java? Где описание и отображение между типами Java и JSON?

Привет

1 Ответ

1 голос
/ 22 июля 2011

Джексон представляет байт [] в виде строки в кодировке 64.

Вам потребуется реализовать пользовательский сериализатор, чтобы вручную перебирать байт [] и генерировать массив целочисленных значений JSON.


Это не сработало так, как я ожидал.

import java.io.IOException;

import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.Version;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializerProvider;
import org.codehaus.jackson.map.module.SimpleModule;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    ObjectMapper mapper = new ObjectMapper();
    System.out.println(mapper.writeValueAsString(new Bar()));
    // output: {"bytes":"AQIDBAUGBwgJCgsMDQ4PEA=="}

    SimpleModule module = new SimpleModule("byte[] as integers", Version.unknownVersion());
    module.addSerializer(byte[].class, new ByteArrayAsIntegersSerializer());
    mapper = new ObjectMapper().withModule(module);
    System.out.println(mapper.writeValueAsString(new Bar()));
    // output: {"bytes":"AQIDBAUGBwgJCgsMDQ4PEA=="}
    // ByteArrayAsIntegersSerializer was not used!

    module = new SimpleModule("byte[] as integers 2", Version.unknownVersion());
    module.addSerializer(Bar.class, new BarSerializer());
    mapper = new ObjectMapper().withModule(module);
    System.out.println(mapper.writeValueAsString(new Bar()));
    // output: {"bytes":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}
  }
}

class Bar
{
  public byte[] bytes = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
}

class BarSerializer extends JsonSerializer<Bar>
{
  @Override
  public void serialize(Bar value, JsonGenerator jgen, SerializerProvider provider) 
      throws IOException, JsonProcessingException
  {
    jgen.writeStartObject();
    jgen.writeFieldName("bytes");
    jgen.writeStartArray();
    for (byte b : value.bytes)
      jgen.writeNumber(b);
    jgen.writeEndArray();
    jgen.writeEndObject();
  }
}

class ByteArrayAsIntegersSerializer extends JsonSerializer<byte[]>
{
  @Override
  public void serialize(byte[] bytes, JsonGenerator jgen, SerializerProvider provider) 
      throws IOException, JsonProcessingException
  {
    jgen.writeStartArray();
    for (byte b : bytes)
      jgen.writeNumber(b);
    jgen.writeEndArray();
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...