HttpMessageNotReadableException provides access to HttpInputMessage
Issue: SPR-15588
This commit is contained in:
parent
fc699b2b37
commit
83faee67d5
|
|
@ -172,7 +172,7 @@ public class BufferedImageHttpMessageConverter implements HttpMessageConverter<B
|
|||
imageInputStream = createImageInputStream(inputMessage.getBody());
|
||||
MediaType contentType = inputMessage.getHeaders().getContentType();
|
||||
if (contentType == null) {
|
||||
throw new HttpMessageNotReadableException("No Content-Type header");
|
||||
throw new HttpMessageNotReadableException("No Content-Type header", inputMessage);
|
||||
}
|
||||
Iterator<ImageReader> imageReaders = ImageIO.getImageReadersByMIMEType(contentType.toString());
|
||||
if (imageReaders.hasNext()) {
|
||||
|
|
@ -184,7 +184,8 @@ public class BufferedImageHttpMessageConverter implements HttpMessageConverter<B
|
|||
}
|
||||
else {
|
||||
throw new HttpMessageNotReadableException(
|
||||
"Could not find javax.imageio.ImageReader for Content-Type [" + contentType + "]");
|
||||
"Could not find javax.imageio.ImageReader for Content-Type [" + contentType + "]",
|
||||
inputMessage);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2018 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.
|
||||
|
|
@ -16,33 +16,79 @@
|
|||
|
||||
package org.springframework.http.converter;
|
||||
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Thrown by {@link HttpMessageConverter} implementations when the
|
||||
* {@link HttpMessageConverter#read} method fails.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class HttpMessageNotReadableException extends HttpMessageConversionException {
|
||||
|
||||
@Nullable
|
||||
private final HttpInputMessage httpInputMessage;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new HttpMessageNotReadableException.
|
||||
* @param msg the detail message
|
||||
* @deprecated as of 5.1, in favor of {@link #HttpMessageNotReadableException(String, HttpInputMessage)}
|
||||
*/
|
||||
@Deprecated
|
||||
public HttpMessageNotReadableException(String msg) {
|
||||
super(msg);
|
||||
this.httpInputMessage = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new HttpMessageNotReadableException.
|
||||
* @param msg the detail message
|
||||
* @param cause the root cause (if any)
|
||||
* @deprecated as of 5.1, in favor of {@link #HttpMessageNotReadableException(String, Throwable, HttpInputMessage)}
|
||||
*/
|
||||
@Deprecated
|
||||
public HttpMessageNotReadableException(String msg, @Nullable Throwable cause) {
|
||||
super(msg, cause);
|
||||
this.httpInputMessage = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new HttpMessageNotReadableException.
|
||||
* @param msg the detail message
|
||||
* @param httpInputMessage the original HTTP message
|
||||
* @since 5.1
|
||||
*/
|
||||
public HttpMessageNotReadableException(String msg, HttpInputMessage httpInputMessage) {
|
||||
super(msg);
|
||||
this.httpInputMessage = httpInputMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new HttpMessageNotReadableException.
|
||||
* @param msg the detail message
|
||||
* @param cause the root cause (if any)
|
||||
* @param httpInputMessage the original HTTP message
|
||||
* @since 5.1
|
||||
*/
|
||||
public HttpMessageNotReadableException(String msg, @Nullable Throwable cause, HttpInputMessage httpInputMessage) {
|
||||
super(msg, cause);
|
||||
this.httpInputMessage = httpInputMessage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the original HTTP message.
|
||||
* @since 5.1
|
||||
*/
|
||||
public HttpInputMessage getHttpInputMessage() {
|
||||
Assert.state(this.httpInputMessage != null, "No HttpInputMessage available - use non-deprecated constructors");
|
||||
return this.httpInputMessage;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,7 +113,8 @@ public class ObjectToStringHttpMessageConverter extends AbstractHttpMessageConve
|
|||
Object result = this.conversionService.convert(value, clazz);
|
||||
if (result == null) {
|
||||
throw new HttpMessageNotReadableException(
|
||||
"Unexpected null conversion result for '" + value + "' to " + clazz);
|
||||
"Unexpected null conversion result for '" + value + "' to " + clazz,
|
||||
inputMessage);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ public class ResourceHttpMessageConverter extends AbstractHttpMessageConverter<R
|
|||
};
|
||||
}
|
||||
else {
|
||||
throw new HttpMessageNotReadableException("Unsupported resource class: " + clazz);
|
||||
throw new HttpMessageNotReadableException("Unsupported resource class: " + clazz, inputMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ public abstract class AbstractWireFeedHttpMessageConverter<T extends WireFeed>
|
|||
return (T) feedInput.build(reader);
|
||||
}
|
||||
catch (FeedException ex) {
|
||||
throw new HttpMessageNotReadableException("Could not read WireFeed: " + ex.getMessage(), ex);
|
||||
throw new HttpMessageNotReadableException("Could not read WireFeed: " + ex.getMessage(), ex, inputMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener
|
|||
throw new HttpMessageConversionException("Type definition error: " + ex.getType(), ex);
|
||||
}
|
||||
catch (JsonProcessingException ex) {
|
||||
throw new HttpMessageNotReadableException("JSON parse error: " + ex.getOriginalMessage(), ex);
|
||||
throw new HttpMessageNotReadableException("JSON parse error: " + ex.getOriginalMessage(), ex, inputMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ public abstract class AbstractJsonHttpMessageConverter extends AbstractGenericHt
|
|||
return readInternal(resolvedType, reader);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new HttpMessageNotReadableException("Could not read JSON: " + ex.getMessage(), ex);
|
||||
throw new HttpMessageNotReadableException("Could not read JSON: " + ex.getMessage(), ex, inputMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -273,12 +273,13 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
|
|||
|
||||
void merge(InputStream input, Charset charset, MediaType contentType,
|
||||
ExtensionRegistry extensionRegistry, Message.Builder builder)
|
||||
throws IOException, HttpMessageNotReadableException;
|
||||
throws IOException, HttpMessageConversionException;
|
||||
|
||||
void print(Message message, OutputStream output, MediaType contentType, Charset charset)
|
||||
throws IOException, HttpMessageNotWritableException;
|
||||
throws IOException, HttpMessageConversionException;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@link ProtobufFormatSupport} implementation used when
|
||||
* {@code com.googlecode.protobuf.format.FormatFactory} is available.
|
||||
|
|
@ -311,7 +312,7 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
|
|||
@Override
|
||||
public void merge(InputStream input, Charset charset, MediaType contentType,
|
||||
ExtensionRegistry extensionRegistry, Message.Builder builder)
|
||||
throws IOException, HttpMessageNotReadableException {
|
||||
throws IOException, HttpMessageConversionException {
|
||||
|
||||
if (contentType.isCompatibleWith(APPLICATION_JSON)) {
|
||||
this.jsonFormatter.merge(input, charset, extensionRegistry, builder);
|
||||
|
|
@ -320,14 +321,14 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
|
|||
this.xmlFormatter.merge(input, charset, extensionRegistry, builder);
|
||||
}
|
||||
else {
|
||||
throw new HttpMessageNotReadableException(
|
||||
throw new HttpMessageConversionException(
|
||||
"protobuf-java-format does not support parsing " + contentType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(Message message, OutputStream output, MediaType contentType, Charset charset)
|
||||
throws IOException, HttpMessageNotWritableException {
|
||||
throws IOException, HttpMessageConversionException {
|
||||
|
||||
if (contentType.isCompatibleWith(APPLICATION_JSON)) {
|
||||
this.jsonFormatter.print(message, output, charset);
|
||||
|
|
@ -339,7 +340,7 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
|
|||
this.htmlFormatter.print(message, output, charset);
|
||||
}
|
||||
else {
|
||||
throw new HttpMessageNotWritableException(
|
||||
throw new HttpMessageConversionException(
|
||||
"protobuf-java-format does not support printing " + contentType);
|
||||
}
|
||||
}
|
||||
|
|
@ -374,21 +375,21 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
|
|||
@Override
|
||||
public void merge(InputStream input, Charset charset, MediaType contentType,
|
||||
ExtensionRegistry extensionRegistry, Message.Builder builder)
|
||||
throws IOException, HttpMessageNotReadableException {
|
||||
throws IOException, HttpMessageConversionException {
|
||||
|
||||
if (contentType.isCompatibleWith(APPLICATION_JSON)) {
|
||||
InputStreamReader reader = new InputStreamReader(input, charset);
|
||||
this.parser.merge(reader, builder);
|
||||
}
|
||||
else {
|
||||
throw new HttpMessageNotReadableException(
|
||||
throw new HttpMessageConversionException(
|
||||
"protobuf-java-util does not support parsing " + contentType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(Message message, OutputStream output, MediaType contentType, Charset charset)
|
||||
throws IOException, HttpMessageNotWritableException {
|
||||
throws IOException, HttpMessageConversionException {
|
||||
|
||||
if (contentType.isCompatibleWith(APPLICATION_JSON)) {
|
||||
OutputStreamWriter writer = new OutputStreamWriter(output, charset);
|
||||
|
|
@ -396,7 +397,7 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
|
|||
writer.flush();
|
||||
}
|
||||
else {
|
||||
throw new HttpMessageNotWritableException(
|
||||
throw new HttpMessageConversionException(
|
||||
"protobuf-java-util does not support printing " + contentType);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import org.springframework.http.HttpInputMessage;
|
|||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.AbstractHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConversionException;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.http.converter.HttpMessageNotWritableException;
|
||||
|
||||
|
|
@ -41,6 +42,7 @@ import org.springframework.http.converter.HttpMessageNotWritableException;
|
|||
* supportedMediaTypes} property.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @param <T> the converted object type
|
||||
*/
|
||||
|
|
@ -62,14 +64,31 @@ public abstract class AbstractXmlHttpMessageConverter<T> extends AbstractHttpMes
|
|||
public final T readInternal(Class<? extends T> clazz, HttpInputMessage inputMessage)
|
||||
throws IOException, HttpMessageNotReadableException {
|
||||
|
||||
return readFromSource(clazz, inputMessage.getHeaders(), new StreamSource(inputMessage.getBody()));
|
||||
try {
|
||||
return readFromSource(clazz, inputMessage.getHeaders(), new StreamSource(inputMessage.getBody()));
|
||||
}
|
||||
catch (IOException | HttpMessageConversionException ex) {
|
||||
throw ex;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new HttpMessageNotReadableException("Could not unmarshal to [" + clazz + "]: " + ex.getMessage(),
|
||||
ex, inputMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void writeInternal(T t, HttpOutputMessage outputMessage)
|
||||
throws IOException, HttpMessageNotWritableException {
|
||||
|
||||
writeToResult(t, outputMessage.getHeaders(), new StreamResult(outputMessage.getBody()));
|
||||
try {
|
||||
writeToResult(t, outputMessage.getHeaders(), new StreamResult(outputMessage.getBody()));
|
||||
}
|
||||
catch (IOException | HttpMessageConversionException ex) {
|
||||
throw ex;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new HttpMessageNotWritableException("Could not marshal [" + t + "]: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -89,21 +108,17 @@ public abstract class AbstractXmlHttpMessageConverter<T> extends AbstractHttpMes
|
|||
* @param headers the HTTP input headers
|
||||
* @param source the HTTP input body
|
||||
* @return the converted object
|
||||
* @throws IOException in case of I/O errors
|
||||
* @throws HttpMessageNotReadableException in case of conversion errors
|
||||
* @throws Exception in case of I/O or conversion errors
|
||||
*/
|
||||
protected abstract T readFromSource(Class<? extends T> clazz, HttpHeaders headers, Source source)
|
||||
throws IOException, HttpMessageNotReadableException;
|
||||
protected abstract T readFromSource(Class<? extends T> clazz, HttpHeaders headers, Source source) throws Exception;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param result the HTTP output body
|
||||
* @throws IOException in case of I/O errors
|
||||
* @throws HttpMessageNotWritableException in case of conversion errors
|
||||
* @throws Exception in case of I/O or conversion errors
|
||||
*/
|
||||
protected abstract void writeToResult(T t, HttpHeaders headers, Result result)
|
||||
throws IOException, HttpMessageNotWritableException;
|
||||
protected abstract void writeToResult(T t, HttpHeaders headers, Result result) throws Exception;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ public class Jaxb2CollectionHttpMessageConverter<T extends Collection>
|
|||
}
|
||||
|
||||
@Override
|
||||
protected T readFromSource(Class<? extends T> clazz, HttpHeaders headers, Source source) throws IOException {
|
||||
protected T readFromSource(Class<? extends T> clazz, HttpHeaders headers, Source source) throws Exception {
|
||||
// should not be called, since we return false for canRead(Class)
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
|
@ -160,18 +160,20 @@ public class Jaxb2CollectionHttpMessageConverter<T extends Collection>
|
|||
}
|
||||
else {
|
||||
// should not happen, since we check in canRead(Type)
|
||||
throw new HttpMessageNotReadableException("Cannot unmarshal to [" + elementClass + "]");
|
||||
throw new HttpMessageNotReadableException(
|
||||
"Cannot unmarshal to [" + elementClass + "]", inputMessage);
|
||||
}
|
||||
event = moveToNextElement(streamReader);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (XMLStreamException ex) {
|
||||
throw new HttpMessageNotReadableException("Failed to read XML stream: " + ex.getMessage(), ex);
|
||||
throw new HttpMessageNotReadableException(
|
||||
"Failed to read XML stream: " + ex.getMessage(), ex, inputMessage);
|
||||
}
|
||||
catch (UnmarshalException ex) {
|
||||
throw new HttpMessageNotReadableException(
|
||||
"Could not unmarshal to [" + elementClass + "]: " + ex.getMessage(), ex);
|
||||
"Could not unmarshal to [" + elementClass + "]: " + ex.getMessage(), ex, inputMessage);
|
||||
}
|
||||
catch (JAXBException ex) {
|
||||
throw new HttpMessageConversionException("Invalid JAXB setup: " + ex.getMessage(), ex);
|
||||
|
|
@ -237,7 +239,7 @@ public class Jaxb2CollectionHttpMessageConverter<T extends Collection>
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void writeToResult(T t, HttpHeaders headers, Result result) throws IOException {
|
||||
protected void writeToResult(T t, HttpHeaders headers, Result result) throws Exception {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package org.springframework.http.converter.xml;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import javax.xml.bind.JAXBElement;
|
||||
import javax.xml.bind.JAXBException;
|
||||
|
|
@ -41,8 +40,6 @@ import org.springframework.core.annotation.AnnotationUtils;
|
|||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.HttpMessageConversionException;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.http.converter.HttpMessageNotWritableException;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
|
|
@ -124,7 +121,7 @@ public class Jaxb2RootElementHttpMessageConverter extends AbstractJaxb2HttpMessa
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Object readFromSource(Class<?> clazz, HttpHeaders headers, Source source) throws IOException {
|
||||
protected Object readFromSource(Class<?> clazz, HttpHeaders headers, Source source) throws Exception {
|
||||
try {
|
||||
source = processSource(source);
|
||||
Unmarshaller unmarshaller = createUnmarshaller(clazz);
|
||||
|
|
@ -138,13 +135,13 @@ public class Jaxb2RootElementHttpMessageConverter extends AbstractJaxb2HttpMessa
|
|||
}
|
||||
catch (NullPointerException ex) {
|
||||
if (!isSupportDtd()) {
|
||||
throw new HttpMessageNotReadableException("NPE while unmarshalling. " +
|
||||
throw new IllegalStateException("NPE while unmarshalling. " +
|
||||
"This can happen due to the presence of DTD declarations which are disabled.", ex);
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
catch (UnmarshalException ex) {
|
||||
throw new HttpMessageNotReadableException("Could not unmarshal to [" + clazz + "]: " + ex.getMessage(), ex);
|
||||
throw ex;
|
||||
}
|
||||
catch (JAXBException ex) {
|
||||
throw new HttpMessageConversionException("Invalid JAXB setup: " + ex.getMessage(), ex);
|
||||
|
|
@ -177,7 +174,7 @@ public class Jaxb2RootElementHttpMessageConverter extends AbstractJaxb2HttpMessa
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void writeToResult(Object o, HttpHeaders headers, Result result) throws IOException {
|
||||
protected void writeToResult(Object o, HttpHeaders headers, Result result) throws Exception {
|
||||
try {
|
||||
Class<?> clazz = ClassUtils.getUserClass(o);
|
||||
Marshaller marshaller = createMarshaller(clazz);
|
||||
|
|
@ -185,7 +182,7 @@ public class Jaxb2RootElementHttpMessageConverter extends AbstractJaxb2HttpMessa
|
|||
marshaller.marshal(o, result);
|
||||
}
|
||||
catch (MarshalException ex) {
|
||||
throw new HttpMessageNotWritableException("Could not marshal [" + o + "]: " + ex.getMessage(), ex);
|
||||
throw ex;
|
||||
}
|
||||
catch (JAXBException ex) {
|
||||
throw new HttpMessageConversionException("Invalid JAXB setup: " + ex.getMessage(), ex);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 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.
|
||||
|
|
@ -16,20 +16,15 @@
|
|||
|
||||
package org.springframework.http.converter.xml;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.xml.transform.Result;
|
||||
import javax.xml.transform.Source;
|
||||
|
||||
import org.springframework.beans.TypeMismatchException;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.http.converter.HttpMessageNotWritableException;
|
||||
import org.springframework.lang.Nullable;
|
||||
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;
|
||||
|
||||
/**
|
||||
|
|
@ -125,28 +120,19 @@ public class MarshallingHttpMessageConverter extends AbstractXmlHttpMessageConve
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Object readFromSource(Class<?> clazz, HttpHeaders headers, Source source) throws IOException {
|
||||
protected Object readFromSource(Class<?> clazz, HttpHeaders headers, Source source) throws Exception {
|
||||
Assert.notNull(this.unmarshaller, "Property 'unmarshaller' is required");
|
||||
try {
|
||||
Object result = this.unmarshaller.unmarshal(source);
|
||||
if (!clazz.isInstance(result)) {
|
||||
throw new TypeMismatchException(result, clazz);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (UnmarshallingFailureException ex) {
|
||||
throw new HttpMessageNotReadableException("Could not read [" + clazz + "]", ex);
|
||||
Object result = this.unmarshaller.unmarshal(source);
|
||||
if (!clazz.isInstance(result)) {
|
||||
throw new TypeMismatchException(result, clazz);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeToResult(Object o, HttpHeaders headers, Result result) throws IOException {
|
||||
protected void writeToResult(Object o, HttpHeaders headers, Result result) throws Exception {
|
||||
Assert.notNull(this.marshaller, "Property 'marshaller' is required");
|
||||
try {
|
||||
this.marshaller.marshal(o, result);
|
||||
}
|
||||
catch (MarshallingFailureException ex) {
|
||||
throw new HttpMessageNotWritableException("Could not write [" + o + "]", ex);
|
||||
}
|
||||
this.marshaller.marshal(o, result);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,24 +147,24 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractHttpMe
|
|||
|
||||
InputStream body = inputMessage.getBody();
|
||||
if (DOMSource.class == clazz) {
|
||||
return (T) readDOMSource(body);
|
||||
return (T) readDOMSource(body, inputMessage);
|
||||
}
|
||||
else if (SAXSource.class == clazz) {
|
||||
return (T) readSAXSource(body);
|
||||
return (T) readSAXSource(body, inputMessage);
|
||||
}
|
||||
else if (StAXSource.class == clazz) {
|
||||
return (T) readStAXSource(body);
|
||||
return (T) readStAXSource(body, inputMessage);
|
||||
}
|
||||
else if (StreamSource.class == clazz || Source.class == clazz) {
|
||||
return (T) readStreamSource(body);
|
||||
}
|
||||
else {
|
||||
throw new HttpMessageNotReadableException("Could not read class [" + clazz +
|
||||
"]. Only DOMSource, SAXSource, StAXSource, and StreamSource are supported.");
|
||||
"]. Only DOMSource, SAXSource, StAXSource, and StreamSource are supported.", inputMessage);
|
||||
}
|
||||
}
|
||||
|
||||
private DOMSource readDOMSource(InputStream body) throws IOException {
|
||||
private DOMSource readDOMSource(InputStream body, HttpInputMessage inputMessage) throws IOException {
|
||||
try {
|
||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||
documentBuilderFactory.setNamespaceAware(true);
|
||||
|
|
@ -181,21 +181,23 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractHttpMe
|
|||
}
|
||||
catch (NullPointerException ex) {
|
||||
if (!isSupportDtd()) {
|
||||
throw new HttpMessageNotReadableException("NPE while unmarshalling: " +
|
||||
"This can happen due to the presence of DTD declarations which are disabled.", ex);
|
||||
throw new HttpMessageNotReadableException("NPE while unmarshalling: This can happen " +
|
||||
"due to the presence of DTD declarations which are disabled.", ex, inputMessage);
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
catch (ParserConfigurationException ex) {
|
||||
throw new HttpMessageNotReadableException("Could not set feature: " + ex.getMessage(), ex);
|
||||
throw new HttpMessageNotReadableException(
|
||||
"Could not set feature: " + ex.getMessage(), ex, inputMessage);
|
||||
}
|
||||
catch (SAXException ex) {
|
||||
throw new HttpMessageNotReadableException("Could not parse document: " + ex.getMessage(), ex);
|
||||
throw new HttpMessageNotReadableException(
|
||||
"Could not parse document: " + ex.getMessage(), ex, inputMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation") // on JDK 9
|
||||
private SAXSource readSAXSource(InputStream body) throws IOException {
|
||||
private SAXSource readSAXSource(InputStream body, HttpInputMessage inputMessage) throws IOException {
|
||||
try {
|
||||
XMLReader xmlReader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();
|
||||
xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
||||
|
|
@ -207,11 +209,12 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractHttpMe
|
|||
return new SAXSource(xmlReader, new InputSource(new ByteArrayInputStream(bytes)));
|
||||
}
|
||||
catch (SAXException ex) {
|
||||
throw new HttpMessageNotReadableException("Could not parse document: " + ex.getMessage(), ex);
|
||||
throw new HttpMessageNotReadableException(
|
||||
"Could not parse document: " + ex.getMessage(), ex, inputMessage);
|
||||
}
|
||||
}
|
||||
|
||||
private Source readStAXSource(InputStream body) {
|
||||
private Source readStAXSource(InputStream body, HttpInputMessage inputMessage) {
|
||||
try {
|
||||
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
|
||||
inputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, isSupportDtd());
|
||||
|
|
@ -223,7 +226,8 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractHttpMe
|
|||
return new StAXSource(streamReader);
|
||||
}
|
||||
catch (XMLStreamException ex) {
|
||||
throw new HttpMessageNotReadableException("Could not parse document: " + ex.getMessage(), ex);
|
||||
throw new HttpMessageNotReadableException(
|
||||
"Could not parse document: " + ex.getMessage(), ex, inputMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2018 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.
|
||||
|
|
@ -87,7 +87,7 @@ public class MarshallingHttpMessageConverterTests {
|
|||
assertEquals("Invalid result", body, result);
|
||||
}
|
||||
|
||||
@Test(expected = TypeMismatchException.class)
|
||||
@Test
|
||||
public void readWithTypeMismatchException() throws Exception {
|
||||
MockHttpInputMessage inputMessage = new MockHttpInputMessage(new byte[0]);
|
||||
|
||||
|
|
@ -96,7 +96,13 @@ public class MarshallingHttpMessageConverterTests {
|
|||
given(unmarshaller.unmarshal(isA(StreamSource.class))).willReturn(Integer.valueOf(3));
|
||||
|
||||
MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter(marshaller, unmarshaller);
|
||||
converter.read(String.class, inputMessage);
|
||||
try {
|
||||
converter.read(String.class, inputMessage);
|
||||
fail("Should have thrown HttpMessageNotReadableException");
|
||||
}
|
||||
catch (HttpMessageNotReadableException ex) {
|
||||
assertTrue(ex.getCause() instanceof TypeMismatchException);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ public abstract class AbstractMessageConverterMethodArgumentResolver implements
|
|||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new HttpMessageNotReadableException("I/O error while reading input message", ex);
|
||||
throw new HttpMessageNotReadableException("I/O error while reading input message", ex, inputMessage);
|
||||
}
|
||||
|
||||
if (body == NO_VALUE) {
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ public class RequestResponseBodyMethodProcessor extends AbstractMessageConverter
|
|||
Object arg = readWithMessageConverters(inputMessage, parameter, paramType);
|
||||
if (arg == null && checkRequired(parameter)) {
|
||||
throw new HttpMessageNotReadableException("Required request body is missing: " +
|
||||
parameter.getExecutable().toGenericString());
|
||||
parameter.getExecutable().toGenericString(), inputMessage);
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue