I have coded a AJAX file upload feature in my application. It works perfectly when running it from my laptop. When I try the exact same file using the same app, but deployed on a jBoss server, I get the following exception:
2013-02-18 11:30:02,796 ERROR [STDERR] java.io.FileNotFoundException: C:\Users\MyUser\Desktop\TestFile.pdf (The system cannot find the file specified).
getFileData method:
private byte[] getFileData(File file) {
FileInputStream fileInputStream = null;
byte[] bytFileData = null;
try {
fileInputStream = new FileInputStream(file);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
if (fileInputStream != null) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bytBuffer = new byte[1024];
try {
for (int readNum; (readNum = fileInputStream.read(bytBuffer)) != -1;) {
byteArrayOutputStream.write(bytBuffer, 0, readNum);
}
} catch (IOException e) {
e.printStackTrace();
}
bytFileData = byteArrayOutputStream.toByteArray();
}
return bytFileData;
}
Getting the file content in a variable (from the method above):
byte[] bytFileData = this.getFileData(file);
Making the file:
private boolean makeFile(File folderToMake, File fileToMake, byte[] bytFileData) {
Boolean booSuccess = false;
FileOutputStream fileOutputStream = null;
try {
if (!folderToMake.exists()) {
folderToMake.mkdirs();
}
if (!fileToMake.exists()) {
if (fileToMake.createNewFile() == true) {
booSuccess = true;
fileOutputStream = new FileOutputStream(fileToMake);
fileOutputStream.write(bytFileData);
fileOutputStream.flush();
fileOutputStream.close();
}
}
} catch (Exception e) {
e.printStackTrace();
booSuccess = false;
}
return booSuccess;
}
Any idea?
Thank you
Charles
It seems you're just passing the file path as part of the request to the server, not actually uploading the file, then attempting to use that file path to access the file.
That will work on your laptop because the code, when running locally, has access to your file system and will be able to locate the file. It won't work deployed on a server because it's an entirely separate machine, and as a result won't have access to your file system.
You'll need to modify your client-side (AJAX) code to actually upload the file, then modify your server-side code to use that uploaded file. Note that AJAX file uploads aren't generally possible - there are plugins for frameworks such as jQuery that provide this functionality using workarounds.
I'm not 100%, but I think proper AJAX file uploads may be possible using HTML5 features, but browser support for that is likely going to be pretty poor right now.
Related
I'm trying to upload zip file to the url https://anypoint.mulesoft.com/designcenter/api-designer/projects/{projectId}/branches/master/import. Content-Type must be application/zip, cant change to multipart/form-data. In Mule 3, a java transform class is used (com.test.FileReader) with the FileReader.class is stored in lib. It worked in Mule 3.
I tried to use ReadFile component to read test.zip and set as payload but it's not working. Any suggestion how to upload zip file in Mule 4?
package com.test;
import org.mule.transformer.*;
import org.mule.api.*;
import org.mule.api.transformer.*;
import java.io.*;
public class PayloadFileReader extends AbstractMessageTransformer
{
public Object transformMessage(final MuleMessage message, final String outputEncoding) throws TransformerException {
byte[] result = null;
try {
result = this.readZipFile("test.zip");
}
catch (Exception e) {
e.printStackTrace();
}
message.setPayload((Object)result);
return message;
}
public String readFileTest(final String path) throws FileNotFoundException, IOException, Exception {
final ClassLoader classLoader = this.getClass().getClassLoader();
final File file = new File(classLoader.getResource(path).getFile());
final FileReader fileReader = new FileReader(file);
BufferedReader bufferReader = null;
final StringBuilder stringBuffer = new StringBuilder();
try {
bufferReader = new BufferedReader(fileReader);
String line;
while ((line = bufferReader.readLine()) != null) {
stringBuffer.append(line);
}
}
catch (IOException e) {
e.printStackTrace();
if (bufferReader != null) {
try {
bufferReader.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
finally {
if (bufferReader != null) {
try {
bufferReader.close();
}
catch (IOException e2) {
e2.printStackTrace();
}
}
}
return stringBuffer.toString();
}
public byte[] readZipFile(final String path) {
final ClassLoader classLoader = this.getClass().getClassLoader();
final File file = new File(classLoader.getResource(path).getFile());
final byte[] b = new byte[(int)file.length()];
try {
final FileInputStream fileInputStream = new FileInputStream(file);
fileInputStream.read(b);
fileInputStream.close();
}
catch (FileNotFoundException e) {
System.out.println("Not Found.");
e.printStackTrace();
}
catch (IOException e2) {
System.out.println("Error");
e2.printStackTrace();
}
return b;
}
}
'
Assuming that your zip file corresponds to a valid API spec, in Mule 4, you don't need to use a custom java code to achieve what you want: you can read the file content using the File connector Read operation, and use an HTTP Request to upload it to Design Center using Design Center API. Your flow should look like:
For the Read operation, you only need to set the file location, in the File Path operation property.
No need to set content type in the HTTP Request (Mule 4 will configure the content type automatically based on the file content loaded by the Read operation).
You can't use Java code that depends on Mule 3 classes in Mule 4. Don't bother trying to adapt the code, it is not meant to work. Their architecture are just different.
While in Mule 4 you can use plain Java code or create a module with the SDK, there is no reason to do so for this problem and it would be counterproductive. My advise it to forget the Java code and resolve the problem with pure Mule 4 components.
In this case there doesn't seem a need to actually use Java code. The File connector read operation should read the file just fine as it doesn't appear the Java code is doing anything else than reading the file into the payload.
Sending through the HTTP Request connector should be straightforward. You didn't provide any details of the error, (where is it happening, complete error message, HTTP status error code, complete flow with the HTTP request in both versions, etc) and the API Designer REST API doesn't document an import endpoint so it is difficult to say if the request is correctly constructed.
So the intention is simple, I want to copy the files from the APK's assets folder to the device storage. I achieved that with the below code and it was actually working,
public void copyAssets() {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = getAssets().list("sourcedir");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
if (files != null) for (String filename : files) {
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filename);
File folder = new File(Environment.getExternalStorageDirectory() + File.separator + "TargetFol");
if (!folder.exists()) {
folder.mkdirs();
}
File outFile = new File(folder, filename);
out = new FileOutputStream(outFile);
copyFile(in, out);
} catch (IOException e) {
Log.e("tag", "Failed to copy asset file: " + filename, e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// NOOP
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
// NOOP
}
}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
}
getAssets().list("sourcedir") actually lists all the images in the sourcedir in the assets folder of the APK.
But when the method called it throws FileNotFoundException: myfile.png for few files only.
For example, I put 5 png in the sourcedir (1.png, 2.png, 3.png, myfile.png, zip.png) All files copied except the myfile.png
I verified that there is no different extension or whatsoever also I had analyzed the APK and all these 5 images are actually there in assets/sourcedir
LOGCAT:
E/tag: Failed to copy asset file: myfile.png
java.io.FileNotFoundException: myfile.png
at android.content.res.AssetManager.nativeOpenAsset(Native Method)
at android.content.res.AssetManager.open(AssetManager.java:833)
at android.content.res.AssetManager.open(AssetManager.java:810)
at org.pac.pac.act.copyAssets(act.java:97)
at org.pac.pac.act$2.run(act.java:78)
at java.lang.Thread.run(Thread.java:919)
2020-10-04 21:06:13.189 30767-30999/packagename E/tag: Failed to copy asset file: myfile2.png
java.io.FileNotFoundException: myfile2.png
at android.content.res.AssetManager.nativeOpenAsset(Native Method)
at android.content.res.AssetManager.open(AssetManager.java:833)
at android.content.res.AssetManager.open(AssetManager.java:810)
at org.pac.pac.act.copyAssets(act.java:97)
at org.pac.pac.act$2.run(act.java:78)
I added another one PNG with the name of myfile2.png and gives the same issue.
UPDATE:
So instead of getting all files I tried to add myfile.png in the inputstream but this also returns the same exception even though the file was exists at the assets/sourcedir folder.
Found the solution, it may help others too. So if you're getting multiple files from the subfolder in the assets directory, make sure to include the subfolder name while calling. In my case it was,
in = assetManager.open(filename);
So adding the subfolder name along with the filename fixed the issue.
in = assetManager.open("sourcedir/" + filename);
Thanks to #CommonsWare who let me know this mistake. Fun fact I copied this method from one StackOverflow's question with high upvotes and accepted as an answer but nobody mentioned this issue in the comment. Yeah, it's a simple mistake, my bad.
I am trying to download a file from Google Drive. Download of a common file (pdf, jpg) went without any problem. But I can't get it to download Google files. I am getting an empty file without type and with size 0. Do you have any idea of what might cause this?
public InputStream download(String id) throws CloudServiceException {
try {
File file = service.files()
.get(id)
.execute();
String link = file.getExportLinks().get("application/pdf");
HttpResponse resp = service.getRequestFactory()
.buildGetRequest(
new GenericUrl(link))
.execute();
return resp.getContent();
} catch (HttpResponseException e) {
throw CloudServiceExceptionTransformer.transform(e, e.getStatusCode());
} catch(IOException ex) {
throw new InternalException(ex);
}
}
You need to use Export method for downloading google docs or any google files
String fileId = "1ZdR3L3qP4Bkq8noWLJHSr_iBau0DNT4Kli4SxNc2YEo";
OutputStream outputStream = new ByteArrayOutputStream();
driveService.files().export(fileId, "application/pdf")
.executeMediaAndDownloadTo(outputStream);
You can try this:
URL url = new URL("http://www.gaertner-servatius.de/images/sinnfrage/kapitel-2/spacetime.gif");
InputStream inStream = url.openStream();
Files.copy(inStream, Paths.get("foobar.gif"), StandardCopyOption.REPLACE_EXISTING);
inStream.close();
Try this:
com.google.api.services.drive.Drive service;
static InputStream download(String id) {
if (service != null && id != null) try {
com.google.api.services.drive.model.File gFl =
service.files().get(id).setFields("downloadUrl").execute();
if (gFl != null){
return service.getRequestFactory()
.buildGetRequest(new GenericUrl(gFl.getDownloadUrl())).execute().getContent());
}
} catch (Exception e) { e.printStackTrace(); }
return null;
}
Good Luck
So the problem was in fact in building of a response. Google files have a size 0 and google media type was not recognized which resulted in this broken file.
Edit: Here is my working version. I removed the set size so that it downloads those 0 sized files.
ResponseEntity.BodyBuilder builder = ResponseEntity.status(HttpStatus.OK)
.header(HttpHeaders.CONTENT_DISPOSITION, encoding)
.contentType(MediaType.parseMediaType(resource.getMimeType()));
return builder.body(new InputStreamResource(resource.getContent()));
I faced with a weird problem. I write android application for downloading mp3 files. I download mp3 with url, it works fine. But any player except VLC can not find these downloaded mp3 files on device. And if I use any file manager I can find these files but they dont have mp3 tags.
For example.
This is a file downloaded with my application. I open its properties with FX file manager.
And it is mp3 downloaded with another program (not mine). As you can see the file has mp3 tags (shown in bottom of screen)
It is my code for downloading files:
#Override
protected Void doInBackground(String... params) {
InputStream inputStream = null;
FileOutputStream fileOutput = null;
try {
URL url = new URL(params[0]);
File file = new File(path);
URLConnection urlConnection = url.openConnection();
inputStream = urlConnection.getInputStream();
fileOutput = new FileOutputStream(file);
int totalSize = urlConnection.getContentLength();
int downloadedSize = 0;
byte[] buffer = new byte[16384];
int bufferLength = 0;
while ((bufferLength = inputStream.read(buffer)) > 0 ) {
while(isPaused) {
sleep();
}
if(isCancelled()) {
if(file.exists())
file.delete();
return null;
}
fileOutput.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
publishProgress(downloadedSize, totalSize);
}
if(totalSize > getFreeMemorySize()) {
//if(true) {
if(errorHandler != null)
errorHandler.onMemorySizeException();
cancel(true);
}
} catch (IOException e) {
int i = e.hashCode();
e.getStackTrace();
}
finally {
try {
if(inputStream != null)
inputStream.close();
if(fileOutput != null)
fileOutput.close();
} catch (IOException e) {
int i = e.hashCode();
e.getStackTrace();
}
}
return null;
}
Where I am wrong? Why mp3-files downloaded with my application can npt be found with mp3-players? How could I fix it?
What you are observing is the fact that MediaStore does not constantly update his database. Database is updated only after reboot and after sd card is mounted.
If you want your files to appear immediately you have to tell MediaStore to add them.
Use MediaScannerConnection.scanFile method to notify MediaStore. (MediaScannerConnection doucumentation) Note that you can add multiple files/paths at once. Also worth noting is that this method is asynchronous, files are added in a separate process and this can take some time - you are notified when operation is completed.
MediaScannerConnection.scanFile(
context,
new String[]{file.getAbsolutePath()},
null,
new OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
// only at this point are files in MediaStore
}
});
How can i retrieve and read local file using fileinputstream using Java 7. Something like this but for a local file. With the new security settings, I cant get it to work
public static InputStream openReading(String file)
throws FileNotFoundException
{
try
{
PersistenceService pService = (PersistenceService) ServiceManager
.lookup(PersistenceService.class.getCanonicalName());
URL fileurl = new URL(getCode() + file);
FileContents fc= pService.get(fileurl);
fc.setMaxLength(10240000);
InputStream in= fc.getInputStream();
return stream;
}
catch (MalformedURLException m)
{
m.printStackTrace();
}
catch (FileNotFoundException f)
{
throw new FileNotFoundException(f.getMessage());
}
}
ExtendedService.openFile is the equivalent for opening a file. That gives read/write access. There is no option to ask for read-only!