You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2009/02/02 11:34:14 UTC
svn commit: r739958 - in /cxf/branches/2.1.x-fixes: ./
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ rt/fronte...
Author: sergeyb
Date: Mon Feb 2 10:34:13 2009
New Revision: 739958
URL: http://svn.apache.org/viewvc?rev=739958&view=rev
Log:
Merged revisions 739366 via svnmerge from
https://svn.apache.org/repos/asf/cxf/trunk
........
r739366 | sergeyb | 2009-01-30 18:23:52 +0000 (Fri, 30 Jan 2009) | 1 line
JAXRS: support for multipart/form-data
........
Added:
cxf/branches/2.1.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/attachmentForm
- copied unchanged from r739366, cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/attachmentForm
Modified:
cxf/branches/2.1.x-fixes/ (props changed)
cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java
cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java
cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Attachment.java
cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBody.java
cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java
cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/AttachmentInputInterceptor.java
cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ActivationProvider.java
cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProvider.java
cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java
cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java
cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBodyTest.java
cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProviderTest.java
cxf/branches/2.1.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java
cxf/branches/2.1.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java
Propchange: cxf/branches/2.1.x-fixes/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Feb 2 10:34:13 2009
@@ -1 +1 @@
-/cxf/trunk:686333-686363,686764,686820,687096,687194,687363,687387,687463,687543,687722,687798,687814,687817,687891,687910,687914,688086,688102,688133,688596,688735,688870,689572,689596,689855,689924,690067,690289,691246,691271,691295,691338,691355,691488,691602,691646,691706,691728,692116,692157,692310,692466,692499,693653,693819,694179,694263,694417,694716,694744,694747,694795,694869,694981,694987,694993,695041,695096,695396,695484,695537,695552,695561,695619,695684,695835,695840,695868,695935,695977,696016,696094,696433,696720,697085,697868,698128,699289,700261,700507,700602,700981,701316,701783,701830,701862,702187,702205-702248,702267,702547,702561,702580,702602,702609,702616,702653,702656,702957,703191,703239,703309,703501,703513,703548,704584,704937,704997,705150,705235,705274,705340,705446,705548,705614,705692,705708,706482,706631,706675,706900,706909,707034,707089,707100,707902,708035,708044,708074,708410,708417,708550,708554,709353-709354,709425,710076,710150,71015
4,711193,711388,711410,711490,711635,711949,711975,712194,712198,712238,712272,712299,712312,712670,712893,713082,713095-713096,713099,713584,713597,713737,713804,713899,714167-714168,714245,714255,717937-717961,718281-718448,718565,718620,718640,718665,718970,719017,719210,719215-719218,719222-719273,719305,719327-719680,720053,720119-720218,720238,720293-720316,720497,721221,721241,721501,722117,722129,722412,722988,723024,723338,723378,723716-723791,724333-724372,724433-724438,724449,724481,724485,724668,724780,724782,724785,724793,724795,724940,725071,725316,725332,725335,725348,725364,725418,725425-725426,725455,725506,725554,725562,725651,725671,725688,725754,725773,725799,725839,726342,726524,726631,726634,726637,726639,726692,726724,726769,726992,727096,727445,727521,727568,727692,727754,727781,727792,728070,728087,728696,728897,729051,729430,729449,729460,729863,730082,730139,730889,730891,731598,731604,731615,731631,731635,732036,732050,732320,732363,732411,732450,
732710,732773,732827,732829,733512,733582,733901,734367,734462,734666,734762,734772,734812,734836,734965,735113,735252,735722-735723,735729,735734,735751,735782,735787,735987,736332,736343,736352,736358-736362,736408,736423,736448,736491,736621,736726,736736,736738-736739,736766,736825,736852,737032,737046,737061,737069,737124,737237,737246,737299,737356,737494,737498,737761,737817,737849,737855,737994,738166,738178,738201,738210,738242,738244,738265,738516,738583,738863,738937,738983,739367,739451-739452,739799-739800,739867,739876-739877,739922
+/cxf/trunk:686333-686363,686764,686820,687096,687194,687363,687387,687463,687543,687722,687798,687814,687817,687891,687910,687914,688086,688102,688133,688596,688735,688870,689572,689596,689855,689924,690067,690289,691246,691271,691295,691338,691355,691488,691602,691646,691706,691728,692116,692157,692310,692466,692499,693653,693819,694179,694263,694417,694716,694744,694747,694795,694869,694981,694987,694993,695041,695096,695396,695484,695537,695552,695561,695619,695684,695835,695840,695868,695935,695977,696016,696094,696433,696720,697085,697868,698128,699289,700261,700507,700602,700981,701316,701783,701830,701862,702187,702205-702248,702267,702547,702561,702580,702602,702609,702616,702653,702656,702957,703191,703239,703309,703501,703513,703548,704584,704937,704997,705150,705235,705274,705340,705446,705548,705614,705692,705708,706482,706631,706675,706900,706909,707034,707089,707100,707902,708035,708044,708074,708410,708417,708550,708554,709353-709354,709425,710076,710150,71015
4,711193,711388,711410,711490,711635,711949,711975,712194,712198,712238,712272,712299,712312,712670,712893,713082,713095-713096,713099,713584,713597,713737,713804,713899,714167-714168,714245,714255,717937-717961,718281-718448,718565,718620,718640,718665,718970,719017,719210,719215-719218,719222-719273,719305,719327-719680,720053,720119-720218,720238,720293-720316,720497,721221,721241,721501,722117,722129,722412,722988,723024,723338,723378,723716-723791,724333-724372,724433-724438,724449,724481,724485,724668,724780,724782,724785,724793,724795,724940,725071,725316,725332,725335,725348,725364,725418,725425-725426,725455,725506,725554,725562,725651,725671,725688,725754,725773,725799,725839,726342,726524,726631,726634,726637,726639,726692,726724,726769,726992,727096,727445,727521,727568,727692,727754,727781,727792,728070,728087,728696,728897,729051,729430,729449,729460,729863,730082,730139,730889,730891,731598,731604,731615,731631,731635,732036,732050,732320,732363,732411,732450,
732710,732773,732827,732829,733512,733582,733901,734367,734462,734666,734762,734772,734812,734836,734965,735113,735252,735722-735723,735729,735734,735751,735782,735787,735987,736332,736343,736352,736358-736362,736408,736423,736448,736491,736621,736726,736736,736738-736739,736766,736825,736852,737032,737046,737061,737069,737124,737237,737246,737299,737356,737494,737498,737761,737817,737849,737855,737994,738166,738178,738201,738210,738242,738244,738265,738516,738583,738863,738937,738983,739366-739367,739451-739452,739799-739800,739867,739876-739877,739922
Propchange: cxf/branches/2.1.x-fixes/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.
Modified: cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java?rev=739958&r1=739957&r2=739958&view=diff
==============================================================================
--- cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java (original)
+++ cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java Mon Feb 2 10:34:13 2009
@@ -36,7 +36,7 @@
public interface MessageContext {
Object get(Object key);
- void put(Object key, Object value);
+ void put(Object key, Object value, boolean outbound);
UriInfo getUriInfo();
Request getRequest();
Modified: cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java?rev=739958&r1=739957&r2=739958&view=diff
==============================================================================
--- cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java (original)
+++ cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java Mon Feb 2 10:34:13 2009
@@ -112,8 +112,12 @@
return JAXRSUtils.createServletResourceValue(m, ServletContext.class);
}
- public void put(Object key, Object value) {
- throw new UnsupportedOperationException("MessageContext.put() is not supported yet");
+ public void put(Object key, Object value, boolean outbound) {
+ if (outbound) {
+ throw new UnsupportedOperationException(
+ "MessageContext.put() is not supported for outbound properties");
+ }
+ m.put(key.toString(), value);
}
private MultipartBody createAttachments(String propertyName) {
Modified: cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Attachment.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Attachment.java?rev=739958&r1=739957&r2=739958&view=diff
==============================================================================
--- cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Attachment.java (original)
+++ cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Attachment.java Mon Feb 2 10:34:13 2009
@@ -61,7 +61,8 @@
}
public ContentDisposition getContentDisposition() {
- String header = headers.getFirst("Content-Disposition");
+ String header = getHeader("Content-Disposition");
+
return header == null ? null : new ContentDisposition(header);
}
@@ -79,11 +80,13 @@
}
public String getHeader(String name) {
- return headers.getFirst(name);
+ String header = headers.getFirst(name);
+ return header == null ? headers.getFirst(name.toLowerCase()) : header;
}
public List<String> getHeaderAsList(String name) {
- return headers.get(name);
+ List<String> header = headers.get(name);
+ return header == null ? headers.get(name.toLowerCase()) : header;
}
public MultivaluedMap<String, String> getHeaders() {
Modified: cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBody.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBody.java?rev=739958&r1=739957&r2=739958&view=diff
==============================================================================
--- cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBody.java (original)
+++ cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBody.java Mon Feb 2 10:34:13 2009
@@ -73,5 +73,12 @@
return atts.size() > 0 ? atts.get(0) : null;
}
-
+ public Attachment getAttachment(String contentId) {
+ for (Attachment a : atts) {
+ if (contentId.equalsIgnoreCase(a.getContentId())) {
+ return a;
+ }
+ }
+ return null;
+ }
}
Modified: cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java?rev=739958&r1=739957&r2=739958&view=diff
==============================================================================
--- cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java (original)
+++ cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java Mon Feb 2 10:34:13 2009
@@ -78,9 +78,9 @@
return get() != null ? get().getRequest() : null;
}
- public void put(Object key, Object value) {
+ public void put(Object key, Object value, boolean outbound) {
if (get() != null) {
- get().put(key, value);
+ get().put(key, value, outbound);
}
throw new IllegalStateException("MessageContext is not set");
Modified: cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/AttachmentInputInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/AttachmentInputInterceptor.java?rev=739958&r1=739957&r2=739958&view=diff
==============================================================================
--- cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/AttachmentInputInterceptor.java (original)
+++ cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/AttachmentInputInterceptor.java Mon Feb 2 10:34:13 2009
@@ -29,7 +29,10 @@
public class AttachmentInputInterceptor extends AttachmentInInterceptor {
private static final List<String> DEFAULT_TYPES =
- Arrays.asList(new String[]{"multipart/related", "multipart/mixed"});
+ Arrays.asList(new String[]{"multipart/related",
+ "multipart/mixed",
+ "multipart/alternative",
+ "multipart/form-data"});
private List<String> types = DEFAULT_TYPES;
Modified: cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ActivationProvider.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ActivationProvider.java?rev=739958&r1=739957&r2=739958&view=diff
==============================================================================
--- cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ActivationProvider.java (original)
+++ cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ActivationProvider.java Mon Feb 2 10:34:13 2009
@@ -38,31 +38,33 @@
import org.apache.cxf.jaxrs.ext.MessageContext;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
+import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
import org.apache.cxf.jaxrs.utils.InjectionUtils;
import org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils;
@Provider
-@ConsumeMime({"multipart/related", "multipart/mixed" })
+@ConsumeMime({"multipart/related", "multipart/mixed", "multipart/alternative" })
public class ActivationProvider implements MessageBodyReader<Object> {
@Context
private MessageContext mc;
+ private String attachmentDir;
+ private String attachmentThreshold;
+
+ public void setAttachmentDirectory(String dir) {
+ attachmentDir = dir;
+ }
+
+ public void setAttachmentThreshold(String threshold) {
+ attachmentThreshold = threshold;
+ }
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations) {
-
if (DataHandler.class.isAssignableFrom(type) || DataSource.class.isAssignableFrom(type)
- || Attachment.class.isAssignableFrom(type)) {
+ || Attachment.class.isAssignableFrom(type) || MultipartBody.class.isAssignableFrom(type)
+ || mediaTypeSupported()) {
return true;
}
- if (mc == null) {
- return false;
- }
- MediaType mt = mc.getHttpHeaders().getMediaType();
- if (mt.getType().equals("multipart")
- && (mt.getSubtype().equals("related") || mt.getSubtype().equals("mixed"))) {
- return true;
- }
-
return false;
}
@@ -70,9 +72,11 @@
MultivaluedMap<String, String> headers, InputStream is)
throws IOException, WebApplicationException {
+ List<Attachment> infos =
+ AttachmentUtils.getAttachments(mc, attachmentDir, attachmentThreshold);
+
if (List.class.isAssignableFrom(c)) {
Class<?> actual = InjectionUtils.getActualType(t);
- List<Attachment> infos = AttachmentUtils.getAttachments(mc);
if (actual.isAssignableFrom(Attachment.class)) {
return infos;
}
@@ -82,8 +86,11 @@
}
return objects;
}
+ if (MultipartBody.class.isAssignableFrom(c)) {
+ return new MultipartBody(infos);
+ }
- Attachment multipart = AttachmentUtils.getMultipart(c, anns, mt, mc);
+ Attachment multipart = AttachmentUtils.getMultipart(c, anns, mt, infos);
if (multipart != null) {
return fromAttachment(multipart, c, t, anns);
}
@@ -109,4 +116,15 @@
}
return null;
}
+
+ private boolean mediaTypeSupported() {
+
+ if (mc == null) {
+ return false;
+ }
+ MediaType mt = mc.getHttpHeaders().getMediaType();
+
+ return mt.getType().equals("multipart") && (mt.getSubtype().equals("related")
+ || mt.getSubtype().equals("mixed") || mt.getSubtype().equals("alternative"));
+ }
}
Modified: cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProvider.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProvider.java?rev=739958&r1=739957&r2=739958&view=diff
==============================================================================
--- cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProvider.java (original)
+++ cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProvider.java Mon Feb 2 10:34:13 2009
@@ -27,20 +27,37 @@
import javax.ws.rs.ConsumeMime;
import javax.ws.rs.Encoded;
import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
import org.apache.cxf.jaxrs.impl.MetadataMap;
import org.apache.cxf.jaxrs.utils.AnnotationUtils;
import org.apache.cxf.jaxrs.utils.FormUtils;
+import org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils;
-@ConsumeMime("application/x-www-form-urlencoded")
+@ConsumeMime({"application/x-www-form-urlencoded", "multipart/form-data" })
@Provider
public class FormEncodingReaderProvider implements MessageBodyReader<Object> {
-
+
+ private static final MediaType MULTIPART_FORM_DATA = MediaType.valueOf("multipart/form-data");
+
private FormValidator validator;
+ @Context private MessageContext mc;
+ private String attachmentDir;
+ private String attachmentThreshold;
+
+ public void setAttachmentDirectory(String dir) {
+ attachmentDir = dir;
+ }
+
+ public void setAttachmentThreshold(String threshold) {
+ attachmentThreshold = threshold;
+ }
public void setValidator(FormValidator formValidator) {
validator = formValidator;
@@ -48,17 +65,22 @@
public boolean isReadable(Class<?> type, Type genericType,
Annotation[] annotations) {
- return MultivaluedMap.class.isAssignableFrom(type);
+ return MultivaluedMap.class.isAssignableFrom(type)
+ || mediaTypeSupported() && MultipartBody.class.isAssignableFrom(type);
}
- public MultivaluedMap<String, String> readFrom(
+ public Object readFrom(
Class<Object> clazz, Type genericType, Annotation[] annotations, MediaType type,
MultivaluedMap<String, String> headers, InputStream is)
throws IOException {
try {
-
+
+ if (MultipartBody.class.isAssignableFrom(clazz)) {
+ return AttachmentUtils.getMultipartBody(mc);
+ }
+
MultivaluedMap<String, String> params = createMap(clazz);
- populateMap(params, is,
+ populateMap(params, is, type,
AnnotationUtils.getAnnotation(annotations, Encoded.class) == null);
validateMap(params);
return params;
@@ -84,9 +106,14 @@
* @return a Map of parameters.
*/
protected void populateMap(MultivaluedMap<String, String> params,
- InputStream is,
- boolean decode) {
- FormUtils.populateMap(params, FormUtils.readBody(is), decode);
+ InputStream is, MediaType mt, boolean decode) {
+ if (mt.isCompatible(MULTIPART_FORM_DATA)) {
+ MultipartBody body =
+ AttachmentUtils.getMultipartBody(mc, attachmentDir, attachmentThreshold);
+ FormUtils.populateMapFromMultipart(params, body, decode);
+ } else {
+ FormUtils.populateMapFromString(params, FormUtils.readBody(is), decode);
+ }
}
protected void validateMap(MultivaluedMap<String, String> params) {
@@ -94,4 +121,14 @@
validator.validate(params);
}
}
+
+ private boolean mediaTypeSupported() {
+
+ if (mc == null) {
+ return false;
+ }
+ MediaType mt = mc.getHttpHeaders().getMediaType();
+
+ return mt.isCompatible(MULTIPART_FORM_DATA);
+ }
}
Modified: cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java?rev=739958&r1=739957&r2=739958&view=diff
==============================================================================
--- cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java (original)
+++ cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java Mon Feb 2 10:34:13 2009
@@ -20,6 +20,7 @@
package org.apache.cxf.jaxrs.utils;
import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
@@ -29,9 +30,14 @@
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.jaxrs.ext.multipart.Attachment;
+import org.apache.cxf.jaxrs.ext.multipart.ContentDisposition;
+import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
public final class FormUtils {
+ private static final String FORM_DATA_TYPE = "form-data";
+
private FormUtils() {
}
@@ -46,8 +52,8 @@
}
}
- public static void populateMap(MultivaluedMap<String, String> params,
- String postBody, boolean decode) {
+ public static void populateMapFromString(MultivaluedMap<String, String> params,
+ String postBody, boolean decode) {
if (!StringUtils.isEmpty(postBody)) {
List<String> parts = Arrays.asList(postBody.split("&"));
for (String part : parts) {
@@ -66,4 +72,24 @@
}
}
}
+
+ public static void populateMapFromMultipart(MultivaluedMap<String, String> params,
+ MultipartBody body,
+ boolean decode) {
+ List<Attachment> atts = body.getAllAttachments();
+ for (Attachment a : atts) {
+ ContentDisposition cd = a.getContentDisposition();
+ if (cd == null || !FORM_DATA_TYPE.equalsIgnoreCase(cd.getType())
+ || cd.getParameter("name") == null) {
+ throw new WebApplicationException(415);
+ }
+ String name = cd.getParameter("name").replace("\"", "").replace("'", "");
+ try {
+ String value = IOUtils.toString(a.getDataHandler().getInputStream());
+ params.add(name, decode ? JAXRSUtils.uriDecode(value) : value);
+ } catch (IOException ex) {
+ throw new WebApplicationException(415);
+ }
+ }
+ }
}
Modified: cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java?rev=739958&r1=739957&r2=739958&view=diff
==============================================================================
--- cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java (original)
+++ cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java Mon Feb 2 10:34:13 2009
@@ -132,6 +132,18 @@
return (Class<?>)paramType.getActualTypeArguments()[0];
}
+ public static Class<?> getActualType(Type genericType, int i) {
+ if (genericType == null
+ || !ParameterizedType.class.isAssignableFrom(genericType.getClass())) {
+ return null;
+ }
+ ParameterizedType paramType = (ParameterizedType)genericType;
+ if (i < paramType.getActualTypeArguments().length) {
+ return (Class<?>)paramType.getActualTypeArguments()[i];
+ }
+ return null;
+ }
+
public static void injectThroughMethod(Object requestObject,
Method method,
Object parameterValue) {
Modified: cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java?rev=739958&r1=739957&r2=739958&view=diff
==============================================================================
--- cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java (original)
+++ cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java Mon Feb 2 10:34:13 2009
@@ -519,7 +519,6 @@
return null;
}
-
public static MultivaluedMap<String, String> getMatrixParams(String path, boolean decode) {
int index = path.indexOf(';');
return index == -1 ? new MetadataMap<String, String>()
Modified: cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java?rev=739958&r1=739957&r2=739958&view=diff
==============================================================================
--- cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java (original)
+++ cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java Mon Feb 2 10:34:13 2009
@@ -29,14 +29,18 @@
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import org.apache.cxf.attachment.AttachmentDeserializer;
import org.apache.cxf.common.i18n.BundleUtils;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.jaxrs.ext.MessageContext;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.apache.cxf.jaxrs.ext.multipart.Multipart;
import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
+import org.apache.cxf.jaxrs.impl.MetadataMap;
import org.apache.cxf.jaxrs.utils.AnnotationUtils;
+import org.apache.cxf.jaxrs.utils.FormUtils;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
public final class AttachmentUtils {
@@ -47,6 +51,10 @@
private AttachmentUtils() {
}
+ public static MultipartBody getMultipartBody(MessageContext mc) {
+ return (MultipartBody)mc.get(MultipartBody.INBOUND_MESSAGE_ATTACHMENTS);
+ }
+
public static Map<String, Attachment> getChildAttachmentsMap(MessageContext mc) {
return fromListToMap(getChildAttachments(mc));
}
@@ -63,12 +71,27 @@
return ((MultipartBody)mc.get(MultipartBody.INBOUND_MESSAGE_ATTACHMENTS)).getAllAttachments();
}
+ public static MultipartBody getMultipartBody(MessageContext mc,
+ String attachmentDir, String attachmentThreshold) {
+ if (attachmentDir != null) {
+ mc.put(AttachmentDeserializer.ATTACHMENT_DIRECTORY, attachmentDir, false);
+ }
+ if (attachmentThreshold != null) {
+ mc.put(AttachmentDeserializer.ATTACHMENT_MEMORY_THRESHOLD, attachmentThreshold, false);
+ }
+ return (MultipartBody)mc.get(MultipartBody.INBOUND_MESSAGE_ATTACHMENTS);
+ }
+
+ public static List<Attachment> getAttachments(MessageContext mc,
+ String attachmentDir, String attachmentThreshold) {
+ return getMultipartBody(mc, attachmentDir, attachmentThreshold).getAllAttachments();
+ }
+
public static Attachment getMultipart(Class<Object> c, Annotation[] anns,
- MediaType mt, MessageContext mc) throws IOException {
- List<Attachment> infos = AttachmentUtils.getAttachments(mc);
+ MediaType mt, List<Attachment> infos) throws IOException {
Multipart id = AnnotationUtils.getAnnotation(anns, Multipart.class);
if (id != null) {
- for (Attachment a : getAttachments(mc)) {
+ for (Attachment a : infos) {
if (a.getContentId().equals(id.value())) {
checkMediaTypes(a.getContentType(), id.type());
return a;
@@ -87,6 +110,19 @@
return infos.size() > 0 ? infos.get(0) : null;
}
+ @SuppressWarnings("unchecked")
+ public static <T> MultivaluedMap<String, T> populateFormMap(MessageContext mc, Class<T> cls) {
+ MultivaluedMap<String, T> data = new MetadataMap<String, T>();
+ FormUtils.populateMapFromMultipart((MultivaluedMap)data,
+ AttachmentUtils.getMultipartBody(mc), true);
+ return data;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static MultivaluedMap<String, String> populateFormMap(MessageContext mc) {
+ return populateFormMap(mc, String.class);
+ }
+
private static Map<String, Attachment> fromListToMap(List<Attachment> atts) {
Map<String, Attachment> map = new LinkedHashMap<String, Attachment>();
for (Attachment a : atts) {
Modified: cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBodyTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBodyTest.java?rev=739958&r1=739957&r2=739958&view=diff
==============================================================================
--- cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBodyTest.java (original)
+++ cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBodyTest.java Mon Feb 2 10:34:13 2009
@@ -43,6 +43,17 @@
assertEquals(atts.get(1), b.getChildAttachments().get(0));
}
+ @Test
+ public void testGetAttachmentsById() {
+ List<Attachment> atts = new ArrayList<Attachment>();
+ atts.add(createAttachment("p1"));
+ atts.add(createAttachment("p2"));
+ MultipartBody b = new MultipartBody(atts);
+ assertEquals(atts.get(0), b.getAttachment("p1"));
+ assertEquals(atts.get(1), b.getAttachment("p2"));
+ assertNull(b.getAttachment("p3"));
+ }
+
private Attachment createAttachment(String id) {
return new Attachment(id,
new DataHandler(new ByteArrayDataSource(new byte[]{1}, "application/octet-stream")),
Modified: cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProviderTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProviderTest.java?rev=739958&r1=739957&r2=739958&view=diff
==============================================================================
--- cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProviderTest.java (original)
+++ cxf/branches/2.1.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProviderTest.java Mon Feb 2 10:34:13 2009
@@ -27,10 +27,12 @@
import javax.ws.rs.ConsumeMime;
import javax.ws.rs.Encoded;
import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import org.apache.cxf.jaxrs.impl.MetadataMap;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -49,7 +51,8 @@
public void testReadFrom() throws Exception {
InputStream is = getClass().getResourceAsStream("singleValPostBody.txt");
MultivaluedMap<String, String> mvMap =
- ferp.readFrom((Class)MultivaluedMap.class, null, new Annotation[]{}, null, null, is);
+ (MultivaluedMap<String, String>)ferp.readFrom((Class)MultivaluedMap.class, null,
+ new Annotation[]{}, MediaType.APPLICATION_FORM_URLENCODED_TYPE, null, is);
assertEquals("Wrong entry for foo", "bar", mvMap.getFirst("foo"));
assertEquals("Wrong entry for boo", "far", mvMap.getFirst("boo"));
@@ -61,9 +64,9 @@
String values = "foo=1+2&bar=1+3";
MultivaluedMap<String, String> mvMap =
- ferp.readFrom((Class)MultivaluedMap.class, null,
- new Annotation[]{}, null, null,
- new ByteArrayInputStream(values.getBytes()));
+ (MultivaluedMap<String, String>)ferp.readFrom((Class)MultivaluedMap.class, null,
+ new Annotation[]{}, MediaType.APPLICATION_FORM_URLENCODED_TYPE, null,
+ new ByteArrayInputStream(values.getBytes()));
assertEquals("Wrong entry for foo", "1 2", mvMap.getFirst("foo"));
assertEquals("Wrong entry for boo", "1 3", mvMap.getFirst("bar"));
@@ -75,9 +78,10 @@
String values = "foo=1+2&bar=1+3";
MultivaluedMap<String, String> mvMap =
- ferp.readFrom((Class)MultivaluedMap.class, null,
- new Annotation[]{CustomMap.class.getAnnotations()[0]}, null, null,
- new ByteArrayInputStream(values.getBytes()));
+ (MultivaluedMap<String, String>)ferp.readFrom((Class)MultivaluedMap.class, null,
+ new Annotation[]{CustomMap.class.getAnnotations()[0]},
+ MediaType.APPLICATION_FORM_URLENCODED_TYPE, null,
+ new ByteArrayInputStream(values.getBytes()));
assertEquals("Wrong entry for foo", "1+2", mvMap.getFirst("foo"));
assertEquals("Wrong entry for boo", "1+3", mvMap.getFirst("bar"));
@@ -89,7 +93,8 @@
String values = "foo=1+2&bar=1+3&baz=4";
MultivaluedMap<String, String> mvMap =
- ferp.readFrom((Class)CustomMap.class, null, new Annotation[]{}, null, null,
+ (MultivaluedMap<String, String>)ferp.readFrom((Class)CustomMap.class, null,
+ new Annotation[]{}, MediaType.APPLICATION_FORM_URLENCODED_TYPE, null,
new ByteArrayInputStream(values.getBytes()));
assertEquals(3, mvMap.size());
assertEquals(1, mvMap.get("foo").size());
@@ -107,8 +112,8 @@
String values = "foo=1+2&bar=line1%0D%0Aline+2&baz=4";
MultivaluedMap<String, String> mvMap =
- ferp.readFrom((Class)CustomMap.class, null,
- new Annotation[]{}, null, null,
+ (MultivaluedMap<String, String>)ferp.readFrom((Class)CustomMap.class, null,
+ new Annotation[]{}, MediaType.APPLICATION_FORM_URLENCODED_TYPE, null,
new ByteArrayInputStream(values.getBytes()));
assertEquals(3, mvMap.size());
assertEquals(1, mvMap.get("foo").size());
@@ -123,12 +128,13 @@
@SuppressWarnings("unchecked")
@Test
- public void testvalidation() throws Exception {
+ public void testValidation() throws Exception {
ferp.setValidator(new CustomFormValidator());
String values = "foo=1+2&bar=1+3";
try {
- ferp.readFrom((Class)CustomMap.class, null, new Annotation[]{}, null, null,
+ ferp.readFrom((Class)CustomMap.class, null, new Annotation[]{},
+ MediaType.APPLICATION_FORM_URLENCODED_TYPE, null,
new ByteArrayInputStream(values.getBytes()));
fail();
} catch (WebApplicationException ex) {
@@ -144,7 +150,8 @@
InputStream is = getClass().getResourceAsStream("multiValPostBody.txt");
MultivaluedMap<String, String> mvMap =
- ferp.readFrom((Class)MultivaluedMap.class, null, new Annotation[]{}, null, null, is);
+ (MultivaluedMap<String, String>)ferp.readFrom((Class)MultivaluedMap.class, null,
+ new Annotation[]{}, MediaType.APPLICATION_FORM_URLENCODED_TYPE, null, is);
List<String> vals = mvMap.get("foo");
assertEquals("Wrong size for foo params", 2, vals.size());
Modified: cxf/branches/2.1.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java?rev=739958&r1=739957&r2=739958&view=diff
==============================================================================
--- cxf/branches/2.1.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java (original)
+++ cxf/branches/2.1.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java Mon Feb 2 10:34:13 2009
@@ -37,7 +37,7 @@
@BeforeClass
public static void startServers() throws Exception {
assertTrue("server did not launch correctly",
- launchServer(MultipartServer.class, true));
+ launchServer(MultipartServer.class));
}
@Test
@@ -95,6 +95,32 @@
}
@Test
+ public void testAddBookAsBody() throws Exception {
+ String address = "http://localhost:9085/bookstore/books/body";
+ doAddBook(address, "attachmentData", 200);
+ }
+
+ @Test
+ public void testAddBookFormData() throws Exception {
+ String address = "http://localhost:9085/bookstore/books/form";
+ doAddBook("multipart/form-data", address, "attachmentForm", 200);
+ }
+
+
+ @Test
+ public void testAddBookFormBody() throws Exception {
+ String address = "http://localhost:9085/bookstore/books/formbody";
+ doAddBook("multipart/form-data", address, "attachmentForm", 200);
+ }
+
+ @Test
+ public void testAddBookFormBody2() throws Exception {
+ String address = "http://localhost:9085/bookstore/books/formbody2";
+ doAddBook("multipart/form-data", address, "attachmentForm", 200);
+ }
+
+
+ @Test
public void testAddBookAsJAXB2() throws Exception {
String address = "http://localhost:9085/bookstore/books/jaxb2";
doAddBook(address, "attachmentData", 200);
Modified: cxf/branches/2.1.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.1.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java?rev=739958&r1=739957&r2=739958&view=diff
==============================================================================
--- cxf/branches/2.1.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java (original)
+++ cxf/branches/2.1.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java Mon Feb 2 10:34:13 2009
@@ -33,6 +33,7 @@
import javax.ws.rs.ProduceMime;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
@@ -41,6 +42,7 @@
import org.apache.cxf.jaxrs.ext.MessageContext;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.apache.cxf.jaxrs.ext.multipart.Multipart;
+import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
import org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils;
@Path("/bookstore")
@@ -64,6 +66,38 @@
}
@POST
+ @Path("/books/form")
+ @ConsumeMime("multipart/form-data")
+ @ProduceMime("text/xml")
+ public Response addBookFromForm(MultivaluedMap<String, String> data) throws Exception {
+ Book b = new Book();
+ b.setId(Long.valueOf(data.getFirst("id")));
+ b.setName(data.getFirst("name"));
+ return Response.ok(b).build();
+ }
+
+ @POST
+ @Path("/books/formbody")
+ @ConsumeMime("multipart/form-data")
+ @ProduceMime("text/xml")
+ public Response addBookFromFormBody(MultipartBody body) throws Exception {
+ MultivaluedMap<String, String> data = AttachmentUtils.populateFormMap(context);
+ Book b = new Book();
+ b.setId(Long.valueOf(data.getFirst("id")));
+ b.setName(data.getFirst("name"));
+ return Response.ok(b).build();
+ }
+
+ @POST
+ @Path("/books/formbody2")
+ @ConsumeMime("multipart/form-data")
+ @ProduceMime("text/xml")
+ public Response addBookFromFormBody2() throws Exception {
+ return addBookFromFormBody(AttachmentUtils.getMultipartBody(context));
+ }
+
+
+ @POST
@Path("/books/istream")
@ProduceMime("text/xml")
public Response addBookFromInputStream(InputStream is) throws Exception {
@@ -147,6 +181,14 @@
}
@POST
+ @Path("/books/body")
+ @ProduceMime("text/xml")
+ public Response addBookFromListOfAttachments(MultipartBody body)
+ throws Exception {
+ return addBookFromListOfAttachments(body.getAllAttachments());
+ }
+
+ @POST
@Path("/books/lististreams")
@ProduceMime("text/xml")
public Response addBookFromListOfStreams(List<InputStream> atts)