java jackson json processor - using in RestTemplate on Android and automatic type conversion
I have to write a proxy client in Java to connect to JSON WebService. I have only textual description of WebService methods and types. For instance the result of one method is
Params { byte[] challenge; byte[] proff; }
If I create a class Params in Java with both fields as byte[], jackson mapper treats them as binary arrays and encodes as following example
{"id":2,"method":"Authenticate","params":["bSwY+kKRO7sIJNZFG/L3dK2ke1kIDwzyK5n717MyBG1pnRhjqSF0kRMAyEqLYKA6VBwujaR8K/wr98+G1Av9vQ12soFi+3DViPN4YDguqF0=","2iNJ5UEK3eVxFTEUHMN04QM8WtNrwGSIu1hKVXFMVvQ="]}
The WebService exptects those paramet开发者_Go百科ers in a form of comma separated non negative byte values like
[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, ...............
I concluded that Jackson mapper uses some kind of automatic Java type recognition and chooses the corresponding JSON type. Is there a way to control it and ie change the type the serializer should use for particular Java type serialization? Where is description and mapping between Java and JSON types?
Regards
Jackson is representing the byte[] as a base 64 encoded string.
You'll need to implement a custom serializer, to manually iterate through the byte[] and generate the JSON array of integer values.
That didn't work out quite as I expected it should.
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();
}
}
精彩评论