i am trying to upload an image file with my jsp form. i am successfully being able to upload it but not in the directory that i want.
#Controller
public class ProductController {
private Path path;
#Autowired
private ProductService productService;
#RequestMapping(value="/admin/addProduct")
public String addProduct() {
return "addProduct";
}
#RequestMapping(value="/admin/addProduct", method= RequestMethod.POST)
public String addNewProduct(#ModelAttribute("product") Product products,
BindingResult result,HttpServletRequest request,#RequestParam("prodImage")
MultipartFile file) {
System.out.println("adding product");
System.out.println(path);
if(result.hasErrors()) {
return "addProduct";
}
productService.saveProduct(products);
MultipartFile productImage = file;
String rootDir = request.getSession().getServletContext().getRealPath("/");
System.out.println(rootDir);
path = Paths.get(rootDir+"//WEB-INF//resources//images//"+products.getId()+
".jpg");
System.out.println("path :"+path);
if(productImage != null && !productImage.isEmpty()) {
System.out.println("inside not null product image");
try {
productImage.transferTo(new File(path.toString()));
System.out.println("after saving image");
}catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException("product image saving failed",ex);
}
}
return "redirect:/admin/productInventory";
}
#RequestMapping("/admin/productInventory")
public String productInventory() {
return "productInventory";
}
}
this is the current dir location being printed:-
/mnt/7A46BE1454633621/eclipseworkspace/ecommerce/target/ecommerce/
path :/mnt/7A46BE1454633621/eclipseworkspace/ecommerce/target/ecommerce/
WEB-INF/resources/images/5.jpg
i want to upload my image inside WEB-INF/resources/images. how can i do that?
you need to check class path is set or not then you can use classpath:/WEB-INF/resources/images/ path to image upload and download.
You can use the below code to upload image to your images folder. Here multipartFile is the reference of MultipartFile interface
InputStream inputStream = multipartFile.getInputStream();
byte[] buf = new byte[1024];
String path = servletContext.getRealPath("WEB-INF/resources/images");
File file = new File(path);
String basePath = file.getCanonicalPath();
String fileName = multipartFile.getOriginalFilename();
FileOutputStream fileOutputStream = new FileOutputStream(basePath+"/"+fileName);
int numRead = 0;
while ((numRead = inputStream.read(buf)) >= 0) {
fileOutputStream.write(buf, 0, numRead);
}
inputStream.close();
fileOutputStream.close();
Also to get servletContext reference autowire ServeletContext interface like this:
#Autowired
ServletContext servletContext;
Related
I am going to convert MultipartFile to File and upload it to S3 bucket.
However, when running the test, an error occurs in the process of converting MultipartFile to File.
ERROR : java.nio.file.AccessDeniedException: D:\workspace_intellij_forKiri\Kiri\server\kiri\temp\8b28a2f2-7276-4036
multipartFile.transferTo(file);
Please advise if there is anything I am missing.
The spring boot version is 2.7.7 version.
Test code
#WithAccount("creamyyyy")
#DisplayName("image save test")
#Test
public void createImageTest() throws Exception {
//given
String filename = "files";
String contentType = "png";
MockMultipartFile image1 = new MockMultipartFile(
filename,
filename + "." + contentType,
"image/png",
filename.getBytes());
//when
//then
this.mockMvc.perform( //== ERROR!!!
MockMvcRequestBuilders
.multipart("/api/posts/image")
.file(image1)
.contentType(MediaType.MULTIPART_FORM_DATA)
.characterEncoding("UTF-8")
)
.andDo(print())
.andExpect(status().isOk());
}
ImageService Code
// FileSave
public List<ImageResDto> addFile(List<MultipartFile> multipartFiles) throws IOException {
List<ImageResDto> imageResDtoList = new ArrayList<>();
/**
* <ImageResDto>
* private Long image_id;
* private String imgUrl;
*/
String absolutePath = new File("").getAbsolutePath() + File.separator + "temp";
for (MultipartFile multipartFile : multipartFiles) {
String contentType = multipartFile.getContentType();
if(ObjectUtils.isEmpty(contentType)) {
throw new RuntimeException("FILE TYPE NOT FOUND");
} else if(!verifyContentType(contentType)){
throw new RuntimeException("FILE TYPE NOT FOUND");
}
}
for (MultipartFile multipartFile : multipartFiles) {
String filename = UUID.randomUUID() + multipartFile.getOriginalFilename();
// save in local
String fullFilePath = absolutePath + File.separator + filename;
System.out.println("fullFilePath = " + fullFilePath);
File file = new File(fullFilePath);
if(!file.exists()) { file.mkdirs(); }
multipartFile.transferTo(file); // ERROR ... OTL
file.createNewFile();
// S3 upload
amazonS3.putObject(
new PutObjectRequest(bucket, filename, file)
.withCannedAcl(CannedAccessControlList.PublicRead)
);
String imgUrl = amazonS3.getUrl(bucket, filename).toString();
Image newImage = Image.builder()
.filename(filename)
.filepath(filename)
.imgUrl(imgUrl)
.build();
imageRepository.save(newImage);
ImageResDto imageResDto = ImageResDto.of(newImage);
imageResDtoList.add(imageResDto);
file.delete(); // local file delete
}
return imageResDtoList;
}
ImageController Code
#PostMapping(value = "/api/posts/image", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity createImage(#RequestPart(value = "files") List<MultipartFile> multipartFiles) throws IOException {
System.out.println("ImageController Runnnn");
// get member
PrincipalDetails principalDetails = (PrincipalDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
Member member = principalDetails.getMember();
List<ImageResDto> imageResDtoList = imageService.addFile(multipartFiles);
return new ResponseEntity(imageResDtoList, HttpStatus.CREATED);
}
I tried to specify a separate route using Path, but I failed.
// Error ..java.nio.file.AccessDeniedException => Path
// multipartFile -> File
Path path = Paths.get(fullFilePath).toAbsolutePath();
multipartFile.transferTo(path.toFile());
Files.createFile(path);
What is incomprehensible is that when tested using PostMan, the file is normally uploaded to the S3 bucket.
Please tell me if I applied anything wrong.
I have a problem about writing a test to upload Image in Amazon s3 in Spring Boot.
I tried to write its test method but I got an error shown below.
How can I fix it?
Here is the method of Rest controller
#RestController
#RequestMapping("/api/v1/bookImage")
#RequiredArgsConstructor
public class ImageRestController {
#PostMapping
public ResponseEntity<String> uploadImage(#RequestParam("bookId") Long bookId, #RequestParam("file") MultipartFile file) {
final String uploadImg = imageStoreService.uploadImg(convert(file), bookId);
service.saveImage(bookId, uploadImg);
return ResponseEntity.ok(uploadImg);
}
private File convert(final MultipartFile multipartFile) {
// convert multipartFile to File
File file = new File(Objects.requireNonNull(multipartFile.getOriginalFilename()));
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(multipartFile.getBytes());
return file;
} catch (IOException e) {
throw new RuntimeException("Failed to convert multipartFile to File");
}
}
Here is the method of imageService.
public String uploadImg(File file, Long bookId) {
s3amazon.putObject(BUCKET_NAME, bookId.toString(), file);
return baseUrl + bookId;
}
Here is the test method shown below.
#Test
void itShouldGetImagePath_WhenValidBookIdAndFile() throws Exception{
// given - precondition or setup
String bookId = "1";
String imagePath = "amazon-imagepath";
String baseUrl = String.format(imagePath + "/%s", bookId);
Long bookIdValue = 1L;
MockMultipartFile uploadFile = new MockMultipartFile("file", new byte[1]);
// when - action or the behaviour that we are going test
when(imageStoreService.uploadImg(convert(uploadFile), bookIdValue)).thenReturn(baseUrl); -> HERE IS THE ERROR
// then - verify the output
mvc.perform(MockMvcRequestBuilders.multipart("/api/v1/bookImage")
.file(uploadFile)
.param("bookId", bookId))
.andExpect((ResultMatcher) content().string(baseUrl))
.andExpect(status().isOk());
}
private File convert(final MultipartFile multipartFile) {
// convert multipartFile to File
File file = new File(Objects.requireNonNull(multipartFile.getOriginalFilename()));
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(multipartFile.getBytes());
return file;
} catch (IOException e) {
throw new RuntimeException("Failed to convert multipartFile to File");
}
}
Here is the error : Failed to convert multipartFile to File (java.lang.RuntimeException: Failed to convert multipartFile to Filejava.io.FileNotFoundException: )
How can I fix it?
Here is the solution shown below.
#Test
void itShouldGetImagePath_WhenValidBookIdAndFile() throws Exception{
// given - precondition or setup
String bookId = "1";
String imagePath = "amazon-imagepath";
String baseUrl = String.format(imagePath + "/%s", bookId);
Long bookIdValue = 1L;
String fileName = "sample.png";
MockMultipartFile uploadFile =
new MockMultipartFile("file", fileName, "image/png", "Some bytes".getBytes());
// when - action or the behaviour that we are going test
when(imageStoreService.uploadImg(convert(uploadFile), bookIdValue)).thenReturn(baseUrl);
doNothing().when(bookSaveService).saveImage(bookIdValue,baseUrl);
// then - verify the output
mvc.perform(MockMvcRequestBuilders.multipart("/api/v1/bookImage")
.file(uploadFile)
.param("bookId", bookId))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$").value(baseUrl))
.andExpect(content().string(baseUrl));
}
I used this code in Spring Boot Java to create an OCR application.
#Controller
public class FileUploadController {
#RequestMapping("/")
public String index() {
return "upload";
}
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public RedirectView singleFileUpload(#RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes, Model model) throws IOException, TesseractException {
byte[] bytes = file.getBytes();
Path path = Paths.get("C:/Users/ashwi/Downloads/javaocr9/src/main/resources/static" + file.getOriginalFilename());
Files.write(path, bytes);
File convFile = convert(file);
Tesseract tesseract = new Tesseract();
tesseract.setDatapath("C:/Users/ashwi/Downloads/ocr-tess4j-example-master/ocr-tess4j-example-master/tessdata");
String text = tesseract.doOCR(file2);
redirectAttributes.addFlashAttribute("file", file);
redirectAttributes.addFlashAttribute("text", text);
return new RedirectView("result");
}
#RequestMapping("/result")
public String result() {
return "result";
}
public static File convert(MultipartFile file) throws IOException {
File convFile = new File(file.getOriginalFilename());
convFile.createNewFile();
FileOutputStream fos = new FileOutputStream(convFile);
fos.write(file.getBytes());
fos.close();
return convFile;
}
}
However, there appears to be an error at:
String text = tesseract.doOCR(file2);
In visual studio code, I got an error saying: "file2 cannot be resolved to a variable".
Any ideas? I am new to Java and am having trouble fixing it.
I got this version of code from: https://stackabuse.com/tesseract-simple-java-optical-character-recognition/
#RequestMapping(value = "/video/{clientID}/{fileName}", method = RequestMethod.GET)
public ResponseEntity<StreamingResponseBody> getClientVideo(#PathVariable(value = "clientID") Integer clientID, #PathVariable(value = "fileName") final String fileName) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
String absolutePath = new File(".").getAbsolutePath();
File file = new File(Paths.get(absolutePath).getParent() + "/" + clientID);
if (null != file) {
FilenameFilter beginswithm = new FilenameFilter() {
public boolean accept(File directory, String filename) {
return filename.contains("ClientVideo_"+fileName);
}
};
File[] files = file.listFiles(beginswithm);
if (null != files && files.length > 0) {
Resource resource = null;
for (final File f : files) {
headers.set("Content-Disposition", "inline; filename=" + f.getName());
StreamingResponseBody responseBody = new StreamingResponseBody() {
#Override
public void writeTo(OutputStream out) throws IOException {
out.write(Files.readAllBytes(f.toPath()));
out.flush();
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
return ResponseEntity.ok().headers(headers).contentType(MediaType.APPLICATION_OCTET_STREAM).body(responseBody); //(responseBody, headers, HttpStatus.OK);
}
}
}
RecruiterResponseBean resBean = new RecruiterResponseBean();
resBean.setStatusMessage("Video is not present : " + Constants.FAILED);
resBean.setStatusCode(Constants.FAILED_CODE);
return new ResponseEntity(HttpStatus.NOT_FOUND);
}
I am using Spring MVC, I tried many methods but all are downloading the video. Above code is streaming the video, the problem is: in firefox it is streaming but in crome it is downloading. I want to play streaming video in crome also like below ex.
[Ex streaming video: http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4]
Do I need to add more Headers? [if so, which headers need to add?]
Or Did i miss anything?
I want to write a String to a file, which the user chooses from . I'm unable to do it because I need the fileName and fileLocation to write my String to the file. But the request.getParamater("") gives me just the fileName. I know that it won't return the fileLocation because of security issues. Then, how do I write my String from the file chosen on my jsp. Please advise.
You cannot write to that file directly.
Short answer : Make a copy file on server.
Long answer:
1) Get the file.
2) Save it on server.
3) Append to that file. Do not overwrite.
4) Again send back the file to user with response.
Do some steps
Get file name using getFileName() method. Store it on server side
if some one wants to Save Same file name again then you append Some Date after file Name. so you can easily get all the files without any code changes.
After write String into file close the file and flush .
See i have upload the file form Front End and Store it on Some local system . when you try to upload Same file again then it append Date with File name
public class uploadFile {
private File myFile;
private String myFileContentType;
private String myFileFileName;
private String destPath;
public String upload() throws IOException {
try {
destPath = System.getProperty("user.home") + System.getProperty("file.separator") + "File-Uploads";
File destFile = new File(destPath, myFileFileName);
File file1 = new File(destFile.toString());
boolean b = false;
Date date = new Date();
if (!(file1.exists())) {
b = file1.createNewFile();
}
if (b) {
FileUtils.copyFile(myFile, destFile);
} else {
String fileContent = "";
File f = new File(file1.toString());
FileInputStream inp = new FileInputStream(f);
byte[] bf = new byte[(int) f.length()];
inp.read(bf);
fileContent = new String(bf, "UTF-8");
System.out.println("file===>" + fileContent);
String filename = destFile.toString() + date;
FileWriter fw = new FileWriter(filename, true);
fw.write(fileContent);
fw.close();
FileUtils.copyFile(myFile, destFile);
}
return SUCCESS;
} catch (IOException e) {
return SUCCESS;
}
}
public File getMyFile() {
return myFile;
}
public void setMyFile(File myFile) {
this.myFile = myFile;
}
public String getMyFileContentType() {
return myFileContentType;
}
public void setMyFileContentType(String myFileContentType) {
this.myFileContentType = myFileContentType;
}
public String getMyFileFileName() {
return myFileFileName;
}
public void setMyFileFileName(String myFileFileName) {
this.myFileFileName = myFileFileName;
}
}