Browse Source

- Renamed writeToInternal to writeInternal

- Added separate exceptions for reading and writing HttpMessages
conversation
Arjen Poutsma 16 years ago
parent
commit
d14cc0d7a2
  1. 29
      org.springframework.web/src/main/java/org/springframework/http/converter/AbstractHttpMessageConverter.java
  2. 10
      org.springframework.web/src/main/java/org/springframework/http/converter/ByteArrayHttpMessageConverter.java
  3. 7
      org.springframework.web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java
  4. 6
      org.springframework.web/src/main/java/org/springframework/http/converter/HttpMessageConversionException.java
  5. 46
      org.springframework.web/src/main/java/org/springframework/http/converter/HttpMessageNotReadableException.java
  6. 46
      org.springframework.web/src/main/java/org/springframework/http/converter/HttpMessageNotWritableException.java
  7. 7
      org.springframework.web/src/main/java/org/springframework/http/converter/StringHttpMessageConverter.java
  8. 17
      org.springframework.web/src/main/java/org/springframework/http/converter/xml/AbstractXmlHttpMessageConverter.java
  9. 34
      org.springframework.web/src/main/java/org/springframework/http/converter/xml/MarshallingHttpMessageConverter.java
  10. 63
      org.springframework.web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java

29
org.springframework.web/src/main/java/org/springframework/http/converter/AbstractHttpMessageConverter.java

@ -25,10 +25,10 @@ import java.util.List; @@ -25,10 +25,10 @@ import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.util.Assert;
/**
* Abstract base class for most {@link HttpMessageConverter} implementations.
@ -47,32 +47,25 @@ public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConv @@ -47,32 +47,25 @@ public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConv
private List<MediaType> supportedMediaTypes = Collections.emptyList();
/**
* Construct an {@code AbstractHttpMessageConverter} with no supported media types.
*
* @see #setSupportedMediaTypes
*/
protected AbstractHttpMessageConverter() {
}
/**
* Construct an {@code AbstractHttpMessageConverter} with one supported media type.
*/
/** Construct an {@code AbstractHttpMessageConverter} with one supported media type. */
protected AbstractHttpMessageConverter(MediaType supportedMediaType) {
this.supportedMediaTypes = Collections.singletonList(supportedMediaType);
}
/**
* Construct an {@code AbstractHttpMessageConverter} with multiple supported media type.
*/
/** Construct an {@code AbstractHttpMessageConverter} with multiple supported media type. */
protected AbstractHttpMessageConverter(MediaType... supportedMediaTypes) {
this.supportedMediaTypes = Arrays.asList(supportedMediaTypes);
}
/**
* Set the list of {@link MediaType} objects supported by this converter.
*/
/** Set the list of {@link MediaType} objects supported by this converter. */
public void setSupportedMediaTypes(List<MediaType> supportedMediaTypes) {
Assert.notEmpty(supportedMediaTypes, "'supportedMediaTypes' must not be empty");
this.supportedMediaTypes = new ArrayList<MediaType>(supportedMediaTypes);
@ -85,7 +78,8 @@ public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConv @@ -85,7 +78,8 @@ public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConv
/**
* <p>This implementation delegates to {@link #getContentType(Object)} and {@link #getContentLength(Object)},
* and sets the corresponding headers on the output message. It then calls
* {@link #writeToInternal(Object, HttpOutputMessage)}.
* {@link #writeInternal(Object, HttpOutputMessage)}.
*
* @throws HttpMessageConversionException in case of conversion errors
*/
public final void write(T t, HttpOutputMessage outputMessage) throws IOException {
@ -98,7 +92,7 @@ public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConv @@ -98,7 +92,7 @@ public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConv
if (contentLength != null) {
headers.setContentLength(contentLength);
}
writeToInternal(t, outputMessage);
writeInternal(t, outputMessage);
outputMessage.getBody().flush();
}
@ -106,6 +100,7 @@ public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConv @@ -106,6 +100,7 @@ public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConv
* Returns the content type for the given type.
* <p>By default, this returns the first element of the {@link #setSupportedMediaTypes(List) supportedMediaTypes}
* property, if any. Can be overriden in subclasses.
*
* @param t the type to return the content type for
* @return the content type, or <code>null</code> if not known
*/
@ -117,6 +112,7 @@ public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConv @@ -117,6 +112,7 @@ public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConv
/**
* Returns the content length for the given type.
* <p>By default, this returns <code>null</code>. Can be overriden in subclasses.
*
* @param t the type to return the content length for
* @return the content length, or <code>null</code> if not known
*/
@ -126,11 +122,12 @@ public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConv @@ -126,11 +122,12 @@ public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConv
/**
* Abstract template method that writes the actualy body. Invoked from {@link #write(Object, HttpOutputMessage)}.
* @param t the object to write to the output message
*
* @param t the object to write to the output message
* @param outputMessage the message to write to
* @throws IOException in case of I/O errors
* @throws HttpMessageConversionException in case of conversion errors
*/
protected abstract void writeToInternal(T t, HttpOutputMessage outputMessage) throws IOException;
protected abstract void writeInternal(T t, HttpOutputMessage outputMessage) throws IOException;
}

10
org.springframework.web/src/main/java/org/springframework/http/converter/ByteArrayHttpMessageConverter.java

@ -19,10 +19,10 @@ package org.springframework.http.converter; @@ -19,10 +19,10 @@ package org.springframework.http.converter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.springframework.util.FileCopyUtils;
import org.springframework.http.MediaType;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.util.FileCopyUtils;
/**
* Implementation of {@link HttpMessageConverter} that can read and write byte arrays.
@ -37,9 +37,7 @@ import org.springframework.http.HttpOutputMessage; @@ -37,9 +37,7 @@ import org.springframework.http.HttpOutputMessage;
*/
public class ByteArrayHttpMessageConverter extends AbstractHttpMessageConverter<byte[]> {
/**
* Creates a new instance of the {@code ByteArrayHttpMessageConverter}.
*/
/** Creates a new instance of the {@code ByteArrayHttpMessageConverter}. */
public ByteArrayHttpMessageConverter() {
super(MediaType.ALL);
}
@ -71,7 +69,7 @@ public class ByteArrayHttpMessageConverter extends AbstractHttpMessageConverter< @@ -71,7 +69,7 @@ public class ByteArrayHttpMessageConverter extends AbstractHttpMessageConverter<
}
@Override
protected void writeToInternal(byte[] bytes, HttpOutputMessage outputMessage) throws IOException {
protected void writeInternal(byte[] bytes, HttpOutputMessage outputMessage) throws IOException {
FileCopyUtils.copy(bytes, outputMessage.getBody());
}

7
org.springframework.web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java

@ -40,6 +40,7 @@ import org.springframework.util.StringUtils; @@ -40,6 +40,7 @@ import org.springframework.util.StringUtils;
* <p>By default, this converter reads and writes the media type ({@code application/x-www-form-urlencoded}). This
* can be overridden by setting the {@link #setSupportedMediaTypes(java.util.List) supportedMediaTypes} property. Form
* data is read from and written into a {@link MultiValueMap MultiValueMap&lt;String, String&gt;}.
*
* @author Arjen Poutsma
* @see MultiValueMap
* @since 3.0
@ -48,9 +49,7 @@ public class FormHttpMessageConverter extends AbstractHttpMessageConverter<Multi @@ -48,9 +49,7 @@ public class FormHttpMessageConverter extends AbstractHttpMessageConverter<Multi
public static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");
/**
* Creates a new instance of the {@code FormHttpMessageConverter}.
*/
/** Creates a new instance of the {@code FormHttpMessageConverter}. */
public FormHttpMessageConverter() {
super(new MediaType("application", "x-www-form-urlencoded"));
}
@ -84,7 +83,7 @@ public class FormHttpMessageConverter extends AbstractHttpMessageConverter<Multi @@ -84,7 +83,7 @@ public class FormHttpMessageConverter extends AbstractHttpMessageConverter<Multi
}
@Override
protected void writeToInternal(MultiValueMap<String, String> form, HttpOutputMessage outputMessage)
protected void writeInternal(MultiValueMap<String, String> form, HttpOutputMessage outputMessage)
throws IOException {
MediaType contentType = getContentType(form);
Charset charset = contentType.getCharSet() != null ? contentType.getCharSet() : DEFAULT_CHARSET;

6
org.springframework.web/src/main/java/org/springframework/http/converter/HttpMessageConversionException.java

@ -27,7 +27,8 @@ import org.springframework.core.NestedRuntimeException; @@ -27,7 +27,8 @@ import org.springframework.core.NestedRuntimeException;
public class HttpMessageConversionException extends NestedRuntimeException {
/**
* Create a new MessageConversionException.
* Create a new HttpMessageConversionException.
*
* @param msg the detail message
*/
public HttpMessageConversionException(String msg) {
@ -35,7 +36,8 @@ public class HttpMessageConversionException extends NestedRuntimeException { @@ -35,7 +36,8 @@ public class HttpMessageConversionException extends NestedRuntimeException {
}
/**
* Create a new MessageConversionException.
* Create a new HttpMessageConversionException.
*
* @param msg the detail message
* @param cause the root cause (if any)
*/

46
org.springframework.web/src/main/java/org/springframework/http/converter/HttpMessageNotReadableException.java

@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
/*
* Copyright 2002-2009 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.http.converter;
/**
* Thrown by {@link HttpMessageConverter} implementations when the
* {@link HttpMessageConverter#read(Class, org.springframework.http.HttpInputMessage) read} method fails.
*
* @author Arjen Poutsma
* @since 3.0
*/
public class HttpMessageNotReadableException extends HttpMessageConversionException {
/**
* Create a new HttpMessageNotReadableException.
*
* @param msg the detail message
*/
public HttpMessageNotReadableException(String msg) {
super(msg);
}
/**
* Create a new HttpMessageNotReadableException.
*
* @param msg the detail message
* @param cause the root cause (if any)
*/
public HttpMessageNotReadableException(String msg, Throwable cause) {
super(msg, cause);
}
}

46
org.springframework.web/src/main/java/org/springframework/http/converter/HttpMessageNotWritableException.java

@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
/*
* Copyright 2002-2009 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.http.converter;
/**
* Thrown by {@link org.springframework.http.converter.HttpMessageConverter} implementations when the
* {@link org.springframework.http.converter.HttpMessageConverter#write(Object, org.springframework.http.HttpOutputMessage) write} method fails.
*
* @author Arjen Poutsma
* @since 3.0
*/
public class HttpMessageNotWritableException extends HttpMessageConversionException {
/**
* Create a new HttpMessageNotWritableException.
*
* @param msg the detail message
*/
public HttpMessageNotWritableException(String msg) {
super(msg);
}
/**
* Create a new HttpMessageNotWritableException.
*
* @param msg the detail message
* @param cause the root cause (if any)
*/
public HttpMessageNotWritableException(String msg, Throwable cause) {
super(msg, cause);
}
}

7
org.springframework.web/src/main/java/org/springframework/http/converter/StringHttpMessageConverter.java

@ -24,10 +24,10 @@ import java.nio.charset.Charset; @@ -24,10 +24,10 @@ import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import org.springframework.util.FileCopyUtils;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.util.FileCopyUtils;
/**
* Implementation of {@link HttpMessageConverter} that can read and write strings.
@ -45,13 +45,11 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str @@ -45,13 +45,11 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str
private final List<Charset> availableCharsets;
public StringHttpMessageConverter() {
super(new MediaType("text", "plain", DEFAULT_CHARSET), new MediaType("text", "*"));
this.availableCharsets = new ArrayList<Charset>(Charset.availableCharsets().values());
}
public boolean supports(Class<? extends String> clazz) {
return String.class.equals(clazz);
}
@ -80,7 +78,7 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str @@ -80,7 +78,7 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str
}
@Override
protected void writeToInternal(String s, HttpOutputMessage outputMessage) throws IOException {
protected void writeInternal(String s, HttpOutputMessage outputMessage) throws IOException {
outputMessage.getHeaders().setAcceptCharset(getAcceptedCharsets());
MediaType contentType = getContentType(s);
Charset charset = contentType.getCharSet() != null ? contentType.getCharSet() : DEFAULT_CHARSET;
@ -90,6 +88,7 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str @@ -90,6 +88,7 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str
/**
* Return the list of supported {@link Charset}.
* <p>By default, returns {@link Charset#availableCharsets()}. Can be overridden in subclasses.
*
* @return the list of accepted charsets
*/
protected List<Charset> getAcceptedCharsets() {

17
org.springframework.web/src/main/java/org/springframework/http/converter/xml/AbstractXmlHttpMessageConverter.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2008 the original author or authors.
* Copyright 2002-2009 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.
@ -72,12 +72,12 @@ public abstract class AbstractXmlHttpMessageConverter<T> extends AbstractHttpMes @@ -72,12 +72,12 @@ public abstract class AbstractXmlHttpMessageConverter<T> extends AbstractHttpMes
protected abstract T readFromSource(Class<T> clazz, HttpHeaders headers, Source source) throws IOException;
@Override
protected final void writeToInternal(T t, HttpOutputMessage outputMessage) throws IOException {
protected final void writeInternal(T t, HttpOutputMessage outputMessage) throws IOException {
writeToResult(t, outputMessage.getHeaders(), new StreamResult(outputMessage.getBody()));
}
/**
* Abstract template method called from {@link #writeToInternal(Object, HttpOutputMessage)}.
* Abstract template method called from {@link #writeInternal(Object, HttpOutputMessage)}.
*
* @param t the object to write to the output message
* @param headers the HTTP output headers
@ -94,14 +94,9 @@ public abstract class AbstractXmlHttpMessageConverter<T> extends AbstractHttpMes @@ -94,14 +94,9 @@ public abstract class AbstractXmlHttpMessageConverter<T> extends AbstractHttpMes
* @param result the result to transform to
* @throws HttpMessageConversionException in case of transformation errors
*/
protected void transform(Source source, Result result) {
try {
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(source, result);
}
catch (TransformerException ex) {
throw new HttpMessageConversionException("Could not transform XML", ex);
}
protected void transform(Source source, Result result) throws TransformerException {
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(source, result);
}
}

34
org.springframework.web/src/main/java/org/springframework/http/converter/xml/MarshallingHttpMessageConverter.java

@ -1,3 +1,19 @@ @@ -1,3 +1,19 @@
/*
* Copyright 2002-2009 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.http.converter.xml;
import java.io.IOException;
@ -6,8 +22,12 @@ import javax.xml.transform.Source; @@ -6,8 +22,12 @@ import javax.xml.transform.Source;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.http.HttpHeaders;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.MarshallingFailureException;
import org.springframework.oxm.Unmarshaller;
import org.springframework.oxm.UnmarshallingFailureException;
import org.springframework.util.Assert;
/**
@ -98,11 +118,21 @@ public class MarshallingHttpMessageConverter extends AbstractXmlHttpMessageConve @@ -98,11 +118,21 @@ public class MarshallingHttpMessageConverter extends AbstractXmlHttpMessageConve
@Override
protected Object readFromSource(Class<Object> clazz, HttpHeaders headers, Source source) throws IOException {
return unmarshaller.unmarshal(source);
try {
return unmarshaller.unmarshal(source);
}
catch (UnmarshallingFailureException ex) {
throw new HttpMessageNotReadableException("Could not read [" + clazz + "]", ex);
}
}
@Override
protected void writeToResult(Object o, HttpHeaders headers, Result result) throws IOException {
marshaller.marshal(o, result);
try {
marshaller.marshal(o, result);
}
catch (MarshallingFailureException ex) {
throw new HttpMessageNotWritableException("Could not write [" + o + "]", ex);
}
}
}

63
org.springframework.web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java

@ -1,3 +1,19 @@ @@ -1,3 +1,19 @@
/*
* Copyright 2002-2009 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.http.converter.xml;
import java.io.ByteArrayInputStream;
@ -5,6 +21,7 @@ import java.io.ByteArrayOutputStream; @@ -5,6 +21,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
@ -15,6 +32,8 @@ import org.xml.sax.InputSource; @@ -15,6 +32,8 @@ import org.xml.sax.InputSource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
/** @author Arjen Poutsma */
public class SourceHttpMessageConverter<T extends Source> extends AbstractXmlHttpMessageConverter<T> {
@ -26,26 +45,31 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractXmlHtt @@ -26,26 +45,31 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractXmlHtt
@Override
@SuppressWarnings("unchecked")
protected T readFromSource(Class<T> clazz, HttpHeaders headers, Source source) throws IOException {
if (DOMSource.class.equals(clazz)) {
DOMResult domResult = new DOMResult();
transform(source, domResult);
return (T) new DOMSource(domResult.getNode());
}
else if (SAXSource.class.equals(clazz)) {
ByteArrayInputStream bis = transformToByteArray(source);
return (T) new SAXSource(new InputSource(bis));
}
else if (StreamSource.class.equals(clazz) || Source.class.equals(clazz)) {
ByteArrayInputStream bis = transformToByteArray(source);
return (T) new StreamSource(bis);
try {
if (DOMSource.class.equals(clazz)) {
DOMResult domResult = new DOMResult();
transform(source, domResult);
return (T) new DOMSource(domResult.getNode());
}
else if (SAXSource.class.equals(clazz)) {
ByteArrayInputStream bis = transformToByteArray(source);
return (T) new SAXSource(new InputSource(bis));
}
else if (StreamSource.class.equals(clazz) || Source.class.equals(clazz)) {
ByteArrayInputStream bis = transformToByteArray(source);
return (T) new StreamSource(bis);
}
else {
throw new HttpMessageConversionException("Could not read class [" + clazz +
"]. Only DOMSource, SAXSource, and StreamSource are supported.");
}
}
else {
throw new HttpMessageConversionException(
"Could not read class [" + clazz + "]. Only DOMSource, SAXSource, and StreamSource are supported.");
catch (TransformerException ex) {
throw new HttpMessageNotReadableException("Could not transform from [" + source + "]", ex);
}
}
private ByteArrayInputStream transformToByteArray(Source source) {
private ByteArrayInputStream transformToByteArray(Source source) throws TransformerException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
transform(source, new StreamResult(bos));
return new ByteArrayInputStream(bos.toByteArray());
@ -53,6 +77,11 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractXmlHtt @@ -53,6 +77,11 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractXmlHtt
@Override
protected void writeToResult(T t, HttpHeaders headers, Result result) throws IOException {
transform(t, result);
try {
transform(t, result);
}
catch (TransformerException ex) {
throw new HttpMessageNotWritableException("Could not transform [" + t + "] to [" + result + "]", ex);
}
}
}

Loading…
Cancel
Save