Here is a useful servlet following best practices to take a file from a client application and write it to the JCR. We follow best practices using the LoginService. Also, do not forget to set the Apache Sling User Mapper service to the appropriate user (for testing on a local instance, use admin). If you are using Archetype 10, the only additional dependency in Maven you need to add is:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2</version>
</dependency>
Thanks to Scott MacDonald, AEM Community Manager at Adobe, for the huge majority of this code.
Code:
//import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.rmi.ServerException;
import java.util.Calendar;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import javax.jcr.Session;
import javax.jcr.Node;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.sling.jcr.api.SlingRepository;
//This is a component so it can provide or consume services
@SlingServlet(paths="/bin/upfile", methods = "POST", metatype=true)
@Property(name = "sling.auth.requirements", value = "-/bin/upfile")
public class HandleFile extends org.apache.sling.api.servlets.SlingAllMethodsServlet {
private static final long serialVersionUID = 2598426539166789515L;
private Session adminSession;
@Reference
private SlingRepository repository;
private String clientLibPath = "";
/** Default log. */
protected final Logger log = LoggerFactory.getLogger(this.getClass());
//Inject a Sling ResourceResolverFactory
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServerException, IOException {
}
@Override
protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServerException, IOException {
try
{
final boolean isMultipart = org.apache.commons.fileupload.servlet.ServletFileUpload.isMultipartContent(request);
if (isMultipart) {
final java.util.Map<String, org.apache.sling.api.request.RequestParameter[]> params = request.getRequestParameterMap();
for (final java.util.Map.Entry<String, org.apache.sling.api.request.RequestParameter[]> pairs : params.entrySet()) {
final org.apache.sling.api.request.RequestParameter[] pArr = pairs.getValue();
final org.apache.sling.api.request.RequestParameter param0 = pArr[0];
//Determine if the posted value is a file or the JCR Path
boolean formField = param0.isFormField(); //Is this a form field or a posted file
if (formField)
{
String libLoc = param0.getString();
clientLibPath = libLoc ; //Set the class member - its the first posted value from the client
log.info("FIELD VALUE IS: "+libLoc ) ;
}
else
{
// final org.apache.sling.api.request.RequestParameter param1 = pArr[1];
final InputStream stream = param0.getInputStream();
String mimeType = param0.getContentType();
log.info("THE CONTENT TYPE IS: "+mimeType ) ;
//Save the uploaded file into the Adobe CQ DAM
writeToClientLib(stream,param0.getFileName(),clientLibPath,mimeType );
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
//Save the uploaded file into the specified client lib path
private String writeToClientLib(InputStream is, String fileName, String path, String mimetype)
{
try
{
//Invoke the adaptTo method to create a Session
adminSession = repository.loginService(null, repository.getDefaultWorkspace());
Node node = adminSession.getNode(path); //Get the client lib node in which to write the posted file
javax.jcr.ValueFactory valueFactory = adminSession.getValueFactory();
javax.jcr.Binary contentValue = valueFactory.createBinary(is);
Node fileNode = node.addNode(fileName, "nt:file");
fileNode.addMixin("mix:referenceable");
Node resNode = fileNode.addNode("jcr:content", "nt:resource");
resNode.setProperty("jcr:mimeType", mimetype);
resNode.setProperty("jcr:data", contentValue);
Calendar lastModified = Calendar.getInstance();
lastModified.setTimeInMillis(lastModified.getTimeInMillis());
resNode.setProperty("jcr:lastModified", lastModified);
adminSession.save();
adminSession.logout();
// Return the path to the document that was stored in CRX.
return fileNode.getPath();
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
}