SPR-7627 added Serializer and Deserializer strategies, Converter adapters, and default implementations

This commit is contained in:
Mark Fisher
2010-10-11 17:36:18 +00:00
parent bd22bed10a
commit c046419acd
13 changed files with 695 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* 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.
*/
package org.springframework.core.serializer;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
/**
* Deserializer that reads an input stream using Java Serialization.
*
* @author Gary Russell
* @author Mark Fisher
* @since 3.0.5
*/
public class DefaultDeserializer implements Deserializer<Object> {
/**
* Reads the input stream and deserializes into an object.
*/
public Object deserialize(InputStream inputStream) throws IOException {
ObjectInputStream objectInputStream = null;
try {
objectInputStream = new ObjectInputStream(inputStream);
return objectInputStream.readObject();
}
catch (ClassNotFoundException e) {
if (objectInputStream != null) {
objectInputStream.close();
}
throw new IOException(e.getMessage());
}
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* 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.
*/
package org.springframework.core.serializer;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import org.springframework.util.Assert;
/**
* Serializer that writes an object to an output stream using Java Serialization.
*
* @author Gary Russell
* @author Mark Fisher
* @since 3.0.5
*/
public class DefaultSerializer implements Serializer<Object> {
/**
* Writes the source object to an output stream using Java Serialization.
* Source object must implement {@link Serializable}.
*/
public void serialize(Object object, OutputStream outputStream) throws IOException {
Assert.isTrue(object instanceof Serializable, this.getClass().getName()
+ " requires a Serializable payload, but received [" + object.getClass().getName() + "]");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(object);
objectOutputStream.flush();
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* 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.
*/
package org.springframework.core.serializer;
/**
* Exception to be thrown when a failure occurs while deserializing an object.
*
* @author Gary Russell
* @since 3.0.5
*/
@SuppressWarnings("serial")
public class DeserializationFailureException extends SerializationException {
/**
* Construct a <code>DeserializationFailureException</code> with the specified detail message.
* @param message the detail message
*/
public DeserializationFailureException(String message) {
super(message);
}
/**
* Construct a <code>DeserializationFailureException</code> with the specified detail message
* and nested exception.
* @param message the detail message
* @param cause the nested exception
*/
public DeserializationFailureException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* 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.
*/
package org.springframework.core.serializer;
import java.io.IOException;
import java.io.InputStream;
/**
* A strategy interface for converting from data in an InputStream to an Object.
*
* @author Gary Russell
* @author Mark Fisher
* @since 3.0.5
*/
public interface Deserializer<T> {
/**
* Read (assemble an object of type T) from an InputStream.
* @param inputStream The InputStream.
* @return the deserialized object
* @throws IOException in case of errors reading the stream
*/
public T deserialize(InputStream inputStream) throws IOException;
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* 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.
*/
package org.springframework.core.serializer;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import org.springframework.core.convert.converter.Converter;
import org.springframework.util.Assert;
/**
* A {@link Converter} that delegates to a {@link Deserializer}
* to convert data in a byte array to an object.
*
* @author Gary Russell
* @author Mark Fisher
* @since 3.0.5
*/
public class DeserializingConverter implements Converter<byte[], Object> {
private final Deserializer<Object> deserializer;
/**
* Create a default DeserializingConverter that uses standard Java deserialization.
*/
public DeserializingConverter() {
this.deserializer = new DefaultDeserializer();
}
/**
* Create a DeserializingConverter that delegates to the provided {@link Deserializer}
*/
public DeserializingConverter(Deserializer<Object> deserializer) {
Assert.notNull(deserializer, "deserializer must not be null");
this.deserializer = deserializer;
}
public Object convert(byte[] source) {
ByteArrayInputStream byteStream = new ByteArrayInputStream(source);
try {
return this.deserializer.deserialize(byteStream);
}
catch (Exception e) {
try {
byteStream.close();
}
catch (IOException e1) { /* ignore */ }
throw new DeserializationFailureException(
"Failed to deserialize payload. " +
"Is the byte array a result of corresponding serialization for " +
this.deserializer.getClass().getName() + "?", e);
}
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* 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.
*/
package org.springframework.core.serializer;
import org.springframework.core.NestedRuntimeException;
/**
* Root exception for serialization and deserialization exceptions.
*
* @author Gary Russell
* @since 3.0.5
*/
@SuppressWarnings("serial")
public abstract class SerializationException extends NestedRuntimeException {
/**
* Construct a <code>SerializationException</code> with the specified detail message.
* @param message the detail message
*/
public SerializationException(String message) {
super(message);
}
/**
* Construct a <code>SerializationException</code> with the specified detail message
* and nested exception.
* @param message the detail message
* @param cause the nested exception
*/
public SerializationException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* 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.
*/
package org.springframework.core.serializer;
/**
* Exception to be thrown when a failure occurs while serializing an object.
*
* @author Gary Russell
* @since 3.0.5
*/
@SuppressWarnings("serial")
public class SerializationFailureException extends SerializationException {
/**
* Construct a <code>SerializationFailureException</code> with the specified detail message.
* @param message the detail message
*/
public SerializationFailureException(String message) {
super(message);
}
/**
* Construct a <code>SerializationFailureException</code> with the specified detail message
* and nested exception.
* @param message the detail message
* @param cause the nested exception
*/
public SerializationFailureException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* 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.
*/
package org.springframework.core.serializer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* Static utility for serialization and deserialization.
*
* @author Dave Syer
* @since 3.0.5
*/
public abstract class SerializationUtils {
/**
* Serialize the object provided.
*
* @param object the object to serialize
* @return an array of bytes representing the object in a portable fashion
*/
public static byte[] serialize(Object object) {
if (object == null) {
return null;
}
ByteArrayOutputStream stream = new ByteArrayOutputStream();
try {
new ObjectOutputStream(stream).writeObject(object);
}
catch (IOException e) {
throw new IllegalArgumentException("failed to serialize object of type: " + object.getClass(), e);
}
return stream.toByteArray();
}
/**
* Deserialize the byte array into an object.
*
* @param bytes a serialized object
* @return the result of deserializing the bytes
*/
public static Object deserialize(byte[] bytes) {
if (bytes == null) {
return null;
}
try {
return new ObjectInputStream(new ByteArrayInputStream(bytes)).readObject();
}
catch (IOException e) {
throw new IllegalArgumentException("failed to deserialize object", e);
}
catch (ClassNotFoundException e) {
throw new IllegalStateException("failed to deserialize object type", e);
}
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* 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.
*/
package org.springframework.core.serializer;
import java.io.IOException;
import java.io.OutputStream;
/**
* A strategy interface for streaming an object to an OutputStream.
*
* @author Gary Russell
* @author Mark Fisher
* @since 3.0.5
*/
public interface Serializer<T> {
/**
* Write an object of type T to the outputSream.
* @param object The object.
* @param outputStream the outputStream
* @throws IOException in case of errors writing to the stream
*/
public void serialize(T object, OutputStream outputStream) throws IOException;
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* 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.
*/
package org.springframework.core.serializer;
import java.io.ByteArrayOutputStream;
import org.springframework.core.convert.converter.Converter;
import org.springframework.util.Assert;
/**
* A {@Link Converter} that delegates to a {@link Serializer} to convert an object to a byte array.
*
* @author Gary Russell
* @author Mark Fisher
* @since 3.0.5
*/
public class SerializingConverter implements Converter<Object, byte[]> {
private final Serializer<Object> serializer;
/**
* Create a default SerializingConverter that uses standard Java serialization.
*/
public SerializingConverter() {
this.serializer = new DefaultSerializer();
}
/**
* Create a SerializingConverter that delegates to the provided {@link Serializer}
*/
public SerializingConverter(Serializer<Object> serializer) {
Assert.notNull(serializer, "serializer must not be null");
this.serializer = serializer;
}
/**
* Serializes the source object and returns the byte array result.
*/
public byte[] convert(Object source) {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream(128);
try {
this.serializer.serialize(source, byteStream);
return byteStream.toByteArray();
}
catch (Exception e) {
throw new SerializationFailureException("failed to serialize object", e);
}
}
}

View File

@@ -0,0 +1,6 @@
/**
* Root package for Spring's serializer interfaces and implementations.
* Provides an abstraction over various serialization techniques.
* Includes exceptions for serialization and deserialization failures.
*/
package org.springframework.core.serializer;