How to implement azure-storage into vaadin framework - java

I am trying to upload a file into Azure Blob.
and I am trying to achieve through Upload in vaadin framework. Vaadin Version : 6.7.8
I am able to develop a code for uploading the file into azure blob.
My Problem Statement Lies below :
I have written a class UploadToBlob.java to upload a file into azure blob.
If I run the class UploadToBlob.java indivually (ran from eclipse run as java application), I am able to upload the file into azure blob.
If I create a object of the UploadToBlob class in my other class[ModifyComplaintComponent.java], storageAccount = CloudStorageAccount.parse(storageConnectionString); is not getting execute.
Below is the UploadToBlob.java code:
package com.---.trs.scms.ui.components;
import com.microsoft.azure.storage.CloudStorageAccount;
import com.microsoft.azure.storage.StorageCredentials;
import com.microsoft.azure.storage.blob.CloudBlobContainer;
public class UploadToBlob {
public static void main(String[] args) {
try {
final String storageConnectionString = "DefaultEndpointsProtocol=https;AccountName=abcd;AccountKey=bmiA7+****==;EndpointSuffix=core.windows.net";
System.out.println("---I am getting called Main-1 ");
CloudStorageAccount storageAccount;
storageAccount = CloudStorageAccount.parse(storageConnectionString);
com.microsoft.azure.storage.blob.CloudBlobClient blobClient = storageAccount.createCloudBlobClient();
CloudBlobContainer container = blobClient.getContainerReference("container2");
container.createIfNotExists();
String filePath = "C:\\Users\\----\\Desktop\\Timesheet - 19th Aug,2019.pdf";
com.microsoft.azure.storage.blob.CloudBlockBlob blob = container.getBlockBlobReference("Timesheet.pdf");
java.io.File source = new java.io.File(filePath);
java.io.FileInputStream fileInputStream = new java.io.FileInputStream(source);
blob.upload(fileInputStream, source.length());
} catch (Exception e) {
e.printStackTrace();
}
}
}
For now , I am passing manual file PATH as above to upload in azure blob, as I told above , this class is getting called till the line of code System.out.println("---I am getting called Main-1 ");
Here is the ModifyComplaintComponent code from where I am calling UploadToBlob.java:
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Upload;
public class ModifyComplaintComponent extends CustomComponent {
//other component code which I haven't pasted here
private Upload uploadnew;
try {
System.out.println("------Inside try block-----------");
UploadToBlob fileReceiver= new UploadToBlob ();
uploadnew = new Upload("Upload a file", fileReceiver);
uploadnew.setReceiver(fileReceiver);
uploadnew.addListener(fileReceiver);
System.out.println("------end of try block-----------");
} catch (Exception e) {
System.out.println("------catch block-----------");
e.printStackTrace();
}
HorizontalLayout hlayout = new HorizontalLayout();
hlayout.setSpacing(true);
hlayout.addComponent(uploadnew);
}
The Reason why I have given a manual file path in my UploadToBlob code is because I firstly wanted to make this code called from ModifyComplaintComponent class.
Secondly when I try to browse the file , and file gets selected but when I click on upload , I get NullPointerException On Vaadin Upload UI Part and even if i selected the file , UI says "no file choosen"
The challenge I am facing is If I run the Upload.java file individually I am able to upload static file into azure blob , but I wanted to browse and upload a file in vaadin framework into azure blob storage.

Firstly, Upload is a Component of Vaadin. You should not create your own Upload class.
Secondly, the public static main method is an entrance where your program starts. If you want to use a method of a class, you need to explicitly invoke it.
TheClassName.MethodName(...) // For static method
new TheClassName(...).MethodName(...) //For non-static method
Thirdly, I did some tests, the following is a successful sample. Two classes will be created:
Class UploadReceiver
This class implements the Receiver interface and some listeners.
import com.microsoft.azure.storage.CloudStorageAccount;
import com.microsoft.azure.storage.StorageException;
import com.microsoft.azure.storage.blob.CloudBlobClient;
import com.microsoft.azure.storage.blob.CloudBlobContainer;
import com.microsoft.azure.storage.blob.CloudBlockBlob;
import com.vaadin.ui.Upload;
import org.springframework.stereotype.Component;
import java.io.OutputStream;
import java.net.URISyntaxException;
import java.security.InvalidKeyException;
#Component
public class UploadReceiver implements Upload.Receiver, Upload.StartedListener, Upload.SucceededListener, Upload.ProgressListener {
// Storage account connection string.
public static String conn = "DefaultEndpointsProtocol=https;AccountName=stora***789;AccountKey=G3***w==;EndpointSuffix=core.windows.net";
#Override
public OutputStream receiveUpload(String filename, String mimeType) {
System.out.println("Uploading -> " + mimeType + " ; File name -> " + filename);
return GetOutputStream("vaadin",filename);
}
#Override
public void uploadStarted(Upload.StartedEvent startedEvent) {
System.out.println("Upload started!");
}
#Override
public void uploadSucceeded(Upload.SucceededEvent succeededEvent) {
System.out.println("Upload succeeded!");
}
public OutputStream GetOutputStream(String container, String blob){
OutputStream outputStream = null;
try{
CloudStorageAccount storageAccount = CloudStorageAccount.parse(conn);
CloudBlobClient blobClient = storageAccount.createCloudBlobClient();
CloudBlobContainer blobContainer = blobClient.getContainerReference(container);
CloudBlockBlob cloudBlockBlob = blobContainer.getBlockBlobReference(blob);
outputStream = cloudBlockBlob.openOutputStream();
} catch (StorageException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
return outputStream;
}
#Override
public void updateProgress(long readBytes, long contentLength) {
System.out.println("Progress: readBytes -> " + readBytes + " ; contentLength -> " + contentLength);
}
}
Class MainUI
This is the UI page. I just add an upload component.
import com.vaadin.server.VaadinRequest;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.UI;
import com.vaadin.ui.Upload;
import com.vaadin.ui.VerticalLayout;
import org.springframework.beans.factory.annotation.Autowired;
#SpringUI
public class MainUI extends UI {
private VerticalLayout layout;
private Upload upload;
private UploadReceiver uploadReceiver;
#Autowired
public MainUI(UploadReceiver uploadReceiver){
this.uploadReceiver = uploadReceiver;
}
#Override
protected void init(VaadinRequest vaadinRequest) {
// Set layout
layout = new VerticalLayout();
layout.setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);
setContent(layout);
// Add upload
upload = new Upload("Upload a file", uploadReceiver);
upload.addStartedListener(uploadReceiver);
upload.addSucceededListener(uploadReceiver);
upload.addProgressListener(uploadReceiver);
layout.addComponent(upload);
}
}
Result:
After I clicked the upload button and chose a file to upload, I could get the following outputs from console:
And, by checking the storage account with Storage Explorer, I could see that the file was successfully uploaded:
Update:
This is how the upload works:
I do not know how your code passed the compiling. To construct an Upload object, you need to pass a caption string and a receiver which implements Upload.Receiver interface.
public Upload(String caption, Receiver uploadReceiver)
And to implement the Upload.Receiver interface, you have to override the receiveUpload method.
OutputStream receiveUpload(String filename, String mimeType)
The receiveUpload will return an output stream, where vaadin will finally write contents to.
That's all. Give vaadin an output stream, and it will write all the contents to the stream.
The input file is sent from your browser and handled by vaadin. I did not find a way to manually set the input content in vaadin. Sorry.

Related

Discord JDA Save a file attachment that was included in a message

The code is as follows:
package volmbot.commands;
import lombok.SneakyThrows;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class SandBox extends ListenerAdapter {
#SneakyThrows
public void onGuildMessageReceived(GuildMessageReceivedEvent e) {
String[] args = e.getMessage().getContentRaw().split(" ");
e.getMessage().getAttachments();
String authId = e.getMessage().getAuthor().getId();
//Grab file and save it as the user's ID
FileOutputStream saveFile = new FileOutputStream(authId + ".txt");
ObjectOutputStream save = new ObjectOutputStream(saveFile);
save.writeObject(e.getMessage().getAttachments());
save.close();
}
}
My goal is to do the following:
Save the file that the user sent in a message (if the message has an attachment)
Ignore it if the message does not contain a message
Save to a file with the user's ID as id.txt
I've tried using a Filestream, but I might be doing something wrong.
How would I manage so grab the messages attachment, assuming it has an attachment, then save the file?
You can use downloadToFile(name):
List<Message.Attachment> attachments = event.getMessage().getAttachments();
if (attachments.isEmpty()) return; // no attachments on the message!
CompletableFuture<File> future = attachments.get(0).downloadToFile(authId + ".txt");
future.exceptionally(error -> { // handle possible errors
error.printStackTrace();
return null;
});

How to send image in JDA

I want to make a discord bot, that when the user types -m skelt a picture will be shown from the bot. Here is what I got so far: Can somone please help me. Thanks!
package lairex59.Commands;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import lairex59.Main;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
public class Comment extends ListenerAdapter
{
public void onGuildMessageReceived(GuildMessageReceivedEvent event){
String[] args = event.getMessage().getContentRaw().split("\\s+");
if (args[0].equalsIgnoreCase(Main.prefix + "help")) {
EmbedBuilder info = new EmbedBuilder();
info.setTitle(":among_us_lime:Among Us help cnter");
info.setDescription("Among Us code center :office:");
info.setColor(0xf45642);
info.setFooter("Created by Laraib", event.getMember().getUser().getAvatarUrl());
event.getChannel().sendTyping().queue();
event.getChannel().sendMessage(info.build()).queue();
info.clear();
}
if ((args[0].equalsIgnoreCase(Main.prefix + "m")) && (args[1].equalsIgnoreCase("polus"))) {
event.getChannel().sendTyping().queue();
event.getChannel().sendMessage("Polus file").queue();
}
if (args[0].equalsIgnoreCase(Main.prefix + "m") && (args[1].equalsIgnoreCase("mira"))) {
event.getChannel().sendTyping().queue();
event.getChannel().sendMessage("Mira file").queue();
}
if (args[0].equalsIgnoreCase(Main.prefix + "m") && (args[1].equalsIgnoreCase("skelt"))) {
event.getChannel().sendTyping().queue();
BufferedImage image = null;
File f = null;
try {
f = new File ("D:\\Laraib\\Images\\Skelt.jpg");
image = ImageIO.read(f);
}
catch(IOException e) {
System.out.println("Error"+e);
}
try {
f = new File ("D:\\Laraib\\Images\\Skelt.jpg");
ImageIO.write(image, "jpg", f);
}
catch (IOException e) {
System.out.println("Error"+e);
}
}
}
}
I managed to read the file but don't know how i can tell the bot to send an image. Every help is needed. Thanks!
Discord does not ask to specify if the file sent is an image or something else, it just sends the file, it is the client who, from the file extension, will display the image as an image, so your BufferedImage is useless.
So, to send your image, it's just plain silly:
The MessageAction interface you have a method MessageAction#addFile(File)
All you have to do is to call this method, and to send all this to the wrong person (like the queue method for example).
File file = new File("path");
if (Objects.nonNull(file)) {
event.getChannel().sendMessage("Here is my image !").addFile(file).queue();
} else {
event.getChannel().sendMessage("Sorry, I can't found the image :c").queue();
}
Here's the java doc : https://ci.dv8tion.net/job/JDA/javadoc/net/dv8tion/jda/api/requests/restaction/MessageAction.html
EDIT:
Or, as #minn reminded me, you don't have to add the file in the MessageAction but you can directly send the file without additional content with the method MessageChannel#sendFile(file).
Here's the doc: https://ci.dv8tion.net/job/JDA/javadoc/net/dv8tion/jda/api/entities/MessageChannel.html

Azure Web Job Upload using java client

History for context:
I am trying to run a web job from an HTTP Client. The file is a ZIP file . and contains a java class and bat file to run that java class. This runs okay when i do from POSTMAN. But when i use HTTP client, i get the following error always " '---i-NPsGbTVUpaP0CeJxMQVrHoDHvaxo3' is not recognized as an internal or external command" - Please help – Jagaran yesterday
#Jagaran if it only happen from some clients, it is likely unrelated. Please ask a new question – David Ebbo 21 hours ago
No any HTTP Client i am using in java, it is the same. it works in CURL or loading from web console. My sample code below – Jagaran 2 hours ago
No any HTTP Client i am using in java, it is the same. it works in CURL or loading from web console.
Do you have any sample Java based HTTP Client where I can publish Azure Web Job? I have tried all Java REST clients.
May be i am doing something wrong. The error I get in Azure console is '---i-NPsGbTVUpaP0CeJxMQVrHoDHvaxo3' is not recognized as an internal or external command, [08/25/2017 09:30:22 > e7f683: ERR ] operable program or batch file.o
I feel Content type = applciation /zip is not happening correctly when using java. Please help us.
Sample Code:
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.apache.http.entity.ContentType;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
/**
* #author jagaran.das
*
*/
public class AIPHTTPClient {
/**
* #param args
* #throws IOException
*/
#SuppressWarnings({ "unused", "rawtypes" })
public static void main(String[] args) throws IOException {
try {
URI uri = new AIPHTTPClient().getURI();
HttpResponse<InputStream> jsonResponse = Unirest.put("https://<URL>/api/triggeredwebjobs/TestJOb")
.basicAuth("$AzureWebJobTestBRMS", "XXXXX")
.header("content-disposition","attachement; filename=acvbgth.bat")
.field("file", new FileInputStream(new File(uri))
,ContentType.create("content-type: application/zip"),"AzureWebJob.zip").asBinary();
System.out.println(jsonResponse.getStatusText());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public InputStream readZip() {
ZipFile zipFile = null;
ZipEntry zipEntry = zipFile.getEntry("run.bat");
InputStream stream = null;
/* try {
zipFile = new ZipFile("/Users/jagaran.das/Documents/work/AIP/AzureWebJob.zip");
java.util.Enumeration<? extends ZipEntry> entries = zipFile.entries();
while(entries.hasMoreElements()){
ZipEntry entry = entries.nextElement();
stream = zipFile.getInputStream(entry);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} */
try {
stream = zipFile.getInputStream(zipEntry);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return stream;
}
public URI getURI() throws MalformedURLException {
File file = new File("/Users/jagaran.das/Documents/work/AIP/azure-poc/AzureWebJob.zip");
URI fileUri = file.toURI();
System.out.println("URI:" + fileUri);
URL fileUrl = file.toURI().toURL();
System.out.println("URL:" + fileUrl);
URL fileUrlWithoutSpecialCharacterHandling = file.toURL();
System.out.println("URL (no special character handling):" + fileUrlWithoutSpecialCharacterHandling);
return fileUri;
}
}
I've been a little too harsh in my answer before really trying stuff out. Apologies. I've now tried out your snippet and looks like you're hitting an issue with Unirest - probably this one.
My advice would be to just move to Apache's HTTP library.
Here's a working sample:
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.EntityBuilder;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import java.io.File;
public class App
{
public static void main( String[] args )
{
File sourceZipFile = new File("webjob.zip");
String kuduApiUrl = "https://yoursitename.scm.azurewebsites.net/api/zip/site/wwwroot/app_data/jobs/triggered/job988/";
HttpEntity httpEntity = EntityBuilder.create()
.setFile(sourceZipFile)
.build();
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(
"$yoursitename", "SiteLevelPasSw0rD"
);
provider.setCredentials(AuthScope.ANY, credentials);
HttpClient client = HttpClientBuilder.create()
.setDefaultCredentialsProvider(provider)
.build();
HttpPut putRequest = new HttpPut(kuduApiUrl);
putRequest.setEntity(httpEntity);
// Kudu's Zip API expects application/zip
putRequest.setHeader("Content-type", "application/zip");
try {
HttpResponse response = client.execute(putRequest);
int statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
String resBody = EntityUtils.toString(entity, "UTF-8");
System.out.println(statusCode);
System.out.println(resBody);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
That's sending Content-Type: application/zip and the raw zip contents in the body (no multipart horse manure). I've probably over-engineered the sample.. but it is what it is.
The upload is successful and the WebJob published:
Glad for you that you have solved the issue and I try to provide a workaround for your reference.
Deploy WebJob to azure , in addition to using REST API, you can also use the FTP way. Of course, the premise is that you need to know the directory uploaded by webjob via KUDU.
I offer you the snippet of code below via FTP4J libiary:
import java.io.File;
import it.sauronsoftware.ftp4j.FTPClient;
public class UploadFileByFTP {
private static String hostName = <your host name>;
private static String userName = <user name>;
private static String password = <password>;
public static void main(String[] args) {
try {
// create client
FTPClient client = new FTPClient();
// connect host
client.connect(hostName);
// log in
client.login(userName, password);
// print address
System.out.println(client);
// change directory
client.changeDirectory("/site/wwwroot/App_Data/jobs/continuous");
// current directory
String dir = client.currentDirectory();
System.out.println(dir);
File file = new File("D:/test.zip");
client.upload(file);
} catch (Exception e) {
e.printStackTrace();
}
}
}
You can follow this tutorial to configure your parameters.

Get call back from Servlet in GWT when Upload file in SmartGWT's dynamic form without using DataSource

I am using SmartGWT Dynamic form submitForm() to implement a file upload functionality in the client side, here is the code:
final String DEFAULT_FILE_UPLOAD_SERVICE_PATH = "upload";
final String TARGET = "uploadTarget";
VLayout body = new VLayout();
uploadForm = new DynamicForm();
// initialise the hidden frame
NamedFrame frame = new NamedFrame(TARGET);
frame.setWidth("1px");
frame.setHeight("1px");
frame.setVisible(false);
uploadForm.setEncoding(Encoding.MULTIPART);
uploadForm.setMethod(FormMethod.POST);
// set the (hidden) form target
uploadForm.setTarget(TARGET);
uploadForm.setAction(DEFAULT_FILE_UPLOAD_SERVICE_PATH);
// initialise the File name field
uploadItem = new UploadItem("filename");
uploadItem.setName("filename");
uploadItem.setTitle("File name");
// set the fields into the form
uploadForm.setFields(uploadItem);
// add the Upload Form and the (hidden) Frame to the main layout container
body.addMember(uploadForm);
body.addMember(frame);
And in the server side I have a servlet to handle the file upload request using Apache File Upload library, here is the code:
#Singleton
#SuppressWarnings("serial")
public class FileUploadServlet extends HttpServlet {
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.process(request, response);
}
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.process(request, response);
}
private void process(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// check that we have a file upload request
if (ServletFileUpload.isMultipartContent(request)) {
processFiles(request, response);
}
}
private File tmpDir;
private static final String DESTINATION_DIR_PATH = "/files/upload";
private File destinationDir;
public void init(ServletConfig config) throws ServletException {
super.init(config);
tmpDir = new File(((File) getServletContext().getAttribute("javax.servlet.context.tempdir")).toString());
if (!tmpDir.isDirectory()) {
throw new ServletException(tmpDir.toString() + " is not a directory");
}
Log.debug("tmpDir: " + tmpDir.toString());
String realPath = getServletContext().getRealPath(DESTINATION_DIR_PATH);
destinationDir = new File(realPath);
if (!destinationDir.isDirectory()) {
throw new ServletException(DESTINATION_DIR_PATH + " is not a directory");
}
}
private void processFiles(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// set the size threshold, above which content will be stored on disk
factory.setSizeThreshold(1 * 1024 * 1024); // 1 MB
// set the temporary directory (this is where files that exceed the threshold will be stored)
factory.setRepository(tmpDir);
// create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
try {
// parse the request
List<?> items = upload.parseRequest(request);
// process the uploaded items
Iterator<?> itr = items.iterator();
while (itr.hasNext()) {
FileItem item = (FileItem) itr.next();
// write the uploaded file to the application's file staging area
File file = new File(destinationDir, item.getName());
item.write(file);
}
} catch (FileUploadException e) {
Log.error("Error encountered while parsing the request", e);
} catch (Exception e) {
Log.error("Error encountered while uploading file", e);
}
}
}
With the above code, files upload works fine. My question is I don't know how to get the call back from servlet. One tutorial says about using the hidden frame, but I don't know how to do that. Could anyone help me with this? Thanks.
You need to write out a tag as your server response, containing JavaScript code which will execute inside the frame. This code will need to navigate out of the frame to call some function you have put into the main page (eg top.someFunction()). To set up the function in the main page, use JSNI to attach a JavaScript function to the window ($wnd in JSNI).
Note you don't have to do any of this if you're using SmartGWT Pro+ - this solution is just for people using the LGPL version.
I achieved to get a callback from my servlet in an alternate way without using JNSI.
I also use an IFRAME as target of the form so it doesn't open a new tab.
Basically it involves a table in a database to store the status of my action.
I use a timer that requests my table from an asynchronous call.
From the servlet side, it change the status of the entry created when it finished the job.
//My service creates an entry in my progressbar database
DelaiServiceAsync.Util.getInstance().launchProgressBar(
new DefaultAutoErrorHandlingAsyncCallback<Long>() {
#Override
public void onSuccess(Long pResult) {
//gets the id from the entry created
final Long token = pResult;
//I give the token to the servlet so it can update the status of the entry
tokenHItem.setDefaultValue(token.toString());
tokenHItem.setValue(token.toString());
importForm.rememberValues();
// here you can show a prompt asking the user to wait. SC.showPrompt( ... );
//form submitted to the servlet
importForm.submitForm();
//Timer setup
//timeout after 5 tick
final int size = 5;
Timer timer = new Timer() {
private int counter = 0;
private String status = "started";
#Override
public void run() {
// asynchronous call querying the table expecting a change of status
DelaiServiceAsync.Util.getInstance().getProgress(token,new DefaultAutoErrorHandlingAsyncCallback<ProgressDTO>() {
#Override
public void onSuccess(ProgressDTO pResult) {
status = pResult.getStatus();
}
#Override
public void onFailure(Throwable caught) {
super.onFailure(caught);
Log.debug(fonctionFormatee
+ "::getProgress - Failure "
+ caught.getMessage());
}
});
if (counter == size) {
//Timeout
cancel();
// we can clear the prompt here. SC.clearPrompt();
return;
}
//check the status from my response
//Here it says that my file has been written succesfully servlet side
if ("written".equals(status)) {
cancel();
// we can clear the prompt here. SC.clearPrompt();
//we leave the timer
return;
}
else if ("error".equals(status)) {
//Finished
cancel();
// we can clear the prompt here. SC.clearPrompt();
SC.error("error");
return;
}
counter++;
}
};
//delay before the timer starts
timer.schedule(10);
//time interval between timer ticks
timer.scheduleRepeating(10);
}
#Override
public void onFailure(Throwable caught) {
super.onFailure(caught);
Log.debug(fonctionFormatee + "::launchProgressBar - Failure "
+ caught.getMessage());
// we can clear the prompt here. SC.clearPrompt();
}
});
I know this is an old question but I'd like to improve #Charles Kendrick answer with sample code.
The SmartGWT documentation explains different ways to achieve this, we're interested in this part
Background upload without the Smart GWT Server
Achieving background file upload without using the Smart GWT server is also possible although considerably more advanced. In addition to the steps above, create a hidden element in the page, and use DynamicForm.target to target the form submission at this IFRAME. In order receive a callback notification when the upload completes, after processing the file upload, your server should output HTML content for the IFRAME that includes a block which will navigate out of the IFRAME (generally via the JavaScript global "top") and call a global method you have declared as a callback.
On the client side
final DynamicForm frmUpload = new DynamicForm();
NamedFrame iframeUpload = new NamedFrame("iframeUpload");
iframeUpload.setVisible(false);
frmUpload.setTarget(iframeUpload.getName());
frmUpload.setEncoding(Encoding.MULTIPART);
frmUpload.setMethod(FormMethod.POST);
UploadItem itmUpload = new UploadItem("itmProveedores", "Archivo Proveedores");
frmUpload.setItems(itmUpload);
frmUpload.setAction(GWT.getHostPageBaseURL() + "api/catalogos/upload");
IButton btnUpload = new IButton("Subir archivo proveedorees");
btnUpload.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent clickEvent) {
frmUpload.submitForm();
}
});
for this to work, we need to register the callback method using JSNI, let's do that
private static void onFileUploadFinished(){
SC.say("upload finished");
}
private native void registerOnFileUploadFinished()/*-{
$wnd.onFileUploadFinished = #com.sample.CatalogosForm::onFileUploadFinished();
}-*/;
...
/*on the constructor, load event or main entry point -it depends on your app-*/
public CatalogosForm(){
/*initial setup*/
registerOnFileUploadFinished();
}
finally, on server side we should return a script block to call the callback function. This implementation uses Apache CXF but the important part is to return the script tag to call the callback function
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.activation.DataHandler;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.List;
#Path("catalogos")
public class CatalogosREST {
private final Logger log = LoggerFactory.getLogger(CatalogosREST.class);
private String getFileName(MultivaluedMap<String, String> header) {
String[] contentDisposition = header.getFirst("Content-Disposition").split(";");
for (String filename : contentDisposition) {
if ((filename.trim().startsWith("filename"))) {
String[] name = filename.split("=");
String exactFileName = name[1].trim().replaceAll("\"", "");
return exactFileName;
}
}
return "unknown";
}
#POST
#Path("/upload")
#Consumes("multipart/form-data")
public Response uploadFile(List<Attachment> attachments, #Context HttpServletRequest request) {
log.debug("se ha recibido una peticion para subir un archivo de proveedores [attachments: {}, request: {}]", attachments, request);
Response response = null;
for (Attachment attachment : attachments) {
DataHandler handler = attachment.getDataHandler();
try {
InputStream stream = handler.getInputStream();
MultivaluedMap<String, String> map = attachment.getHeaders();
log.debug("headers: {}", map);
log.debug("fileName: {}", getFileName(map));
OutputStream out = new FileOutputStream(new File("/tmp/" + getFileName(map)));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
stream.close();
out.flush();
out.close();
StringBuilder scriptOnFileUploadFinished = new StringBuilder(
"<script type=\"application/javascript\">\n" +
" window.top.onFileUploadFinished();\n" +
" </script>"
);
response = Response.ok(scriptOnFileUploadFinished.toString()).build();
} catch (Exception e) {
String error = "Ocurrio un error al subir el archivo de proveedores";
log.error(error, e);
response = Response.serverError().entity(error).build();
}
}
return response;
}
}

Java Applet to Download files files

I have an applet that is executed in an HTML file that the user downloads and opens locally (i.e. file:// on the URL bar). This applet has a method that downloads a file from the web and stores it in a directory inside the directory where the applet is running. On my HTML file I call the function to download a file and it works but when I call it the second time, to download another file, I get a Error calling method on NPObject. I don't get any error on the Java side (I have the console open and it stays clean).
What can be the issue here? Thank you a lot for your help. Below, the code of the applet.
import java.security.*;
import java.io.*;
import java.nio.channels.*;
import java.net.*;
public class EPPenDrive extends java.applet.Applet {
public final static String baseURL = "http://localhost/data/documents/";
public String downloadFile(final String filename) {
return (String)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
try {
URL finalURL = new URL(baseURL + filename);
ReadableByteChannel rbc = Channels.newChannel(finalURL.openStream());
URL appletDir = getCodeBase();
FileOutputStream fos = new FileOutputStream(appletDir.getPath() + "documents/"+ filename);
fos.getChannel().transferFrom(rbc, 0, 1 << 24);
return 1;
} catch (Exception x) {
x.printStackTrace();
return null;
}
}
});
}
public void init() { }
public void stop() { }
}
I found the problem: the run() method would block if returning 1. I changed it to return null and now everything works. :)

Categories

Resources