Yesterday I stucked on problem of getting data from WebScriptRequest, which were sent by POST method. There is some bug in Apache Tomcat, so there is a simple workaround described for example here. My task was to create webscript, which tries to find a file in repository (or create it, if it doesn’t exist) and to write content inside – data of POST request.
My webscript is Java backed, so only description in WEB-INF/classes/alfresco/templates/client/webscripts/org/alfresco/archivace is needed:
<webscript> <shortname>SaveModif file</shortname> <description>Ulozi dorucena data do *.modif.xml</description> <url>/archivace/savemodif?nodeRef={noderef}</url> <authentication>user</authentication> <transaction>required</transaction> </webscript>
Also definition in web-scripts-application-context.xml:
<bean id=“webscript.org.alfresco.archivace.savemodif.post“ class=“cz.shmoula.webscripts.SaveModif“ parent=“webscript“>
<property name=“authenticationComponent“ ref=“AuthenticationComponent“/>
<property name=“nodeService“ ref=“NodeService“/>
<property name=“searchService“ ref=“SearchService“/>
<property name=“fileFolderService“ ref=“FileFolderService“/>
<property name=“contentService“ ref=“ContentService“/>
</bean>
Now let’s get Node object itself:
// try to get DescriptionNode
Node xmlNode = getDescriptionNode(nodeRef);// if DescriptionNode doesn’t exist, create one
if (xmlNode == null) {
String path = noda.getName();
String filename = path.substring(0, path.lastIndexOf(„.“)) + „.modif.xml“;
NodeRef spaceRef = nodeService.getPrimaryParent(noda.getNodeRef()).getParentRef();
xmlNode = createDescriptionNode(spaceRef, filename);
}
At this time in xmlNode is Node object – either existing one, or created one, so let’s write that request content inside:
ContentWriter writer = contentService.getWriter(xmlNode.getNodeRef(), ContentModel.PROP_CONTENT, true);
writer.putContent(req.getContent().getInputStream());
Simple, but sometimes it doesnt work. Why? Due to that bug mentioned in perex. So how are data sent through POST method? Let’s try it with wget:
wget –post-data=’pokus‘ –http-user=admin –http-password=admin http://localhost:8080/alfresco/service/archivace/savemodif?nodeRef=workspace://SpacesStore/91919928-3709-4e2e-a829-b0be46976e42
Captured request looks like this
As you can see, everything looks ok. But getContent() in our webscript is empty. Why? there is no content – there are just parameters, due to application/x-www-form-urlencoded content type. So req.getParameterNames() returns String[] array in which are in our case two parameters: {{nodeRef}, {pokus}}. This is not what we want, because length ot these parameter names may be limited (2M?). So let’s use mentioned advice – change content-type:
wget –post-data=’pokus‘ –header=’Content-Type: text/xml‘ –http-user=admin –http-password=admin http://localhost:8080/alfresco/service/archivace/savemodif?nodeRef=workspace://SpacesStore/91919928-3709-4e2e-a829-b0be46976e42
And now it works! 🙂 Sniffed request looks like before, just content-type header line had changed:
Now is possible to send inputStream of content to Writer:
writer.putContent(req.getContent().getInputStream());
At this time req.getParameterNames() has just one parameter – {{nodeRef}} and content is really saved in data field.