CXF converts collections to arrays during serialization
-------------------------------------------------------
Key: CXF-3148
URL: https://issues.apache.org/jira/browse/CXF-3148
Project: CXF
Issue Type: Bug
Affects Versions: 2.3.0
Reporter: Dobes Vandermeer
In
org.apache.cxf.jaxrs.provider.JAXBElementProvider.marshalCollection(Class<?>,
Object, Class<?>, Type, String, OutputStream, MediaType), it converts the
resulting collection into an array before serializing it.
Unfortunately, this prevents us from using a collection that lazily loads its
contents from the DB as it goes, since toArray() would require us to create and
return all the results immediately.
Ideally this method would be changed to operate in a manner that is "friendly"
to lazy collections, by only using the collection's iterator (once).
This version iterates over the collection only once, which would be the most
efficient for collections that are backed by out of memory storage:
<code>
protected void marshalCollection(Class<?> originalCls, Object
actualObject, Class<?> actualClass, Type genericType, String encoding,
OutputStream os, MediaType m) throws Exception {
Collection c = originalCls.isArray() ? Arrays.asList((Object[])
actualObject) : (Collection) actualObject;
Iterator it = c.iterator();
boolean empty = false == it.hasNext();
Object firstObj = empty?null:it.next();
QName qname = null;
if (firstObj instanceof JAXBElement) {
JAXBElement el = (JAXBElement) firstObj;
qname = el.getName();
actualClass = el.getDeclaredType();
} else {
qname = getCollectionWrapperQName(actualClass,
genericType, actualObject, true);
}
if (qname == null) {
String message = new
org.apache.cxf.common.i18n.Message("NO_COLLECTION_ROOT", BUNDLE).toString();
throw new
WebApplicationException(Response.serverError().entity(message).build());
}
String startTag = null;
String endTag = null;
if (qname.getNamespaceURI().length() > 0) {
startTag = "<ns1:" + qname.getLocalPart() + "
xmlns:ns1=\"" + qname.getNamespaceURI() + "\">";
endTag = "</ns1:" + qname.getLocalPart() + ">";
} else {
startTag = "<" + qname.getLocalPart() + ">";
endTag = "</" + qname.getLocalPart() + ">";
}
os.write(startTag.getBytes());
marshalCollectionMember(firstObj instanceof JAXBElement ?
((JAXBElement) firstObj).getValue() : firstObj, actualClass, genericType,
encoding, os, m, qname
.getNamespaceURI());
while (it.hasNext()) {
Object o = it.next();
marshalCollectionMember(o instanceof JAXBElement ?
((JAXBElement) o).getValue() : firstObj, actualClass, genericType, encoding,
os, m, qname
.getNamespaceURI());
}
os.write(endTag.getBytes());
}
</code>
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.