I've been started one simple website project to study Spring. I'm trying to check file extension and upload only image file on the board. So I added if else statement before upload file but it dosen't seem working correctly.
My code is below:
#Controller
public class FileUploadController {
#RequestMapping("/write")
public String write(HttpServletRequest request, #RequestParam("bFile") MultipartFile bFile, Model model) {
System.out.println("writeDao()");
String savePath = request.getSession().getServletContext().getRealPath("/fileUpload");
String originalFName = bFile.getOriginalFilename();
String onlyFName = originalFName.substring(0, originalFName.indexOf("."));
String extension = originalFName.substring(originalFName.indexOf(".")); // .jpg
String rename = onlyFName + "_" + getCurrentDayTime() + extension; // fileName_20150721-14-07-50.jpg
String fullPath = savePath + "\\" + rename;
if(!bFile.getContentType().equals("images/jpeg")) {
try{
byte[] bytes = bFile.getBytes();
BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(fullPath)));
stream.write(bytes);
stream.close();
System.out.println("Success to upload file");
} catch (Exception e) {
System.out.println("Fail to upload file");
}
} else {
System.out.println("Choose file to upload");
}
String bPwd = request.getParameter("bPwd");
BoardDao dao = sqlSession.getMapper(BoardDao.class);
dao.writeDao(pwd, rename, fullPath);
return "redirect:list";
}
//file upload.jsp
<form action="write" method="post" enctype="multipart/form-data">
<tr>
<td> File </td>
<td> <input type="file" multiple accept='image/*' name="bFile" size = "50"> </td>
</tr>
</form>
Related
I've done uploading and displaying images with Vuetify and Spring.
It's work, but I'm not sure that I did it correctly. I am not sure that I have implemented the correct approach to solving this problem. Can you check it and say what you think?
On side Vuetify I use v-file-input component and axios for sending image to the server:
<v-file-input
v-model="selectedLogo"
accept="image/png, image/jpeg, image/bmp"
placeholder="Выберите Логотип"
prepend-icon="mdi-camera"
label="Логотип"
show-size
>
<template v-slot:append-outer>
<v-btn small #click="uploadLogo">
<v-icon dense>mdi-upload</v-icon>
</v-btn>
</template>
</v-file-input>
//...
uploadLogo(){
uploadLogo(this.$axios, this.company.id, this.selectedLogo)
}
//...
export const uploadLogo = function ($axios, id, logo) {
let formData = new FormData()
formData.append("logo", logo)
return $axios.post(url+ `/${id}/logo`,
formData,
{
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
In Spring I have RestController:
#RestController
#RequestMapping("/api/")
public class FileController {
#Autowired
private FileStorageService fileStorageService;
#PostMapping("companies/{id}/logo")
public ResponseEntity<Object> uploadFile(#PathVariable Long id, #RequestParam("logo") MultipartFile logo) {
String fileName = fileStorageService.uploadLogo(id, logo);
return new ResponseEntity<>(HttpStatus.OK);
}
#GetMapping("/companies/{id}/logo")
public ResponseEntity<Resource> downloadLogo(#PathVariable Long id, HttpServletRequest request) {
Resource resource = fileStorageService.loadLogoAsResource(id);
String contentType = null;
try {
contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
} catch (IOException ex) {
contentType = "application/octet-stream";
}
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(contentType))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
.body(resource);
}
}
fileStorageService:
#Service
public class FileStorageService {
private final Path logoStorageLocation;
#Autowired
public FileStorageService(FileStorageProperties fileStorageProperties) {
this.logoStorageLocation = Paths.get(fileStorageProperties.getLogoDir())
.toAbsolutePath().normalize();
try {
Files.createDirectories(this.logoStorageLocation);
} catch (Exception ex) {
throw new FileStorageException("Could not create the directory where the uploaded files will be stored.", ex);
}
}
public String uploadLogo(Long id, MultipartFile file) {
String fileExtension = StringUtils.getFilenameExtension(file.getOriginalFilename());
String fileName = id.toString() + "." + fileExtension;
try {
if(fileName.contains("..")) {
throw new FileStorageException("Sorry! Filename contains invalid path sequence " + fileName);
}
Path targetLocation = this.logoStorageLocation.resolve(fileName);
Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);
return fileName;
} catch (IOException ex) {
throw new FileStorageException("Could not store file " + fileName + ". Please try again!", ex);
}
}
public Resource loadLogoAsResource(Long id) {
String fileName = id.toString() + ".png";
try {
Path filePath = this.logoStorageLocation.resolve(fileName).normalize();
Resource resource = new UrlResource(filePath.toUri());
if(resource.exists()) {
return resource;
} else {
throw new FileNotFoundException("File not found " + fileName);
}
} catch (MalformedURLException ex) {
throw new FileNotFoundException("File not found " + fileName, ex);
}
}
}
My idea is uploading/displaying images by URL http://server/api/companies/{id}/logo without knowing the name of the logo file.
For displaying I use v-img component:
<v-img :src="'http://localhost:8081/api/companies/' + company.id +'/logo'"></v-img>
Questions:
What do you think about my solution?
Here I use RestController for displaying images.
I thought that I can get image directly by its location on the server. Without using RestController for #GetMapping. For example, if my images are stored in the folder with path /images/companies/logo on the server, I can get my images by URL with path http://server/images/companies/logo/namelogo.png
In this way, I should know name of the file on the server.
How can I display the image without using RestController for #GetMapping?
I have configured my CloudinaryService to upload JUST ONE photo on my cloud on cloudinary. But i have really great troubles with configuring this to make it work on multiple uploads. Please help me, here is my code for single upload:
public async Task<string> UploadPictureAsync(IFormFile pictureFile, string fileName)
{
byte[] destinationData;
using (var ms = new MemoryStream())
{
await pictureFile.CopyToAsync(ms);
destinationData = ms.ToArray();
}
UploadResult uploadResult = null;
using (var ms = new MemoryStream(destinationData))
{
ImageUploadParams uploadParams = new ImageUploadParams
{
Folder = "cars",
File = new FileDescription(fileName, ms),
PublicId = "audizone"
};
uploadResult = this.cloudinaryUtility.Upload(uploadParams);
}
return uploadResult?.SecureUri.AbsoluteUri;
}
}
}
I change IFormFile pictureFile to List<IFormFile> pictureFiles, going on with foreach (file in pictureFiles)...the only thing this service is doing is just uploading 2 or 3 times the same picture(the first one of three or two)...just not uploading two or three different photos.
<form asp-action="Create" method="post" enctype="multipart/form-data">
<input type="file" multiple
class="form-control text-primary text-center"
id="picture"
name="picture"
placeholder="Picture..." />
<input type="submit" value="Submit" class="btn btn-dark" style="border-bottom-left-
radius:25%;border-bottom-right-radius:25%" />
</form>
I managed to successfully loop using this method:
public static void BulkUpload(List<string> filePaths, ResourceType resourceType = ResourceType.Image, string type = "upload")
{
var cloudinary = GetCloudinary(); // Initializing Cloudinary
foreach (var path in filePaths)
{
byte[] bytes = File.ReadAllBytes(path);
var streamed = "streamed";
using (MemoryStream memoryStream = new MemoryStream(bytes))
{
ImageUploadParams uploadParams = new ImageUploadParams()
{
File = new FileDescription(streamed, memoryStream)
};
ImageUploadResult uploadResult = cloudinary.Upload(uploadParams);
if (uploadResult.StatusCode == HttpStatusCode.OK)
Console.WriteLine("uploaded: " + uploadResult.PublicId);
else
Console.WriteLine("Failed: " + uploadResult.Error);
}
}
}
I use spring mvc I want to uplaod image to jsp form so I add enctype="multipart/form-data" to the form tag but when i add this, modelAttribute values equals null in the controller
This is my form in jsp page:
<form:form action="saveContact" method="post" modelAttribute="Contacting" id="container" enctype="multipart/form-data">
This is the header of the function in controller:
#RequestMapping(value = "/saveContact", method = RequestMethod.POST)
public ModelAndView saveContact(#ModelAttribute ("Contacting") Contacting Contacting,ModelAndView modelndView,HttpServletRequest request ,HttpServletResponse response
) throws Exception {............}
#ModelAttribute ("Contacting") Contacting Contacting all values are null. and When I erease the enctype="multipart/form-data" from form tag its work well but I cant upload the image
this is the uplaud function:
public void uplaodImages(String url,HttpServletRequest request) {
// configures upload settings
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(THRESHOLD_SIZE);
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setFileSizeMax(MAX_FILE_SIZE);
upload.setSizeMax(MAX_REQUEST_SIZE);
String uuidValue = "";
FileItem itemFile = null;
try {
// parses the request's content to extract file data
List formItems = upload.parseRequest(request);
Iterator iter = formItems.iterator();
// iterates over form's fields to get UUID Value
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
if (item.isFormField()) {
if (item.getFieldName().equalsIgnoreCase(UUID_STRING)) {
uuidValue = item.getString();
}
}
// processes only fields that are not form fields
if (!item.isFormField()) {
itemFile = item;
}
}
if (itemFile != null) {
// get item inputstream to upload file into s3 aws
BasicAWSCredentials awsCredentials = new BasicAWSCredentials(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY);
AmazonS3 s3client = new AmazonS3Client(awsCredentials);
try {
ObjectMetadata om = new ObjectMetadata();
om.setContentLength(itemFile.getSize());
om.setContentType("image/png");
String ext = FilenameUtils.getExtension(itemFile.getName());
String keyName = uuidValue + '.' + ext;
// s3client.putObject(new PutObjectRequest(S3_BUCKET_NAME,"99/after/img", itemFile,st om));
// s3client.setObjectAcl(S3_BUCKET_NAME, "99/after/img", CannedAccessControlList.PublicRead);
TransferManager tm = new TransferManager(new ProfileCredentialsProvider());
System.out.println("Hello");
// TransferManager processes all transfers asynchronously,
// so this call will return immediately.
Upload upload1 = tm.upload(
S3_BUCKET_NAME, url, itemFile.getInputStream(),om);
System.out.println("Hello2");
try {
// Or you can block and wait for the upload to finish
upload1.waitForCompletion();
System.out.println("Upload complete.");
} catch (AmazonClientException amazonClientException) {
System.out.println("Unable to upload file, upload was aborted.");
amazonClientException.printStackTrace();
}
} catch (AmazonServiceException ase) {
// LOGGER.error(uuidValue + ":error:" + ase.getMessage());
} catch (AmazonClientException ace) {
//LOGGER.error(uuidValue + ":error:" + ace.getMessage());
}
} else {
//LOGGER.error(uuidValue + ":error:" + "No Upload file");
System.out.println("No Upload file");
}
} catch (Exception ex) {
//LOGGER.error(uuidValue + ":" + ":error: " + ex.getMessage());
System.out.println(ex.getMessage());
}
//LOGGER.info(uuidValue + ":Upload done");
System.out.println("Upload done");
}
#RequestMapping(value = "/form.html", method = RequestMethod.POST)
public String handleFormUpload(#RequestParam("name") String name,
#RequestParam("file") MultipartFile file) throws Exception {
}
I'm uploading an image to a folder images. it's working fine.but what I actually want is to look for a folder name (I have the folder name) if not found create that folder and give it that name.how could that happen?
this is what I have done so far:
string ImageName = System.IO.Path.GetFileName(file.FileName);
string physicalPath = Server.MapPath("~/images/" + ImageName);
instead of images I should have folderName.
the complete view:
#{
ViewBag.Title = "Index";
}
#using (Html.BeginForm("FileUpload", "datum", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
<div>
category<br />
#Html.DropDownList("category", ViewBag.Roles as SelectList)
<br/>
description<br />
#Html.TextBox("description") <br />
Image<br />
<input type="File" name="file" id="file" value="Choose File" />
<input type="submit" value="Upload" class="submit" />
</div>
}
the complete controller
public class datumController : Controller
{
DataEntry db = new DataEntry();
public ActionResult Index()
{
var data = from p in db.categories
select p.categoryName;
SelectList list = new SelectList(data);
ViewBag.Roles = list;
return View();
}
public ActionResult create ()
{
return View();
}
[HttpPost]
public ActionResult FileUpload(HttpPostedFileBase file)
{
if (file != null)
{
string ImageName = System.IO.Path.GetFileName(file.FileName);
string physicalPath = Server.MapPath("~/images/" + ImageName);
// save image in folder
file.SaveAs(physicalPath);
//save new record in database
datum newRecord = new datum();
newRecord.category = Request.Form["category"];
newRecord.description = Request.Form["description"];
newRecord.imagePath = ImageName;
db.data.Add(newRecord);
db.SaveChanges();
}
//Display records
return RedirectToAction("Display");
}
so I should be getting the selected value from the drop down list and attach it to the physical path, check if folder exists if no then create folder and upload image to that folder
Try like below...
string subPath ="ImagesPath"; // your code goes here
bool exists = System.IO.Directory.Exists(Server.MapPath(subPath));
if(!exists)
System.IO.Directory.CreateDirectory(Server.MapPath(subPath));
For further info, please refer below link.
If a folder does not exist, create it
if (file != null && file.ContentLength > 0)
{
string path = Path.Combine(Server.MapPath("~/Images"), Path.GetFileName(file.FileName));
tbl_MixEmp.EmpImage = Path.Combine("~/Images", file.FileName);
file.SaveAs(path);
}
in my project I have to upload the image and show it in user profile view . Now I am successfully storing , I have problem in displaying image. the image is stored path D:/uploads so my image retrieving code in jsp is,
<c:set var="fileanme2" value="${teacherId.getPhoto()}"></c:set>
<%
String uploadFilePath2 = "D:" + "/" + "uploads";
%>
<c:set var="shlash2" value="/"></c:set>
<c:set var="pathValue2" value="<%=uploadFilePath2%>"></c:set>
<c:set var="string4" value="${pathValue2}${shlash2}${fileanme2}" />
<img alt="Image" src="${string4}" width="160" height="160"
class="img-thumbnail">
But image is not displaying , when I inspect the image element in browser in src attrib it showing path as D:/uploads/img when I hover mouse on it shows the path along with the project path how can I get the exact path for displaying image.
no need of any string concatenation and any extra work, you can do it in one line:
<c:set var="filePath" value="D:/uploads/${teacherId.getPhoto()}" />
and solutions for your problem:
1) if you are going to show image from you local file system then do like:
<img src="file:///D|/uploads/image_name.jpg"
width="200"
height="200"
alt="Image"/>
Warning: image may not be accessible when you publish your site.
2) create a servlet to handle GET request's of all images by passing name of image in url like:
#WebServlet("/ImageServlet")
public class ImageServlet extends HttpServlet {
private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("getting photo...");
String imageName = request.getParameter("imageName");
System.out.println("imageName: "+imageName);
//set your upload path
File imageFile = new File("D:\\uploads\\"+imageName);
System.out.println("file exists: "+imageFile.exists());
// Get content type by filename.
String contentType = getServletContext().getMimeType(imageFile.getName());
// Init servlet response.
response.reset();
response.setBufferSize(DEFAULT_BUFFER_SIZE);
response.setContentType(contentType);
response.setHeader("Content-Length", String.valueOf(imageFile.length()));
response.setHeader("Content-Disposition", "inline; filename=\"" + imageFile.getName() + "\"");
// Prepare streams.
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
// Open streams.
input = new BufferedInputStream(new FileInputStream(imageFile), DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
// Write file contents to response.
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
} finally {
// Gently close streams.
close(output);
close(input);
}
// Check if file is actually an image (avoid download of other files by hackers!).
// For all content types, see: http://www.w3schools.com/media/media_mimeref.asp
if (contentType == null || !contentType.startsWith("image")) {
// Do your thing if the file appears not being a real image.
// Throw an exception, or send 404, or show default/warning image, or just ignore it.
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
return;
}
}
// Helpers (can be refactored to public utility class)
private static void close(Closeable resource) {
if (resource != null) {
try {
resource.close();
} catch (IOException e) {
// Do your thing with the exception. Print it, log it or mail it.
e.printStackTrace();
}
}
}
}
and then in jsp use img tag like:
<img alt="Image"
src="<c:url value="/ImageServlet?imageName=${teacherId.getPhoto()}"/>" />
Source: BalusC image servlet