mirror of
https://github.com/jlengrand/vert.x.git
synced 2026-03-10 08:51:19 +00:00
Fixed JsonCodecLoader to manage wrong types
Signed-off-by: slinkydeveloper <francescoguard@gmail.com>
This commit is contained in:
committed by
Julien Viet
parent
5b83683c7d
commit
3062540c5d
@@ -5,8 +5,8 @@ import io.vertx.core.buffer.Buffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.function.Function;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class JsonCodecLoader {
|
||||
|
||||
Map<Class, JsonCodec> jsonCodecMap;
|
||||
@@ -24,22 +24,58 @@ public class JsonCodecLoader {
|
||||
return new JsonCodecLoader(codecs);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T decode(Buffer value, Class<T> c) {
|
||||
Object json = value.toJson();
|
||||
private <T> JsonCodec retrieveCodec(Class<T> c) {
|
||||
JsonCodec codec = jsonCodecMap.get(c);
|
||||
if (codec == null) throw new IllegalStateException("Unable to find codec for class " + c.getName());
|
||||
return codec;
|
||||
}
|
||||
|
||||
public <T> T decode(Object json, Class<T> c) {
|
||||
try {
|
||||
return (T) jsonCodecMap.get(c).decode(json);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Unable to find codec for class " + c.getCanonicalName(), e);
|
||||
return (T) retrieveCodec(c).decode(json);
|
||||
} catch (ClassCastException e) {
|
||||
// A codec accepts only a particular type, that could not be the same of json parameter.
|
||||
// This happens in particular with decodeBuffer(), when jackson decides what he wants for the serialized type
|
||||
// And it's even worse if someone configure the Jackson mapper to use always float or long or things like these
|
||||
// That's why these awful tricks
|
||||
if (json.getClass().equals(Double.class)) {
|
||||
return (T) retrieveCodec(c).decode(((Double)json).floatValue());
|
||||
}
|
||||
if (json.getClass().equals(Float.class)) {
|
||||
return (T) retrieveCodec(c).decode(((Float)json).doubleValue());
|
||||
}
|
||||
if (json.getClass().equals(String.class)) {
|
||||
return (T) retrieveCodec(c).decode(((String)json).charAt(0));
|
||||
}
|
||||
try {
|
||||
return decodeNaturalNumber((Number)json, c);
|
||||
} catch (ClassCastException e1) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Buffer encode(Object value) {
|
||||
private <T> T decodeNaturalNumber(Number number, Class<T> c) {
|
||||
try {
|
||||
return Buffer.buffer(jsonCodecMap.get(value.getClass()).encode(value).toString());
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Unable to find codec for class " + value.getClass().getCanonicalName(), e);
|
||||
return (T) retrieveCodec(c).decode(number.intValue());
|
||||
} catch (ClassCastException e) {
|
||||
try {
|
||||
return (T) retrieveCodec(c).decode(number.longValue());
|
||||
} catch (ClassCastException e1) {
|
||||
return (T) retrieveCodec(c).decode(number.shortValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T decodeBuffer(Buffer value, Class<T> c) {
|
||||
return decode(Json.decodeValue(value), c);
|
||||
}
|
||||
|
||||
public Object encode(Object value) {
|
||||
return retrieveCodec(value.getClass()).encode(value);
|
||||
}
|
||||
|
||||
public Buffer encodeBuffer(Object value) {
|
||||
return Json.encodeToBuffer(encode(value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package io.vertx.core.json;
|
||||
|
||||
import io.vertx.core.buffer.Buffer;
|
||||
import io.vertx.core.json.codecs.MyBooleanPojo;
|
||||
import io.vertx.core.json.codecs.MyCharPojo;
|
||||
import io.vertx.core.json.codecs.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static io.vertx.core.json.Json.encodeToBuffer;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class JsonCodecLoaderTest {
|
||||
@@ -21,15 +20,119 @@ public class JsonCodecLoaderTest {
|
||||
public void booleanCodecTest() {
|
||||
MyBooleanPojo pojo = new MyBooleanPojo();
|
||||
pojo.setValue(true);
|
||||
assertEquals(Buffer.buffer("true"), jsonCodecLoader.encode(pojo));
|
||||
assertEquals(pojo, jsonCodecLoader.decode(Buffer.buffer("true"), MyBooleanPojo.class));
|
||||
assertEquals(encodeToBuffer(true), jsonCodecLoader.encodeBuffer(pojo));
|
||||
assertEquals(pojo, jsonCodecLoader.decodeBuffer(encodeToBuffer(true), MyBooleanPojo.class));
|
||||
}
|
||||
|
||||
@Test(expected = ClassCastException.class)
|
||||
public void booleanCodecWrongTypeTest() {
|
||||
jsonCodecLoader.decodeBuffer(encodeToBuffer("aaa"), MyBooleanPojo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void charCodecTest() {
|
||||
MyCharPojo pojo = new MyCharPojo();
|
||||
pojo.setValue('a');
|
||||
assertEquals('a', jsonCodecLoader.decode(Buffer.buffer(new byte[] {(byte)'a'}), MyCharPojo.class));
|
||||
assertEquals(encodeToBuffer('a'), jsonCodecLoader.encodeBuffer(pojo));
|
||||
assertEquals(pojo, jsonCodecLoader.decodeBuffer(encodeToBuffer('a'), MyCharPojo.class));
|
||||
}
|
||||
|
||||
@Test(expected = ClassCastException.class)
|
||||
public void charCodecWrongTypeTest() {
|
||||
jsonCodecLoader.decodeBuffer(encodeToBuffer(1), MyCharPojo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doubleCodecTest() {
|
||||
MyDoublePojo pojo = new MyDoublePojo();
|
||||
pojo.setValue(1.2d);
|
||||
assertEquals(encodeToBuffer(1.2d), jsonCodecLoader.encodeBuffer(pojo));
|
||||
assertEquals(pojo, jsonCodecLoader.decodeBuffer(encodeToBuffer(1.2d), MyDoublePojo.class));
|
||||
}
|
||||
|
||||
@Test(expected = ClassCastException.class)
|
||||
public void doubleCodecWrongTypeTest() {
|
||||
jsonCodecLoader.decodeBuffer(encodeToBuffer(1L), MyDoublePojo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void floatCodecTest() {
|
||||
MyFloatPojo pojo = new MyFloatPojo();
|
||||
pojo.setValue(1.2f);
|
||||
assertEquals(encodeToBuffer(1.2f), jsonCodecLoader.encodeBuffer(pojo));
|
||||
assertEquals(pojo, jsonCodecLoader.decodeBuffer(encodeToBuffer(1.2f), MyFloatPojo.class));
|
||||
}
|
||||
|
||||
@Test(expected = ClassCastException.class)
|
||||
public void floatCodecWrongTypeTest() {
|
||||
jsonCodecLoader.decodeBuffer(encodeToBuffer(1L), MyFloatPojo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void intCodecTest() {
|
||||
MyIntegerPojo pojo = new MyIntegerPojo();
|
||||
pojo.setValue(1);
|
||||
assertEquals(encodeToBuffer((int)1), jsonCodecLoader.encodeBuffer(pojo));
|
||||
assertEquals(pojo, jsonCodecLoader.decodeBuffer(encodeToBuffer((int)1), MyIntegerPojo.class));
|
||||
}
|
||||
|
||||
@Test(expected = ClassCastException.class)
|
||||
public void intCodecWrongTypeTest() {
|
||||
jsonCodecLoader.decodeBuffer(encodeToBuffer(1.2), MyIntegerPojo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void longCodecTest() {
|
||||
MyLongPojo pojo = new MyLongPojo();
|
||||
pojo.setValue(1L);
|
||||
assertEquals(encodeToBuffer(1L), jsonCodecLoader.encodeBuffer(pojo));
|
||||
assertEquals(pojo, jsonCodecLoader.decodeBuffer(encodeToBuffer(1L), MyLongPojo.class));
|
||||
}
|
||||
|
||||
@Test(expected = ClassCastException.class)
|
||||
public void longCodecWrongTypeTest() {
|
||||
jsonCodecLoader.decodeBuffer(encodeToBuffer(1.2), MyLongPojo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shortCodecTest() {
|
||||
MyShortPojo pojo = new MyShortPojo();
|
||||
pojo.setValue((short)1);
|
||||
assertEquals(encodeToBuffer((short)1), jsonCodecLoader.encodeBuffer(pojo));
|
||||
assertEquals(pojo, jsonCodecLoader.decodeBuffer(encodeToBuffer((short)1), MyShortPojo.class));
|
||||
}
|
||||
|
||||
@Test(expected = ClassCastException.class)
|
||||
public void shortCodecWrongTypeTest() {
|
||||
jsonCodecLoader.decodeBuffer(encodeToBuffer(1.2), MyShortPojo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jsonArrayCodecTest() {
|
||||
MyJsonArrayPojo pojo = new MyJsonArrayPojo();
|
||||
JsonArray array = new JsonArray().add(1).add(2).add(3);
|
||||
pojo.setValue(array);
|
||||
assertEquals(array.toBuffer(), jsonCodecLoader.encodeBuffer(pojo));
|
||||
assertEquals(pojo, jsonCodecLoader.decodeBuffer(array.toBuffer(), MyJsonArrayPojo.class));
|
||||
}
|
||||
|
||||
@Test(expected = ClassCastException.class)
|
||||
public void jsonArrayCodecWrongTypeTest() {
|
||||
jsonCodecLoader.decodeBuffer(encodeToBuffer(2), MyJsonArrayPojo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jsonObjectCodecTest() {
|
||||
MyJsonObjectPojo pojo = new MyJsonObjectPojo();
|
||||
JsonObject obj = new JsonObject().put("a", 1).put("b", "c");
|
||||
pojo.setValue(obj);
|
||||
assertEquals(obj.toBuffer(), jsonCodecLoader.encodeBuffer(pojo));
|
||||
assertEquals(pojo, jsonCodecLoader.decodeBuffer(obj.toBuffer(), MyJsonObjectPojo.class));
|
||||
}
|
||||
|
||||
@Test(expected = ClassCastException.class)
|
||||
public void jsonObjectCodecWrongTypeTest() {
|
||||
jsonCodecLoader.decodeBuffer(encodeToBuffer(2), MyJsonObjectPojo.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class MyJsonObjectPojo {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
MyJsonObjectPojo that = (MyJsonObjectPojo) o;
|
||||
return value == that.value;
|
||||
return Objects.equals(value, that.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user