I am able to upload a picture in my webapp with the struts2 framework, but i am not able to understand the path.
how to get the path of the image as a URL, so that i can use it for further processing in <img src="url"/>.
This is my action class source code and i have mentioned the URL returned in comments, but the URL does not make any sense to me. How can i decrypt it to actual URL ?
public class AddItemAction extends ActionSupport implements
ServletContextAware {
#Override
public void setServletContext(ServletContext arg0) {
// TODO Auto-generated method stub
}
File pic;
String picContentType;
String picFileName;
public File getPic() {
return pic;
}
public void setPic(File pic) {
this.pic = pic;
}
public String getPicContentType() {
return picContentType;
}
void setPicContentType(String picContentType) {
System.out.println("Setting conteent tuype" + picContentType);
this.picContentType = picContentType;
}
public void setPicFileName(String picFileName) {
this.picFileName = picFileName;
}
public String getPicFileName() {
return picFileName;
}
public String execute() {
File file = getPic();
String strFinalFullPathFileName = file.getAbsolutePath() + File.separator + picFileName;
System.out.println(strFinalFullPathFileName);
// This is the path returned
/*
* /Users/..../Catalina/localhost/.../upload_584d2719_13d5fdf593d__8000_00000000.tmp/IMG_20120526_083438.jpg
*
*
*/
return SUCCESS;
}
}
Uploaded artifacts should be stored outside the web app structure.
In addition, by default, the file upload interceptor deletes the temporary files created during the upload process. That should either be turned off, or the file should be copied to a known location so they can be either (a) streamed back via an action, or (b) served directly if you set up your container to serve static assets outside of the normal web structure.
seems like you are uploading your file to a temp folder, what you should do is move this file to a folder inside your web app
you case use request.getServletContext().getRealPath(YOUR_PATH) to get a path where to move the file
YOUR_PATH being something like "/uploadimage/img.png" => uploadimage being a folder directly in you webapp
Related
I have implemented a function to download aws s3 files using the following code:
public void credentialsProvider()
{
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
getApplicationContext(), "us-east-2:xxxxxx-xxxxx-xxxxx-xxxx-xxxxxxx", Regions.US_EAST_2
);
setAmazonS3Client(credentialsProvider);
System.out.println("setAmazonS3Client done");
}
public void setAmazonS3Client( CognitoCachingCredentialsProvider credentialsProvider)
{
s3 = new AmazonS3Client(credentialsProvider);
s3.setRegion(Region.getRegion(Regions.US_EAST_2));
}
public void setTransferUtility()
{
transferUtility = new TransferUtility(s3, getApplicationContext());
System.out.println("setTransferUtility done");
}
public void setFileDownload()
{
final String path = this.getFilesDir().getAbsolutePath();
File myFile = new File(path);
TransferObserver transferObserver = transferUtility.download("sample-bucket-001", "images-4.jpeg", myFile);
transferObserverListener(transferObserver);
}
public void transferObserverListener(TransferObserver transferObserver)
{
transferObserver.setTransferListener(new TransferListener() {
#Override
public void onStateChanged(int id, TransferState state) {
System.out.println("onStateChanged: "+ state);
if(state == TransferState.FAILED || state == TransferState.WAITING_FOR_NETWORK){
}
}
#Override
public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
int percentage = (int)(bytesCurrent/bytesTotal * 100);
System.out.println("percentage: "+ percentage);
}
#Override
public void onError(int id, Exception ex) {
System.out.println("Error faced: "+ ex.toString());
}
});
}
As I try to execute the following code I get the following error:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xxxxxx.xxxxxxxx/com.xxxxxx.xxxxxxxx.Activity}: java.lang.IllegalArgumentException: Invalid file: /data/user/0/com.xxxxxx.xxxxxxxx/files/
I cannot save the file on external storage as I prefer to have them hidden and protected, and deleted in case the app got deleted. I used to use the path to save files on it, that are directly loaded from the internet and no problem there.
Kindly advise on the matter.
The file path supplied to TransferUtility needs to include a file name, e.g.:
final String path = this.getFilesDir().getAbsolutePath() + "images-4.jpeg";
I have finally found the solution to the question asked, which simple using a path that is totally new, unused previously, so it can create the folder that where it will store the downloaded picture or file.
final String path = this.getFilesDir().getAbsolutePath()+"/zip";
I wish Amazon's feedback could be a bit more specific than just 'invalid file'.
Am very very new to Vaadin. Am setting up the project by looking into Github and other docs, where am using Spring-security, Vaadin, Maven.
I created sample vaadin-maven with spring security project. Now am getting login page then after suucessful login, am getting some MainView.java.
Am trying to change the upload .xls file and read that file and do some functionality and then download pop-up.
I have followed http://demo.vaadin.com/sampler/#ui/data-input/other/upload , but errors. unable to reproduce my output.
For now, am able to read the file using path " final String FILE_PATH = "F://input.xls";" But, i need option to upload the file and then use that file for further functionality.
After the functionality completed, i need to download the file.
Please suggest me how can i browse the file and upload and use the uploaded file for ding some read and write operation and then download Vaadin.
Am having sleepless nights for this. Please suggest me how can i come out of this.
Here is my code:
#Component
#Scope("prototype")
#VaadinView(RoleAdminView.NAME)
#Secured("ROLE_ADMIN")
public class RoleAdminView extends Panel implements View
{
public static final String NAME = "role_admin";
#PostConstruct
public void PostConstruct()
{
LoggerFactory.getLogger(this.getClass()).debug("POST");
setSizeFull();
VerticalLayout layout = new VerticalLayout();
layout.setSpacing(true);
layout.setMargin(true);
layout.addComponent(new Button());
layout.addComponent(new Label("ROLE_ADMIN"));
layout.addComponent(new Link("Go back", new ExternalResource("#!" +
MainView.NAME)));
setContent(layout);
}
#Override
public void enter(ViewChangeListener.ViewChangeEvent event)
{
}
}
A big thank you in advance. Hope you guys sort out my issue :)
You can do,
public class RoleAdminView extends Panel implements View{
//add a button view
//
#Override
public void uploadFailed(Upload.FailedEvent event) {
Notification.show(event.getFilename() + "----" + event.getMIMEType());
//here it will show the error if upload failed
}
#Override
public void uploadSucceeded(SucceededEvent event) {
/// do your functionlity
}
#Override
public OutputStream receiveUpload(String filename, String mimeType) {
FileOutputStream fos = null;
// do your functionality to save in any path or server path
return fos; // Return the output stream to write to
}
}
I hope this my help you :)
I am trying to provide capability to upload file in my vaadin application
protected Upload questionImageUpload = new Upload("Upload question", questionReceiver);
questionImageUpload.addFinishedListener(new Upload.FinishedListener() {
#Override
public void uploadFinished(Upload.FinishedEvent event) {
boolean hasLock = VaadinSession.getCurrent().hasLock();
button.setEnabled(false);
}
});
But, in my FinishListener.uploadFinished(), if I modify some UI element (in above, I disable a button), the modification does not get applied.
I assumed that this method may be invoked in a non UI thread so I checked whether VaadinSession is available by putting a breakpoint in uploadFinished above. But, VaadinSession.getCurrent() didn't return null. Also hasLock is also true.
What could be the reason?
I am running this vaadin application on Google App Engine (still running locally inside IntelliJ IDEA). Could that be the reason behind this?
File upload is done as a POST request to the server, containing the file data. When the upload is complete, Upload.FinishedListeners are called at the end of that POST request. While all thread locals are set up correctly, this is not a UI update request (or UIDL request) and the response which is sent to the browser only contains a text that informs the browser that the upload finished. Any UI updates done will be queued until another request asks for them.
Because of this, you need to either use #Push, so that the UI changes are pushed immediately to the client through the push channel, or enable polling at the latest when starting the upload, so that the poll request will pick up the UI changes.
I actually accomplish what you want to do with a SuccedListener. I have a code which updates an embedded component with picture uploaded. You can look at the code and take a cue from it. It can also disable the button. You can correct it not optimised but it works
public class PicUploader extends Upload implements SucceededListener, Receiver {
private static final long serialVersionUID = 1L;
File file;
public String fileName;
final String LOCATION = "/home/###";
Embedded image = new Embedded();
TextField field;
public PicUploader(Embedded image, String caption) {
this.image = image;
this.addSucceededListener(this);
this.setReceiver(this);
this.setCaption(caption);
this.setIcon(FontAwesome.UPLOAD);;
}
public PicUploader(Embedded image, TextField field) {
this.image = image;
this.addSucceededListener(this);
this.setReceiver(this);
this.field = field;
this.setButtonCaption(""+FontAwesome.UPLOAD);
this.setIcon(FontAwesome.UPLOAD);;
}
#Override
public OutputStream receiveUpload(String filename, String mimeType) {
// TODO Auto-generated method stub
FileOutputStream stream = null;
try {
file = new File(LOCATION
+ "/Pictures/"
+ System.currentTimeMillis()
+ filename.substring(filename.length() - 4,
filename.length()));
fileName = file.getName();
System.out.println("This is the file name " + filename);
stream = new FileOutputStream(file);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
return stream;
}
#Override
public void uploadSucceeded(SucceededEvent event) {
// TODO Auto-generated method stub
image.setSource(new FileResource(file));
image.setVisible(true);
image.setWidth("150");
image.setHeight("200");
// float ratio = image.getHeight()/image.getWidth();
// image.setWidth(""+image.getWidth());
// image.setHeight(""+image.getHeight());
// field.setValue(getFileName());
this.setEnabled(false);
}
public String getFileName() {
return fileName;
}
}
I'm using JSF with primefaces and want to display an image from java code.
I already saw the tutorial on http://www.primefaces.org/showcase/ui/dynamicImage.jsf
But I'm not clear on how I can get the path to my image file correctly:
Code:
Bean:
#ManagedBean
public class ABean {
private StreamedContent bStatus;
public ABean() {
try {
Boolean connected = false;
if (connected == true) {
bStatus = new DefaultStreamedContent(new FileInputStream(new File("/images/greendot.png")), "image/jpeg");
} else {
bStatus = new DefaultStreamedContent(new FileInputStream(new File("/images/reddot.png")), "image/jpeg");
}
} catch(Exception e) {
e.printStackTrace();
}
}
public StreamedContent getBStatus() {
return bStatus;
}
public void setBStatus(StreamedContent bStatus) {
this.bStatus = bStatus;
}
}
xhtml:
<p:graphicImage value="#{ABean.bStatus}" />
returns:
java.io.FileNotFoundException: \images\reddot.png
I would appreciate best practices on where to store my image when displaying it form code and how to do it.
Since your images are in your web folder, you don't really need to use DefaultStreamedContent. I'd leave that only for images generated on the fly.
For your case, I'd just create a simple method that returns the image path (in your web folder) based on the boolean variable. Something like this:
public String getImagePath(){
return connected ? "/images/greendot.png" : "/images/reddot.png";
}
And on the graphicImage, you can just reference that:
<p:graphicImage value="#{yourBean.imagePath}"/>
Note that you might have to adjust the graphicImage tag if your web context is not root.
EDIT
You can actually make this even simpler:
<p:graphicImage value="#{yourBean.connected ? '/images/greendot.png' : '/images/reddot.png'}"/>
Just make sure to have a getter for the connected property.
Create your StreamedContent as follows:
bStatus = new DefaultStreamedContent(FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/images/greendot.png"), "image/jpeg");
When you are creating new File() this will be absolute path in your disk, not just in your application.
I am writing a custom event and would like some help please. Most of what I am about to talk about is based on the help provided at Custom event listener on Android app
So here is my issue. I am writing an app that needs to download updated images from the web, store the images on the phone, then later display those images. Basically, I download any needed images during a splash screen. Then when the images are downloaded and stored, the splash screen clears and any necessary (newly downloaded) images are displayed on the screen. Here is the problem: the download process is done via an asynctask so the part where the images are loaded on to the screen can't be done inside the asynctask. It has to be done on the main UI thread. I would like to create an event and a custom event listener for the main thread to listen for that basically tells the main UI thread that it is safe to start loading the downloaded images from memory.
According to the discussion from the link above, I came up with this so far... a download listener interace
public interface DataDownloadListener {
void onDownloadStarted();
void onDownloadFinished();
}
an event class...
public class DataDownloadEvent {
ArrayList<DataDownloadListener> listeners = new ArrayList<DataDownloadListener>();
public void setOnDownload(DataDownloadListener listener){
this.listeners.add(listener);
}
}
My problem is that I don't understand where to put the last two steps in those instructions. I thought I would have to put the listener and event inside the class that actually initiates the downloads. But where? Here is my function that initiates the download and saves it to the device:
public String download(String sourceLocation) {
String filename = "";
String path = "";
try {
File externalStorageDirectory = Environment
.getExternalStorageDirectory();
URL urlTmp = new URL(sourceLocation);
filename = urlTmp.getFile()
.substring(filename.lastIndexOf("/") + 1);
path = externalStorageDirectory + PATH;
// check if the path exists
File f = new File(path);
if (!f.exists()) {
f.mkdirs();
}
filename = path + filename;
f = new File(filename);
//only perform the download if the file doesn't already exist
if (!f.exists()) {
Bitmap bitmap = BitmapFactory.decodeStream(urlTmp.openStream());
FileOutputStream fileOutputStream = new FileOutputStream(
filename);
if (bitmap != null) {
bitmap.compress(getFormat(filename), 50, fileOutputStream);
Log.d(TAG, "Saved image " + filename);
return filename;
}
}
else{
Log.d(TAG, "Image already exists: " + filename + " Not re-downloading file.");
}
} catch (MalformedURLException e) {
//bad url
} catch (IOException e) {
//save error
}
return null;
}
And the last step about registering the listener, where do I put that? The instructions say to put that somewhere during initialization. Does that mean in the onCreate method of my main activity? outside the class in the import section of the main activity? Never done a custom event before, so any help would be appreciated.
According to the discussion from the link above, I came up with this so far... a download listener interace
public interface DataDownloadListener {
void onDownloadStarted();
void onDownloadFinished();
}
an event class...
public class DataDownloadEvent {
ArrayList<DataDownloadListener> listeners = new ArrayList<DataDownloadListener>();
public void setOnDownload(DataDownloadListener listener){
this.listeners.add(listener);
}
}
Ok...
Now in your download procedure, at the start of the download, cycle all the elements on the listeners ArrayList and invoke the onDownloadStarted event to inform all your listeners that the download is just started (in this event i presume you'll need to open the splashscreen).
Always in your download procedure, at the and of the download, cycle all the elements on the listeners ArrayList and invoke the onDownloadFinished event to inform all your listeners that the download is finished (now close the splashscreen).
How to cycle listeners on download completed
foreach(DataDownloadListener downloadListener: listeners){
downloadListener.onDownloadFinished();
}
How to cycle listeners on download started
foreach(DataDownloadListener downloadListener: listeners){
downloadListener.onDownloadStarted();
}
Don't make it static if possible... In the class that you'll use to download your files, simply add what you put in your DataDownloadEvent class (listeners arrayList and facility methods for adding and removing). You have no immediate need to use a class in that way (static members I mean).
Example
public class DownloadFileClassExample{
private ArrayList<DataDownloadListener> listeners = new ArrayList<DataDownloadListener>();
public DownloadFileClassExample(){
}
public void addDownloadListener(DataDownloadListener listener){
listeners.add(listener);
}
public void removeDownloadListener(DataDownloadListener listener){
listeners.remove(listener);
}
//this is your download procedure
public void downloadFile(){...}
}
Then access you class in this way
DownloadFileClassExample example = new DownloadFileClassExample();
example.addDownloadListener(this); // if your class is implementing the **DataDownloadListener**
or use
example.addDownloadListener( new DataDownloadListener{...})