mirror of https://github.com/jwtk/jjwt.git
Added Gson serialization/deserialization exception
This commit is contained in:
parent
243ec7802c
commit
747238a479
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2018 JWTK
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-root</artifactId>
|
||||
<version>0.11.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>jjwt-gson</artifactId>
|
||||
<name>JJWT :: Extensions :: Gson</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<jjwt.root>${basedir}/../..</jjwt.root>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,42 @@
|
|||
package io.jsonwebtoken.io;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import io.jsonwebtoken.lang.Assert;
|
||||
import java.io.IOException;
|
||||
|
||||
public class GsonDeserializer<T> implements Deserializer<T> {
|
||||
|
||||
private final Class<T> returnType;
|
||||
private final Gson gson;
|
||||
|
||||
@SuppressWarnings("unused") //used via reflection by RuntimeClasspathDeserializerLocator
|
||||
public GsonDeserializer() {
|
||||
this(GsonSerializer.DEFAULT_GSON);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "WeakerAccess", "unused"}) // for end-users providing a custom gson
|
||||
public GsonDeserializer(Gson gson) {
|
||||
this(gson, (Class<T>) Object.class);
|
||||
}
|
||||
|
||||
private GsonDeserializer(Gson gson, Class<T> returnType) {
|
||||
Assert.notNull(gson, "gson cannot be null.");
|
||||
Assert.notNull(returnType, "Return type cannot be null.");
|
||||
this.gson = gson;
|
||||
this.returnType = returnType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T deserialize(byte[] bytes) throws DeserializationException {
|
||||
try {
|
||||
return readValue(bytes);
|
||||
} catch (IOException e) {
|
||||
String msg = "Unable to deserialize bytes into a " + returnType.getName() + " instance: " + e.getMessage();
|
||||
throw new DeserializationException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
protected T readValue(byte[] bytes) throws IOException {
|
||||
return gson.fromJson(new String(bytes), returnType);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package io.jsonwebtoken.io;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import io.jsonwebtoken.lang.Assert;
|
||||
import io.jsonwebtoken.lang.Strings;
|
||||
|
||||
public class GsonSerializer<T> implements Serializer<T> {
|
||||
|
||||
static final Gson DEFAULT_GSON = new GsonBuilder().disableHtmlEscaping().create();
|
||||
private Gson gson;
|
||||
|
||||
@SuppressWarnings("unused") //used via reflection by RuntimeClasspathDeserializerLocator
|
||||
public GsonSerializer() {
|
||||
this(DEFAULT_GSON);
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess") //intended for end-users to use when providing a custom gson
|
||||
public GsonSerializer(Gson gson) {
|
||||
Assert.notNull(gson, "gson cannot be null.");
|
||||
this.gson = gson;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] serialize(T t) throws SerializationException {
|
||||
Assert.notNull(t, "Object to serialize cannot be null.");
|
||||
//Gson never throws any serialization exception
|
||||
return writeValueAsBytes(t);
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess") //for testing
|
||||
protected byte[] writeValueAsBytes(T t) {
|
||||
Object o;
|
||||
if (t instanceof byte[]) {
|
||||
o = Encoders.BASE64.encode((byte[]) t);
|
||||
} else if (t instanceof char[]) {
|
||||
o = new String((char[]) t);
|
||||
} else {
|
||||
o = t;
|
||||
}
|
||||
return this.gson.toJson(o).getBytes(Strings.UTF_8);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package io.jsonwebtoken.io
|
||||
|
||||
import com.google.gson.Gson
|
||||
import io.jsonwebtoken.lang.Strings
|
||||
import org.junit.Test
|
||||
|
||||
import static org.easymock.EasyMock.*
|
||||
import static org.junit.Assert.*
|
||||
|
||||
class GsonDeserializerTest {
|
||||
|
||||
@Test
|
||||
void testDefaultConstructor() {
|
||||
def deserializer = new GsonDeserializer()
|
||||
assertNotNull deserializer.gson
|
||||
}
|
||||
|
||||
@Test
|
||||
void testObjectMapperConstructor() {
|
||||
def customGSON = new Gson()
|
||||
def deserializer = new GsonDeserializer(customGSON)
|
||||
assertSame customGSON, deserializer.gson
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException)
|
||||
void testObjectMapperConstructorWithNullArgument() {
|
||||
new GsonDeserializer<>(null)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeserialize() {
|
||||
byte[] serialized = '{"hello":"世界"}'.getBytes(Strings.UTF_8)
|
||||
def expected = [hello: '世界']
|
||||
def result = new GsonDeserializer().deserialize(serialized)
|
||||
assertEquals expected, result
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeserializeFailsWithJsonProcessingException() {
|
||||
|
||||
def ex = createMock(java.io.IOException)
|
||||
|
||||
expect(ex.getMessage()).andReturn('foo')
|
||||
|
||||
def deserializer = new GsonDeserializer() {
|
||||
@Override
|
||||
protected Object readValue(byte[] bytes) throws java.io.IOException {
|
||||
throw ex
|
||||
}
|
||||
}
|
||||
|
||||
replay ex
|
||||
|
||||
try {
|
||||
deserializer.deserialize('{"hello":"世界"}'.getBytes(Strings.UTF_8))
|
||||
fail()
|
||||
} catch (DeserializationException se) {
|
||||
assertEquals 'Unable to deserialize bytes into a java.lang.Object instance: foo', se.getMessage()
|
||||
assertSame ex, se.getCause()
|
||||
}
|
||||
|
||||
verify ex
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
package io.jsonwebtoken.io
|
||||
|
||||
import io.jsonwebtoken.lang.Strings
|
||||
import org.junit.Test
|
||||
|
||||
import static org.easymock.EasyMock.*
|
||||
import static org.junit.Assert.*
|
||||
import com.google.gson.Gson
|
||||
|
||||
class GsonSerializerTest {
|
||||
|
||||
@Test
|
||||
void testDefaultConstructor() {
|
||||
def serializer = new GsonSerializer()
|
||||
assertNotNull serializer.gson
|
||||
}
|
||||
|
||||
@Test
|
||||
void testObjectMapperConstructor() {
|
||||
def customGSON = new Gson()
|
||||
def serializer = new GsonSerializer<>(customGSON)
|
||||
assertSame customGSON, serializer.gson
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException)
|
||||
void testObjectMapperConstructorWithNullArgument() {
|
||||
new GsonSerializer<>(null)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testByte() {
|
||||
byte[] expected = "120".getBytes(Strings.UTF_8) //ascii("x") = 120
|
||||
byte[] bytes = "x".getBytes(Strings.UTF_8)
|
||||
byte[] result = new GsonSerializer().serialize(bytes[0]) //single byte
|
||||
assertTrue Arrays.equals(expected, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testByteArray() { //expect Base64 string by default:
|
||||
byte[] bytes = "hi".getBytes(Strings.UTF_8)
|
||||
String expected = '"aGk="' as String //base64(hi) --> aGk=
|
||||
byte[] result = new GsonSerializer().serialize(bytes)
|
||||
assertEquals expected, new String(result, Strings.UTF_8)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEmptyByteArray() { //expect Base64 string by default:
|
||||
byte[] bytes = new byte[0]
|
||||
byte[] result = new GsonSerializer().serialize(bytes)
|
||||
assertEquals '""', new String(result, Strings.UTF_8)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testChar() { //expect Base64 string by default:
|
||||
byte[] result = new GsonSerializer().serialize('h' as char)
|
||||
assertEquals "\"h\"", new String(result, Strings.UTF_8)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCharArray() { //expect Base64 string by default:
|
||||
byte[] result = new GsonSerializer().serialize("hi".toCharArray())
|
||||
assertEquals "\"hi\"", new String(result, Strings.UTF_8)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSerialize() {
|
||||
byte[] expected = '{"hello":"世界"}'.getBytes(Strings.UTF_8)
|
||||
byte[] result = new GsonSerializer().serialize([hello: '世界'])
|
||||
assertTrue Arrays.equals(expected, result)
|
||||
}
|
||||
|
||||
//THIS IS COMMENTED OUT BECAUSE GSN NEVER THROWS ANY SERIALIZATION EXCEPTION
|
||||
// @Test
|
||||
// void testSerializeFailsWithJsonProcessingException() {
|
||||
//
|
||||
// def ex = createMock(JsonProcessingException)
|
||||
//
|
||||
// expect(ex.getMessage()).andReturn('foo')
|
||||
//
|
||||
// def serializer = new GsonSerializer() {
|
||||
// @Override
|
||||
// protected byte[] writeValueAsBytes(Object o) throws JsonProcessingException {
|
||||
// throw ex
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// replay ex
|
||||
//
|
||||
// try {
|
||||
// serializer.serialize([hello: 'world'])
|
||||
// fail()
|
||||
// } catch (SerializationException se) {
|
||||
// assertEquals 'Unable to serialize object: foo', se.getMessage()
|
||||
// assertSame ex, se.getCause()
|
||||
// }
|
||||
//
|
||||
// verify ex
|
||||
// }
|
||||
}
|
|
@ -36,6 +36,7 @@
|
|||
<modules>
|
||||
<module>jackson</module>
|
||||
<module>orgjson</module>
|
||||
<module>gson</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
Loading…
Reference in New Issue