Vaadin File Uploading using FileFilter - vaadin

I am Using Vaadin Framework. I need to Upload Files in the format of PDF,JAR & ZIP only. I tried with this code.This code is also I got from STACK OVER FLOW.
public void uploadStarted(StartedEvent event) {
// TODO Auto-generated method stub
System.out.println("***Upload: uploadStarted()");
ArrayList<String> allowedMimeTypes = new ArrayList<String>();
allowedMimeTypes.add("application/java-archive");
allowedMimeTypes.add("application/pdf");
allowedMimeTypes.add("application/zip");
String contentType = event.getMIMEType();
boolean allowed = false;
System.out.println(":::::::::::::contentType::::::"
+ contentType);
for (int i = 0; i < allowedMimeTypes.size(); i++) {
if (contentType.equalsIgnoreCase(allowedMimeTypes.get(i))) {
allowed = true;
break;
}
}
try {
if (allowed) {
System.out.println("boolean value:::::::allowed"
+ allowed);
finalDeedUpload.setReceiver(finalDeedFileUploadHandler);
finalDeedUpload.addListener(finalDeedFileUploadHandler);
} else {
showWarningNotification(
"Error:Please Upload File in Given Format", "");
}
This is working for while uploading PDf files it's working, while uploading Zip OR Jar file and any other file it is showing NULLPOINTER EXCEPTION.
Please help me.

Vaadin has a special upload component which is easy to use. There is a whole chapter in Book of Vaadin related to this component.
https://vaadin.com/book/-/page/components.upload.html

In Vaadin 14 there is a method setAcceptedFileTypes at class Upload:
MemoryBuffer buffer = new MemoryBuffer();
Upload upload = new Upload(buffer);
upload.setAcceptedFileTypes(new String[]{"application/zip", "application/pdf", "application/java-archive"});
The method setAcceptedFileTypes sets the HTML attribute accept at the <input type="file"> element and therefore limits / filters what the application user can upload.

Related

Vaadin 23: file upload from clipboard / Ctrl+V

My need: I'd like to add an "upload from clipboard" functionality into a Vaadin 23 application so that the user can paste a screenshot into an Upload field.
Known pieces of the puzzle: I know that there is a paste event (see here https://stackoverflow.com/a/51586232/10318272 or here https://developer.mozilla.org/en-US/docs/Web/API/Element/paste_event ) and there's the Vaadin Upload component ( https://vaadin.com/docs/latest/components/upload ).
Question: How can I transfer the pasted data into the Upload field?
Why initially intended solution does not work: It seems that uploading a screenshot via an Upload field is not feasible because the FileList (= model of a file input field) does not allow to add/append a new File object.
(Working) Workaround: So my workaround is a TextArea with a paste-EventListener that does a remote procedure call of a #ClientCallable method at the server.
Left component is the TextArea, right component is a preview Image.
Code:
import com.vaadin.flow.component.ClientCallable;
import com.vaadin.flow.component.html.Image;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.textfield.TextArea;
import com.vaadin.flow.server.StreamResource;
import java.io.ByteArrayInputStream;
import java.util.Base64;
public class PasteScreenshotField extends HorizontalLayout {
private final Image previewImg;
public PasteScreenshotField() {
// This could be any focusable type of component, I guess.
TextArea textField = new TextArea();
textField.setWidth("50px");
textField.setHeight("50px");
this.add(textField);
String pasteFunction = "for(const item of event.clipboardData.items) {"
+ " if(item.type.startsWith(\"image/\")) {"
+ " var blob = item.getAsFile();"
+ " var reader = new FileReader();"
+ " reader.onload = function(onloadevent) {$1.$server.upload(onloadevent.target.result);};"
+ " reader.readAsDataURL(blob);"
+ " }"
+ "}";
this.getElement().executeJs("$0.addEventListener(\"paste\", event => {"+pasteFunction+"})", textField.getElement(), this);
// Optional: Preview of the uploaded screenshot
previewImg = new Image();
// TODO: Fixed size of 50px x 50px stretches the image. Could be better.
previewImg.setWidth("50px");
previewImg.setHeight("50px");
this.add(previewImg);
}
#ClientCallable()
private void upload(String dataUrl) {
System.out.println("DataUrl: "+dataUrl);
if (dataUrl.startsWith("data:")) {
byte[] imgBytes = Base64.getDecoder().decode(dataUrl.substring(dataUrl.indexOf(',') + 1));
// Showing a preview is just one of the possible scenarios.
// TODO: check filename extension. Maybe it's not a png.
previewImg.setSrc(new StreamResource("preview.png", () -> new ByteArrayInputStream(imgBytes)));
}
}
}
Extendability: Instead of previewImg.setSrc you could do whatever you want with the uploaded file. The preview is just the proof that the screenshot goes to the server (and could go back to the client again).
Possible connection to Upload component:
If you've got an Upload component and want to extend it with this paste functionality, you can register the paste listener at the Upload component (or at some other component) and instead of previewImg.setSrc you just call this (whereas the onSucceededRunner is a BiConsumer<String, String> in my case that runs the onSucceeded stuff (updating thumbnails, setting attributes at the bound bean, ...)):
String filename = "screenshot.png";
String mimeType = "image/png";
OutputStream outputStream = uploadField.getReceiver().receiveUpload(filename, mimeType);
outputStream.write(imgBytes);
outputStream.flush();
outputStream.close();
onSucceededRunner.accept(filename, mimeTypeString);
Final result:
This is what my custom upload field looks like in the end (assembled from the code above plus an Upload field plus a TextField for the file name and a thumbnail preview). The user now has to click somewhere at that field (=focus it, because there could be more than one in a form), press Ctrl+V and then a screenshot gets uploaded (if there is any) from clipboard to Vaadin application at the server.

Random image from folder

How can I make possible that the app will load all of the images from the specific folder and then put in array and choose one image randomly? When chose one then pass to the fronted to show the image. How to do that too?
I am C# developer but not long time ago I found ElectronJS and this framework does everything easier so therefore I am moving to this framework.
I did in C# programming this way:
// basic settings.
var ext = new List<string> { ".jpg", ".gif", ".png" };
// we use same directory where program is.
string targetDirectory = Directory.GetCurrentDirectory() + "\\assets\\" + "images\\" + "animals\\";
// Here we create our list of files
// New list
// Use GetFiles to getfilenames
// Filter unwanted stuff away (like our program)
if (Directory.Exists(targetDirectory))
{
Files = new List<string>
(Directory.GetFiles(targetDirectory, "*.*", SearchOption.TopDirectoryOnly)
.Where(s => ext.Any(es => s.EndsWith(es))));
// Show first picture so we dont need wait 3 secs.
ChangePicture();
}
else
{
panel5.BackgroundImage = new Bitmap(Resources.doggy);
}
I don't know how to do in ElectronJS.
Thank you in advance the answers.
Alright. I found the solution.
However I don't understand the people who are giving negative reputation for the opened question. If they are giving negative reputation then they could explain why.
Well anyway, I did fix this issue with this way:
I created images.js file and added this:
var fs = require('fs');
function getRandImage() {
var files = fs.readdirSync('./assets/images/animals/')
/* now files is an Array of the name of the files in the folder and you can pick a random name inside of that array */
let chosenFile = files[Math.floor(Math.random() * files.length)]
console.log('../assets/images/animals/' + chosenFile);
return '../assets/images/animals/' + chosenFile;
}
module.exports = { getRandImage }
I used console to see if the value is correct, otherwise others can delete that part.
Sending the data to the renderer process:
const { getRandImage } = require('./images');
child.webContents.send('random-image', getRandImage());
I did put in the preload.js file the following (I used the starter pack electronjs github to start with something):
var { ipcRenderer } = require('electron');
ipcRenderer.on('random-image', function (event, store) {
document.getElementById("randompic").src = store;
console.log(store);
});
Same here, I did use console.log just for test the value is correct and I used to change the randompic ID related image src html to the randomly chosen image.
Hopefully I did helping those people who are newbie as me.

.Net Core 2. How to upload a file with metadata in same request?

I am trying to upload a file to a .net core 2 rest API while in the same POST request also upload metadata (which will be stored in database). By metadata I mean a few info about the file (uploader, date/time of upload and just a few more) as Json format.
I have searched and tried different ways found on Stackoverflow but none worked. I am right now at this point.
The API Controller:
[HttpPost]
[Consumes("multipart/form-data")]
public async Task<ActionResult> upload(IFormFile file, MyMetadata metadata)
{
// my logic
}
The client:
using (var fileStream = File.OpenRead(filePath))
{
using (var multiPartFormDataContent = new MultipartFormDataContent())
{
multiPartFormDataContent.Add
(
new StreamContent(fileStream)
{
Headers =
{
ContentLength = fileStream.Length,
ContentType = new MediaTypeHeaderValue("application/octet-stream")
}
}
, "file"
, Path.GetFileName(filePath)
);
var link = /mycontroller/upload;
var resultTask = client.PostAsync(link, multiPartFormDataContent);
var result = await resultTask;
I have tried adding the model to multPartFormDataContent but without success.
So what I am asking for, is a complete solution Controller and Client in same answer that will work.

Google docs file upload and move collection issue

Issue #1
When i'm uploading a file to google docs i receive status code "201" created, but when i try to open the file it seems that i'm doing something wrong, because i can't open it, and when i'm trying to download and open it on my PC i see the binary data instead of text or image. Current language is APEX, but i think it's pretty understandable.
First of all i'm getting Upload URL and then putting data to this URL;
public void getUploadURL()
{
Httprequest req = new Httprequest();
req.setEndpoint('https://docs.google.com/feeds/upload/create-session/default/private/full?convert=false');
req.setMethod('POST');
req.setHeader('GData-Version', '3.0');
req.setHeader('Authorization', 'OAuth '+accessToken);
req.setHeader('Content-Length', '359');
req.setHeader('X-Upload-Content-Type', fileType);
req.setHeader('X-Upload-Content-Length', fileSize);
Dom.Document requestDoc = new Dom.Document();
String xml =
'<?xml version=\'1.0\' encoding=\'UTF-8\'?>'
+'<entry xmlns="http://www.w3.org/2005/Atom" xmlns:docs="http://schemas.google.com/docs/2007">'
+'<title>'+fileName+'</title></entry>';
requestDoc.load(xml);
req.setBodyDocument(requestDoc);
Http h = new Http();
Httpresponse res = h.send(req);
System.debug('response=\n'+res.getHeader('Location'));
uploadFIle(res.getHeader('Location'));
}
public void uploadFIle(String uploadUrl)
{
Httprequest req = new Httprequest();
req.setEndpoint(uploadUrl);
req.setMethod('PUT');
req.setHeader('GData-Version', '3.0');
req.setHeader('Authorization', 'OAuth '+accessToken);
req.setHeader('Host', 'docs.google.com');
req.setHeader('Content-Length', fileSize);
req.setHeader('Content-Type', fileType);
req.setBody(''+binaryData);
Http h = new Http();
Httpresponse res = h.send(req);
System.debug('response=\n'+res.getBody());
}
As for "binaryData" property - i receive it from the page using javascript like this:
<input type="file" id="myuploadfield" onchange="getBinary()"/>
<script>
function getBinary()
{
var file = document.getElementById('myuploadfield').files[0];
fileSizeToController.val(file.size.toString());
fileNameToController.val(file.name.toString());
fileTypeToController.val(file.type.toString());
var r = new FileReader();
r.onload = function(){ binaryToController.val(r.result); };
r.readAsBinaryString(file);
}
</script>
r.onload = function(){ binaryToController.val(r.result); }; - this is the string that sends file binary data to my controller.
Issue #2
I'm trying to move one collection(folder) to another, and using this article (protocol tab instead of .NET). The issue is that i need to move collection instead of copying it and when i add my collection to another using this article, i'm currently adding reference to my collection instead of moving the whole collection from one place to another.
Please tell me what am i doing wrong.
Thank you for consideration.
Your "binary" data is being corrupted, when you are performing '' + binaryData.
In general, I have had more success using slicing of files, here is an example for webkit:
var chunk = this.file.webkitSlice(startByte, startByte + chunkSize, file_type);
// Upload the chunk
uploadChunk(startByte, chunk, callback);

Image upload to filesystem in Grails

I'm implementing a file upload functionality to a web-app in Grails. This includes adapting existing code to allow multiple file extensions. In the code, I've implemented a boolean to verify that the file path exists, but I'm still getting a FileNotFoundException that /hubbub/images/testcommand/photo.gif (No such file or directory)
My upload code is
def rawUpload = {
def mpf = request.getFile("photo")
if (!mpf?.empty && mpf.size < 200*1024){
def type = mpf.contentType
String[] splitType = type.split("/")
boolean exists= new File("/hubbub/images/${params.userId}")
if (exists) {
mpf.transferTo(new File("/hubbub/images/${params.userId}/picture.${splitType[1]}"))
} else {
tempFile = new File("/hubbub/images/${params.userId}").mkdir()
mpf.transferTo(new File("/hubbub/images/${params.userId}/picture.${splitType[1]}"))
}
}
}
I'm getting the exception message at
if (exists) {
mpf.transferTo(new File("/hubbub/images/${params.userId}/picture.${splitType[1]}"))
}
So, why is this error happening, as I'm simply collatating an valid existing path as well as a valid filename and extension?
Why do you think that convertation of File object to Boolean returns existence of a file?
Try
File dir = new File("/hubbub/images/${params.userId}")
if (!dir.exists()) {
assert dir.mkdirs()
}
mpf.transferTo(new File(dir, "picture.${splitType[1]}"))

Resources