Spring MVC Resources not refreshing - image

I'm working on an image manager system for my Spring MVC project, with the basic functions of displaying the gallery of all images stored in the local image folder, deleting images and uploading new images.
I would like that, once a new image is uploaded, the page reloads the images gallery, including the image just added. What it happens in fact is that the new image is correctly saved on the HD, but it doesn't automatically show up in the resources/img folder in the Java project; therefore, once the page is reloaded, the new image is not there. Only when I manually refresh the project, the new image appears in the resources/img folder.
The odd thing is, I don't have the same problem with the delete method: once an image is deleted, it disappears from the HD AND the resources/img folder, and the page reloads the gallery without showing the image just deleted.
Any idea where the problem could be?
Here is my controller
#Controller
public class imagesManagerController {
// READ ALL FILES FROM IMG FOLDER
#RequestMapping(value = "/imagesManager", method = RequestMethod.GET)
public ModelAndView readImages
(#RequestParam(value = "error", required = false) String error) {
// create model and link it to jsp imagesManager
ModelAndView model = new ModelAndView("imagesManager");
// return content from images folder and add it to model
File imgsPath = new File("C:/Users/Alessandro/workspace/SpringMVCBlog/WebContent/resources/img");
String[] imgsNames = imgsPath.list();
model.addObject("imgsNames", imgsNames);
//if upload fails, display error message
if (error != null) {
model.addObject("error",
"Please select a file to upload");
}
return model;
}
//UPLOAD FILE TO HD
#RequestMapping(value = "/imagesManager/upload", method = RequestMethod.POST)
public String handleFileUpload (#RequestParam("file") MultipartFile file) {
//get img name
String imgName = file.getOriginalFilename();
System.out.println(imgName);
//create file path
String folder = "C:/Users/Alessandro/workspace/SpringMVCBlog/WebContent/resources/img/";
File path = new File (folder+imgName);
System.out.println(path);
if (!file.isEmpty()) {
try {
//get bytes array from file
byte[] bytes = file.getBytes();
//create output stream
BufferedOutputStream stream = new BufferedOutputStream(
new FileOutputStream(path));
//write img content on path
stream.write(bytes);
//close stream
stream.close();
//if upload is successful, reload page
return "redirect:/imagesManager";
} catch (Exception e) {
return "You failed to upload " + imgName + " => " + e.getMessage();
}
} else {
return "redirect:/imagesManager?error";
}
}
// DELETE FILE FROM HD
#RequestMapping(value = "/imagesManager/delete", method = RequestMethod.POST)
public String deleteFile(#RequestParam (value="imgName") String imgName) {
//create file path to be deleted
String folder = "C:/Users/Alessandro/workspace/SpringMVCBlog/WebContent/resources/img/";
File path = new File (folder+imgName);
// delete file
if (path.delete()) {
//if delete is successful, reload page
return "redirect:/imagesManager";
} else {
return "Delete operation failed";
}
}
}

The problem is in the path:
WebContent/resources/img
It is refreshing probably due to IDE server auto-deployment. Test with %TEMP% path and check.
1) You should not save uploaded files to the application server file system.
2) You should not save uploaded files to the application folder as it is part of the deployment. It will only be deployed once and that folder is only for the application files.
Instead, use the cloud or a dedicated file system.

Related

Saving an image to a newly created folder with Uri?

The app i am creating is supposed to save a picture in a sub folder of the pictures folder. As long as i save the picture to the base folder it works fine, but it returns an error as soon as i try to target the subfolder. Permission for writing/reading external storage are given. Do i need to create the folder another way to use it? How do i get the URI of the folder itself?
The error for v1 is: "Failed to write destination file".
The error for v2 is: "Unknown or unsupported URL:content://media/external/images/media/ProxF/"
private void captureImage(ImageCapture imageCapture)
{
//Folder
File dir = new File(getExternalStoragePublicDirectory(DIRECTORY_PICTURES) +"/ProxF");
try{
if(dir.mkdir()) {
System.out.println("Directory created");
} else {
System.out.println("Directory is not created");
}
}catch(Exception e){
e.printStackTrace();
}
//MEDIA API
String FotoString="picture1";
ContentValues contentValues=new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, FotoString);
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
//Saving to the picture folder - working
Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
//V1 - not working
File folder = new File(getExternalStoragePublicDirectory(DIRECTORY_PICTURES).toString() + "/ProxF/");
Uri uri1=Uri.fromFile(folder);
//V2 - not working
Uri uri2 = Uri.parse(MediaStore.Images.Media.EXTERNAL_CONTENT_URI+"/ProxF/")
ImageCapture.OutputFileOptions fileOptions= new ImageCapture.OutputFileOptions.Builder(getContentResolver(),uri,contentValues).build();
imageCapture.takePicture(fileOptions, Executors.newCachedThreadPool(), new ImageCapture.OnImageSavedCallback() {
#Override
public void onImageSaved(#NonNull ImageCapture.OutputFileResults outputFileResults) {
runOnUiThread(() -> Toast.makeText(KameraAc.this, "Image Saved ",Toast.LENGTH_SHORT).show());
startCamera();
}
#Override
public void onError(#NonNull ImageCaptureException exception) {
runOnUiThread(() -> Toast.makeText(KameraAc.this, "Failed to save: "+exception.getMessage(), Toast.LENGTH_SHORT).show());
startCamera();
}
});
}

Spring MVC - Copy image into WEB-INF/assets folder

I am trying to copy image into assets folder inside WEB-INF folder. Following code successfully copy images outside the project but can't copy inside WEB-INF folder.
public static void copyFile(String source, String destination) throws IOException {
try {
File sourceFile = new File(source);
File destinationFile = new File(destination);
FileInputStream fileInputStream = new FileInputStream(sourceFile);
FileOutputStream fileOutputStream = new FileOutputStream(destinationFile);
int bufferSize;
byte[] bufffer = new byte[512];
while ((bufferSize = fileInputStream.read(bufffer)) > 0) {
fileOutputStream.write(bufffer, 0, bufferSize);
}
fileInputStream.close();
fileOutputStream.close();
} catch (IOException e) {
throw new IOException(e.getMessage());
}
}
I get a image path from Http request.
CopyFile.copyFile(imageUrl, "http://localhost:8080/M.S.-Handloom-Fabrics/static/"+imageName+".png");
I have mapped the resources in dispatcher-servlet.xml
<mvc:resources mapping="/static/**" location="/WEB-INF/assets/"/>
Here is the error
Info: http:\localhost:8080\M.S.-Handloom-Fabrics\static\TueJun1216_27_54NPT20180.png (The filename, directory name, or volume label syntax is incorrect)
http://localhost:8080/M.S.-Handloom-Fabrics/static/"+imageName+".png"
is a URL, not a file-path, and is therefore meaningless as a parameter to the File constructor.
IF you configured your app server to explode your webapp on deploy then you could use ServletContext.getRealPath but as this SO post details nicely you most likely do not want to do this as your saved files will be lost upon re-deploy.
Saving them outside of the web app is the way to go.

sub folder in not creating on azure in asp.net mvc5 application

I am ruing my website on azure, every folder is present on site directory in azure but uploadimages is my sub folder of content is absent from wwwroot, and images is not uploading also
I am using
var path =Path.Combine(Server.MapPath("~/Content/UploadImages/")+filename);
same with document upload
According to your description, I have tested on my side, please follow below to find out whether it could help you.
As you said, you got the target file path by this code:
var path = Path.Combine(Server.MapPath("~/Content/UploadImages/") + filename);
Before uploading files, please make sure that the directory in your web server “~/Content/UploadImages/” is existed.
Here is my test code:
MVC controller method
[HttpPost]
public JsonResult UploadFiles()
{
try
{
foreach (string file in Request.Files)
{
var fileContent = Request.Files[file];
if (fileContent != null && fileContent.ContentLength > 0)
{
var stream = fileContent.InputStream;
var fileName = Path.GetFileName(fileContent.FileName);
string baseDir = Server.MapPath("~/Content/UploadImages/");
if (!Directory.Exists(baseDir))
Directory.CreateDirectory(baseDir);
var path = Path.Combine(baseDir, fileName);
using (var fileStream = System.IO.File.Create(path))
{
stream.CopyTo(fileStream);
}
}
}
}
catch (Exception e)
{
return Json(new
{
Flag = false,
Message = string.Format("File Uploaded failed with exception:{0}", e.Message)
});
}
return Json(new
{
Flag = true,
Message = "File uploaded successfully!"
});
}
Additionally, for long-term consideration, you could store your files on Azure Blob Storage which could bring you some benefits, such as:
1.Serving images or documents directly to a browser
2.Storing files for distributed access
3.When you scale up your site, your site could run in multiple Web Server instances which could access the same files & docs simultaneously
For more details, please refer to this link: https://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-blobs/

Image without extension in src not loading in IE alone, and works perfect in all other browers

I have below HTML code:
<img title="hotelThumbImage" id="hotelThumbImage01" width="140px" height="129px"
src="/b2c/images/?url=FixedPkgB2c/FF-252-325"/>
It renders in IE as below:
It renders in all other browser like FireFox and Chrome as:
Related question : How to make a Servlet call form UI which returns the Content itself and place an img tag using Script in the output?
My project is suffering from this too, and it's because IE prevents download/display of files which have a different encoding than their extension. It has something to do with malicious code being able to be hidden as image files simply by changing the extension of the file.
Firefox and Chrome are smart enough to display it as an image so long as the encoding is that of an image, but IE takes no chances, it seems.
You'll have to add the extension that matches your image's encoding for it to display in IE.
Edit: It's also possible that your server is sending the file with a header denoting plain text. Again, Firefox and Chrome are smart enough to handle it, but IE isn't. See: https://stackoverflow.com/a/32988576/4793951
Welcome to IE world... :(
What i would do, in order to have better control of the situation is to modify the getter method, so in Holiday.getPkgCode():
public String getPkgCode() throws IOException {
if (!this.pkgCode.contains(".")) {
String ext = ImgUtil.determineFormat(this.pkgCode);
return this.pkgCode + ImgUtil.toExtension(ext);
} else {
return this.pkgCode;
}
}
To use it you will need to catch exceptions and this ImgUtil class adapted from here:
class ImgUtil {
public static String determineFormat(String name) throws IOException {
// get image format in a file
File file = new File(name);
// create an image input stream from the specified file
ImageInputStream iis = ImageIO.createImageInputStream(file);
// get all currently registered readers that recognize the image format
Iterator<ImageReader> iter = ImageIO.getImageReaders(iis);
if (!iter.hasNext()) {
throw new RuntimeException("No readers found!");
}
// get the first reader
ImageReader reader = iter.next();
String toReturn = reader.getFormatName();
// close stream
iis.close();
return toReturn;
}
public static String toExtension(String ext) {
switch (ext) {
case "JPEG": return ".jpg";
case "PNG": return ".png";
}
return null;
}
}
TEST IT:
NOTE: I placed an image (jpg) without extension placed in C:\tmp folder
public class Q37052184 {
String pkgCode = "C:\\tmp\\yorch";
public static void main(String[] args) throws IOException {
Q37052184 q = new Q37052184();
System.out.println(q.getPkgCode());
}
// the given getter!!!
}
OUTPUT:
C:\tmp\yorch.jpg
You have to set the Content Type property of responses' header in the servlet.
For example in spring 4 mvc,
#GetMapping(value = "/b2c/images/?url=FixedPkgB2c/FF-252-325")
public ResponseEntity<byte []> getImageThumbnail() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(media type));
byte [] content= ...;
return ResponseEntity.ok().headers(headers).body(content);
}

loading a pdf in-browser from a file in the server file system?

How can I get a pdf located in a file in a server's directory structure to load in a browser for users of a Spring MVC application?
I have googled this and found postings about how to generate PDFs, but their answers do not work in this situation. For example, this other posting is not relevant because res.setContentType("application/pdf"); in my code below does not solve the problem. Also, this other posting describes how to do it from a database but does not show full working controller code. Other postings had similar problems that caused them not to work in this case.
I need to simply serve up a file (not from a database) and have it been viewable by a user in their browser. The best I have come up with is the code below, which asks the user to download the PDF or to view it in a separate application outside the browser. What specific changes can I make to the specific code below so that the user automatically sees the PDF content inside their browser when they click on the link instead of being prompted to download it?
#RequestMapping(value = "/test-pdf")
public void generatePdf(HttpServletRequest req,HttpServletResponse res){
res.setContentType("application/pdf");
res.setHeader("Content-Disposition", "attachment;filename=report.pdf");
ServletOutputStream outStream=null;
try {
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(new File("/path/to", "nameOfThe.pdf")));
/*ServletOutputStream*/ outStream = res.getOutputStream();
//to make it easier to change to 8 or 16 KBs
int FILE_CHUNK_SIZE = 1024 * 4;
byte[] chunk = new byte[FILE_CHUNK_SIZE];
int bytesRead = 0;
while ((bytesRead = bis.read(chunk)) != -1) {outStream.write(chunk, 0, bytesRead);}
bis.close();
outStream.flush();
outStream.close();
}
catch (Exception e) {e.printStackTrace();}
}
Change
res.setHeader("Content-Disposition", "attachment;filename=report.pdf");
To
res.setHeader("Content-Disposition", "inline;filename=report.pdf");
You should also set the Content Length
FileCopyUtils is handy:
#Controller
public class FileController {
#RequestMapping("/report")
void getFile(HttpServletResponse response) throws IOException {
String fileName = "report.pdf";
String path = "/path/to/" + fileName;
File file = new File(path);
FileInputStream inputStream = new FileInputStream(file);
response.setContentType("application/pdf");
response.setContentLength((int) file.length());
response.setHeader("Content-Disposition", "inline;filename=\"" + fileName + "\"");
FileCopyUtils.copy(inputStream, response.getOutputStream());
}
}

Resources