diff --git a/jaxrs/resteasy-jaxrs/src/main/java/org/jboss/resteasy/core/MessageBodyParameterInjector.java b/jaxrs/resteasy-jaxrs/src/main/java/org/jboss/resteasy/core/MessageBodyParameterInjector.java index 1e53035..7f2ce3d 100644 --- a/jaxrs/resteasy-jaxrs/src/main/java/org/jboss/resteasy/core/MessageBodyParameterInjector.java +++ b/jaxrs/resteasy-jaxrs/src/main/java/org/jboss/resteasy/core/MessageBodyParameterInjector.java @@ -25,6 +25,8 @@ import java.lang.annotation.Annotation; import java.lang.reflect.AccessibleObject; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.util.List; +import java.util.Set; /** * @author Bill Burke @@ -120,91 +122,116 @@ public class MessageBodyParameterInjector implements ValueInjector, JaxrsInterce return params.getActualTypeArguments()[0].equals(String.class) && params.getActualTypeArguments()[1].equals(String.class); } + public static boolean isFormData(Object obj) { + if (obj == null) + return false; + + if (!MultivaluedMap.class.isAssignableFrom(obj.getClass())) + return false; + + Set keys = ((MultivaluedMap) obj).keySet(); + + if (keys.size() < 1) { + return false; // empty form data is considered illegal + } + + for (Object key : keys) { + if (!String.class.isAssignableFrom(key.getClass())) + return false; + Object values = ((MultivaluedMap) obj).get(key); + if (values != null) { + if (!List.class.isAssignableFrom(values.getClass())) + return false; + for (Object value : (List) values) { + if (value != null && !String.class.isAssignableFrom(value.getClass())) + return false; + } + } + } + + return true; + } + + + public Object inject(HttpRequest request, HttpResponse response) { + Object o = getBody(); + if (o != null) { + return o; + } + MediaType mediaType = request.getHttpHeaders().getMediaType(); + if (mediaType == null) { + mediaType = MediaType.WILDCARD_TYPE; + //throw new BadRequestException("content-type was null and expecting to extract a body into " + this.target); + } + + // We have to do this isFormData() hack because of servlets and servlet filters + // A filter that does getParameter() will screw up the input stream which will screw up the + // provider. We do it here rather than hack the provider as the provider is reused for client side + // and also, the server may be using the client framework to make another remote call. + MultivaluedMap origFormData = null; + boolean paramIsFormData = isFormData(type, genericType, annotations, mediaType); + if (paramIsFormData) { + boolean encoded = FindAnnotation.findAnnotation(annotations, Encoded.class) != null; + if (encoded) { + origFormData = request.getFormParameters(); + } else { + origFormData = request.getDecodedFormParameters(); + } + } - public Object inject(HttpRequest request, HttpResponse response) - { - Object o = getBody(); - if (o != null) - { - return o; - } - MediaType mediaType = request.getHttpHeaders().getMediaType(); - if (mediaType == null) - { - mediaType = MediaType.WILDCARD_TYPE; - //throw new BadRequestException("content-type was null and expecting to extract a body into " + this.target); - } - - // We have to do this isFormData() hack because of servlets and servlet filters - // A filter that does getParameter() will screw up the input stream which will screw up the - // provider. We do it here rather than hack the provider as the provider is reused for client side - // and also, the server may be using the client framework to make another remote call. - if (isFormData(type, genericType, annotations, mediaType)) - { - boolean encoded = FindAnnotation.findAnnotation(annotations, Encoded.class) != null; - if (encoded) return request.getFormParameters(); - else return request.getDecodedFormParameters(); - } - else - { - MessageBodyReader reader = factory.getMessageBodyReader(type, - genericType, annotations, mediaType); - if (reader == null) - { + MessageBodyReader reader = factory.getMessageBodyReader(type, + genericType, annotations, mediaType); + if (reader == null) { throw new BadRequestException( "Could not find message body reader for type: " + genericType + " of content type: " + mediaType); - } + } - try - { + try { InputStream is = request.getInputStream(); - if (isMarshalledEntity) - { - is = new InputStreamToByteArray(is); + if (isMarshalledEntity) { + is = new InputStreamToByteArray(is); } AbstractReaderInterceptorContext messageBodyReaderContext = new ServerReaderInterceptorContext(interceptors, reader, type, genericType, annotations, mediaType, request .getHttpHeaders().getRequestHeaders(), is, request); final Object obj = messageBodyReaderContext.proceed(); - if (isMarshalledEntity) - { - InputStreamToByteArray isba = (InputStreamToByteArray) is; - final byte[] bytes = isba.toByteArray(); - return new MarshalledEntity() - { - @Override - public byte[] getMarshalledBytes() - { - return bytes; - } - - @Override - public Object getEntity() - { - return obj; - } - }; - } - else - { - return obj; - } - } - catch (Exception e) - { - if (e instanceof ReaderException) - { - throw (ReaderException) e; + + if (paramIsFormData) { + if (isFormData(obj)) { // give user a chance to process form data in their message body reader + return obj; + } else { + return origFormData; + } + } else { + if (isMarshalledEntity) { + InputStreamToByteArray isba = (InputStreamToByteArray) is; + final byte[] bytes = isba.toByteArray(); + return new MarshalledEntity() { + @Override + public byte[] getMarshalledBytes() { + return bytes; + } + + @Override + public Object getEntity() { + return obj; + } + }; + } else { + return obj; + } } - else - { - throw new ReaderException(e); + } catch (Exception e) { + if (e instanceof ReaderException) { + throw (ReaderException) e; + } else { + throw new ReaderException(e); } - } - } - } + } + + } public Object inject() {