Seit längerem beschäftige ich mich damit wie man grössere Dateien über Ajax Request in eine Notes Datenbank hochladen könnte.
Dabei bin ich über diesen Beitrag gestolpert:
http://www.linqed.eu/2015/06/24/file-uploads-to-domino-servlets-with-an-angular-demo/Ist schon ganz schön. Braucht aber immerhin noch einiges an Java Code in der Datenbank.
Kürzlich habe ich mir SmartNSF genauer angesehen.
https://smartnsf.openntf.org/main.nsf/project.xsp?r=project/SmartNSF/summaryFragte mich ob ich das nicht kombinieren könnte.
Habe also Beispielklasse (org.openntf.smartnsf.Info) in Beispieldatenbank die SmartNSF beiliegt angepasst.
Ich habe da den Code von Beispiel Datenbank aus ersten Beitrag reinkopiert und etwas angepasst.
Daraus wurde das (org.openntf.smartnsf.Upload):
package org.openntf.smartnsf;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lotus.domino.Database;
import lotus.domino.Document;
import lotus.domino.MIMEEntity;
import lotus.domino.MIMEHeader;
import lotus.domino.NotesException;
import lotus.domino.Stream;
import org.openntf.xrest.xsp.exec.Context;
import org.openntf.xrest.xsp.exec.CustomRestHandler;
import com.ibm.commons.util.io.json.JsonJavaObject;
import com.ibm.commons.util.io.json.util.JsonWriter;
import com.ibm.domino.services.HttpServiceConstants;
import com.ibm.xsp.extlib.util.ExtLibUtil;
import com.ibm.xsp.http.fileupload.FileItem;
import com.ibm.xsp.http.fileupload.disk.DiskFileItemFactory;
import com.ibm.xsp.http.fileupload.servlet.ServletFileUpload;
public class Upload implements CustomRestHandler {
public void processCall(Context context, String path) throws Exception {
JsonJavaObject result = new JsonJavaObject();
HttpServletResponse res = context.getResponse();
HttpServletRequest req = context.getRequest();
try {
// We only accept POST requests
if (!req.getMethod().equals("POST")) {
res.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
// Check if we're receiving the right content
boolean isMultipart = ServletFileUpload.isMultipartContent(req);
if (!isMultipart) {
throw (new Exception("that's not multipart content: we need that to continue"));
}
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Configure a repository (to ensure a secure temp location is used)
//ServletContext servletContext = this.getServletConfig().getServletContext();
//File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
File repository = (File) req.getAttribute("javax.servlet.context.tempdir");
factory.setRepository(repository);
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Parse the incoming request
List<FileItem> items = upload.parseRequest(req);
// Create a target document in the current database
Database dbCurrent = ExtLibUtil.getCurrentDatabase();
Document docTarget = dbCurrent.createDocument();
// Create a MIME entity in which we're storing all uploaded files
MIMEEntity mime = docTarget.createMIMEEntity("Files");
// Loop through all data received (files as well as form fields)
for (FileItem item : items) {
if (item.isFormField()) { //'form fields' contain the form data that is send along with the request
System.out.println("form field: " + item.getFieldName() + " : " + item.getString());
docTarget.replaceItemValue(item.getFieldName(), item.getString());
} else {
processUploadedFile(item, mime);
}
}
docTarget.save();
res.setStatus(HttpServletResponse.SC_OK);
result.put("status", "success");
//out.print("{ \"success\" : true }"); //no, this is not how I would do it in production
} catch (Exception e) {
e.printStackTrace();
res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
//out.print("{ \"success\" : false, \"message\" : \"" + e.getMessage() + "\"}");
result.put("status", "error");
}
System.out.println("Test4");
res.setContentType(HttpServiceConstants.CONTENTTYPE_APPLICATION_JSON_UTF8);
JsonWriter jsw = new JsonWriter(res.getWriter(),true);
jsw.outObject(result);
jsw.close();
}
/*
* Store an uploaded fild as a MIMEEntity in a MIME item
*/
private void processUploadedFile(FileItem item, MIMEEntity mime) throws IOException, NotesException {
System.out.println("- processing uploaded file: " + item.getName());
MIMEEntity child = mime.createChildEntity();
MIMEHeader header = child.createHeader("content-disposition");
header.setHeaderVal("attachment;filename=\"" + item.getName() + "\"");
Stream stream = ExtLibUtil.getCurrentSession().createStream();
stream.write(item.get());
child.setContentFromBytes(stream, item.getContentType(), MIMEEntity.ENC_IDENTITY_BINARY); //ENC_BASE64);
child.decodeContent();
}
}
HTML schaut bei mir dann so aus:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Titel hier einfügen</title>
<script src="bluebird/3.5.0/bluebird.min.js"></script>
<script src="polyfill.js"></script>
<script src="axios/0.18.0/axios.min.js"></script>
</head>
<body>
<input type="file" onChange="onFileChanged(event)" multiple>
<script>
function onFileChanged(event) {
var files;
var formData = new FormData()
formData.append('form', 'Files');
formData.append('subject', 'Hallo Welt!');
Array.from(event.target.files).forEach(function(file, index) {
console.log('Dateiname: ' + file.name + ' Dateigrösse: ' + file.size);
formData.append('file' + index, file, file.name);
})
axios.post('xsp/.xrest/upload', formData, {
onUploadProgress: function(event) {
console.log(Math.floor(event.loaded / event.total * 100));
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
</script>
</body>
</html>
Das scheint zu funktionieren, schaffe es also mit kleiner HTML Datei in NSF Dateien hochzuladen.
Bei Problemen mit dem Code werde ich versuchen ob ich halfen kann, kenne mich aber leider nicht wirklich gross mit Servlets aus).
Hoffe jemand findet diesen Beitrag interessant.
Gruss
Remo