How to create MultipartFile with location file (path) - java

I have location file (C:\fakepath\Code.txt) . I want to create MultipartFile with this location. My Code:
public void fileUpload(String locationFile) {
Path path = Paths.get(locationFile);
String name = "Code.txt";
String originalFileName = "Code.txt";
String contentType = "text/plain";
byte[] content = null;
try {
content = Files.readAllBytes(path);
} catch (final IOException e) {
}
MultipartFile file = new MockMultipartFile(name, originalFileName, contentType, content);
try {
// Get the file and save it somewhere
byte[] bytes = file.getBytes();
Path paths = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());
Files.write(paths, bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
Also in this code I need type my file name it's not correct for my opinion. How to create MultipartFile and save somewhere? with location

In Windows you need double slashes "C://fakepath//Code.txt"

Related

Unable to get URI of a text file

I am trying to make an app in which I can take text input from the user store it in a text file and then upload that file to firebase so that I can retrieve it later.
The issue is that I am unable to get the correct URI of the file. Please help me get the URI.
Here is the code
public class TextUpload extends AppCompatActivity {
private void writeToFile(String data, Context context) throws FileNotFoundException {
mediaFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
if (!mediaFile.exists()) {
mediaFile.mkdir();
}
byte[] data2 = data.getBytes();
FileOutputStream f = new FileOutputStream(new File(mediaFile, "textfile.txt"));
try {
f.write(data2);
f.flush();
f.close();
} catch (IOException e) {
e.printStackTrace();
}
fileUri = Uri.fromFile(mediaFile);
Log.d("TAHH" , "URI = "+fileUri);
}
}
This is the value I'm getting stored at fileUri
URI = file:///storage/emulated/0
[
Please help me get the URI of the highlighted file.
Main problem is that you are reading the path of mediaFile which is a directory (not the file itself). mediaFile is the parent directory of the file that you want.
So, change to this:
mediaFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
if (!mediaFile.exists()) {
mediaFile.mkdir();
}
byte[] data2 = data.getBytes();
// Hold the reference to the file that you are writting
File txtFile = new File(mediaFile, "textfile.txt")
FileOutputStream f = new FileOutputStream(txtFile );
try {
f.write(data2);
f.flush();
f.close();
} catch (IOException e) {
e.printStackTrace();
}
// Here, use txtFile instead of mediaFile
fileUri = Uri.fromFile(txtFile);
Log.d("TAHH" , "URI = "+fileUri);

Broken Image when uploading using Rest Controller Multipart File

When i try to upload image in my RestController using MultipartFile, sometimes it creates a broken image (which doesn't open, just has some trashes inside file). It happens when i try to send (through Postman) images fast.
Here is my Controller:
#PostMapping("/upload/photo")
public ResponseEntity<ServerResponse> uploadPhoto(#RequestParam MultipartFile file, HttpServletRequest httpServletRequest) {
UserAccount userAccount = getPrincipal();
String localAddress = "http://" + getServerUrl(httpServletRequest);
ServerResponse response = userAccountService.addPhoto(userAccount, file, localAddress);
return getResponseEntity(response);
}
And my Service:
#Override
public ServerResponse<String> addPhoto(UserAccount userAccount, MultipartFile file, String localAddress) {
String uploadFilePath = uploadFile(file);
if(uploadFilePath.isEmpty()) {
return new ServerResponse<>(ResponseStatus.BAD_REQUEST, "Please select a file to upload", "");
}
final String PHOTO_URL = localAddress + "/" + uploadFilePath;
userAccount.setPhoto(PHOTO_URL);
userAccountRepository.save(userAccount);
return new ServerResponse<>(ResponseStatus.OK, null, PHOTO_URL);
}
private String uploadFile(MultipartFile file) {
if (file.isEmpty()) {
return "";
}
final String UPLOADED_FOLDER = "photos";
String uniqueName = generateRandomString();
String filePath = UPLOADED_FOLDER + "/" + uniqueName + file.getOriginalFilename();
new File(UPLOADED_FOLDER).mkdirs();
try {
byte[] bytes = file.getBytes();
Path path = Paths.get(filePath);
if (Files.exists(path)){
uniqueName = generateRandomString();
filePath = UPLOADED_FOLDER + "/" + uniqueName + file.getOriginalFilename();
path = Paths.get(filePath);
}
Files.write(path, bytes);
} catch (IOException e) {
e.printStackTrace();
}
return filePath;
}
I also tried to read multipart file as InputStream, but didin't help.
try (InputStream inputStream = file.getInputStream()) {
Files.copy(inputStream, path,
StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
}
I think the problem is, when i try to send couple images at the pretty same time it just can't handle that?

create a temporary file with a specified name in java

I have a Byte[] array that i want to put it's content into a temporary file .
I have tryied to do it like this
try {
tempFile = File.createTempFile("tmp", null);
FileOutputStream fos = new FileOutputStream(tempFile);
fos.write(sCourrier.getBody());
} catch (IOException e) {
e.printStackTrace();
}
but i want that I specify the filename by myself so not generated by the jvm
You can directly give the location and file name or You can access local filesystem and find the temp directory
String tempDir=System.getProperty("java.io.tmpdir");
you can use temp directory and your custom file name.
public static void main(String[] args) {
try {
String tempDir=System.getProperty("java.io.tmpdir");
String sCourrier ="sahu";
File file = new File(tempDir+"newfile.txt");
FileOutputStream fos = new FileOutputStream(file);
fos.write(sCourrier.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
You can use Guava Files.createTempDir():
File file = new File(Files.createTempDir(), fileName.txt);
But because the API is deprecated and they also recommend to use Nio with more params:
Path createTempDirectory(String prefix, FileAttribute<?>... attrs)
so it would be better if you have a method yourself:
File createTempFile(String fileName, String content) throws IOException {
String dir = System.getProperty("java.io.tmpdir");
File file = new File(dir + fileName);
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(content.getBytes(StandardCharsets.UTF_8));
}
return file;
}

Download the byte array as a original file in AngularJS from server

I have the below requirement,
Java server will send the below details by reading the file from server (it can be pdf, doc or image)
Java code:
public static byte[] downloadFileAsStream(String fileName) throws IOException, MalformedURLException
File file = new File(fileName);
if (!file.exists()) {
// File not found
return null;
}
try {
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
return readFileAsByte(file.getAbsolutePath());
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
return null;
}
private static byte[] readFileAsByte(String filePath) {
try {
Path path = Paths.get(filePath);
return Files.readAllBytes(path);
} catch (IOException ex) {
ex.printStackTrace();
}
return new byte[0];
}
server will return the file as byte array, then this needs to be converted as the original file AngularJS and download
You need to add the response header in server side like below.
response.setHeader("Content-Type", "application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=sample.pdf");
The following code may be used to create a file on client side based on the response from server:
$http.post("<SERVER_URL>", "<PARAMS_IF_ANY>", {
responseType:'arraybuffer'
}).success(function(data, status, headers) {
var contentType = headers["content-type"] || "application/octet-stream";
var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
if (urlCreator) {
var blob = new Blob([data], { type: contentType });
var url = urlCreator.createObjectURL(blob);
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
a.href = url;
a.download = "download.pdf"; //you may assign this value from header as well
a.click();
window.URL.revokeObjectURL(url);
}
}

Azure storage through java MVC web site

I have a java web app using Spring and hibernate framework. I am moving this web app on azure. In on premises web app there is one functionality in which I upload the image first in a temporary folder in C: and later access that file for application. The location of uploaded file is also stored in DB for further references. I have defined the base-path for uploading file in a properties file and accessing through it in controller as well as service layer for creating the directory, file name and file path.
Can any tell me how to do the same in azure using azure storage? Any help is appreciated.
Code in properties file:
# Base File Path for Uploading Files
fileupload.basepath=C:/webApp
Code for creating temporary folder
#RequestMapping(value = "/file/upload", method = RequestMethod.POST)
public #ResponseBody
String upload(MultipartHttpServletRequest request,
HttpServletResponse response) {
// 0. notice, we have used MultipartHttpServletRequest
// 1. get the files from the request object
Iterator<String> itr = request.getFileNames();
MultipartFile mpf = request.getFile(itr.next());
if (!CommonUtil.isNull(mpf)) {
if (mpf.getSize() > ProductCommonConstants.MAX_FILE_UPLOAD_SIZE_IN_BYTES) {
return CommonConstants.STR_FAILURE;
}
}
long fileName = Calendar.getInstance().getTimeInMillis();
final String modelImageDirPath = baseUploadFilePath + "/"
+ CommonConstants.TEMP_FILE_NAME;
// Check for folder existence
final File modelImageDir = new File(modelImageDirPath);
if (!modelImageDir.exists()) {
// Create the directory
modelImageDir.mkdirs();
}
InputStream is = null;
FileOutputStream fos = null;
try {
String contentType = mpf.getContentType();
if (contentType != null) {
is = new DataInputStream(mpf.getInputStream());
// just temporary save file info
File file = new File(modelImageDirPath + "/" + fileName);
fos = new FileOutputStream(file);
// Write to the file
IOUtils.copy(is, fos);
}
} catch (FileNotFoundException ex) {
} catch (IOException ex) {
} finally {
try {
if (fos != null) {
fos.close();
}
if (is != null) {
is.close();
}
} catch (IOException ignored) {
// Log the Exception
}
}
// 2. send it back to the client as <img> that calls get method
// we are using getTimeInMillis to avoid server cached image
return "/service/common/file/get/" + fileName;
}
}
Per my experience, you can use the upload(InputStream sourceStream, long length) of Class CloudBlob to upload files from Spring MVC MultipartFile to Azure Blob Storage, please see the code below modified from your code.
#RequestMapping(value = "/file/upload", method = RequestMethod.POST)
public #ResponseBody String upload(MultipartHttpServletRequest request,
HttpServletResponse response) {
// 0. notice, we have used MultipartHttpServletRequest
// 1. get the files from the request object
Iterator<String> itr = request.getFileNames();
MultipartFile mpf = request.getFile(itr.next());
if (!CommonUtil.isNull(mpf)) {
if (mpf.getSize() > ProductCommonConstants.MAX_FILE_UPLOAD_SIZE_IN_BYTES) {
return CommonConstants.STR_FAILURE;
}
}
long fileName = Calendar.getInstance().getTimeInMillis();
// Modified from your code: START
String storageConnectionString = "DefaultEndpointsProtocol=http;" + "AccountName=your_storage_account;" + "AccountKey=your_storage_account_key";
CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString);
CloudBlobClient blobClient = storageAccount.createCloudBlobClient();
CloudBlobContainer container = blobClient.getContainerReference("<blob-container-name>");
InputStream is = null;
try {
String contentType = mpf.getContentType();
if (contentType != null) {
is = new DataInputStream(mpf.getInputStream());
long length = mpf.getSize();
CloudBlockBlob blob = container.getBlockBlobReference(""+fileName);
blob.upload(is, length);
}
// Modified from your code: END
} catch (FileNotFoundException ex) {
} catch (IOException ex) {
} finally {
try {
if (is != null) {
is.close();
}
} catch (IOException ignored) {
// Log the Exception
}
}
// 2. send it back to the client as <img> that calls get method
// we are using getTimeInMillis to avoid server cached image
return "/service/common/file/get/" + fileName;
}
For downloading or referencing the blob, you need to record the container name & blob name of the blob to the database.
OutputStream os = ...; // get the OutputStream from the HTTP Response
CloudBlobContainer container = blobClient.getContainerReference("<container-name>");
CloudBlob blob = getBlockBlobReference("<blob-name>");
blob.download(os)
For more information, you can refer to the Javadoc of Class CloudBlob http://azure.github.io/azure-storage-java/com/microsoft/azure/storage/blob/CloudBlob.html and the Get started doc for Blob Storage https://azure.microsoft.com/en-us/documentation/articles/storage-java-how-to-use-blob-storage/.

Categories