EDIT IMAGE in Srping Boot Controller - spring-boot

In the edit section, I wrote how to make it upload the image
Thank you very much
#PostMapping("/save")
public String add(#ModelAttribute("category") Category category, RedirectAttributes ra,
#RequestParam("fileImage") MultipartFile multipartFile) throws IOException {
String fileName = StringUtils.cleanPath(multipartFile.getOriginalFilename());
category.setPhoto(fileName);
Category saveCategory = categoryService.save(category);
String uploadDir = "./category-logos/" + saveCategory.getId();
Path uploadPath = Paths.get(uploadDir);
if (!Files.exists(uploadPath)) {
Files.createDirectories(uploadPath);
}
try (InputStream inputStream = multipartFile.getInputStream()) {
Path filePath = uploadPath.resolve(fileName);
Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
throw new IOException("could not save upload file: " + fileName);
}
return "redirect:/category/list";
}
#GetMapping("/edit/{id}")
public String edit(Model model, #PathVariable(name="id")Long id) {
//`**`**`**enter code here**`**`**`
}

Related

AWS S3 uploaded file was not shown on cyberduck

I am trying to write an API for uploading and downloading files. After I uploaded a test file, it was not shown on cyberduck, but I can download the test file that I just uploaded.
Then I try to download the file that exist on cyberduck, but it shows
com.emc.object.s3.S3Exception: The specified key does not exist.
API code:
StorageImpl.java
#Service
public class StorageImpl implements Storage {
private static Logger logger = LoggerFactory.getLogger(Storage.class);
#Value("${storage.file.repository}")
private String fileRepository;
#Value("${object.storage.user}")
private String oUser;
#Value("${object.storage.endpoint}")
private String endpoint;
#Value("${object.storage.bucket}")
private String nBucket;
#Value("${object.storage.key.secret}")
private String nSecret;
#Value("${object.storage.region.name}")
private String nRegion;
private S3Client s3client;
public StorageImpl() {
}
#Inject
void init() {
try {
s3client = this.getS3Client();
} catch (Exception e) {
e.printStackTrace();
}
}
private S3Client getS3Client() {
if (s3client == null) {
try {
SSLContext sc = SSLContext.getInstance("TLSv1.2");
sc.init(null, null, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(new PreferredCipherSuiteSSLSocketFactory(sc.getSocketFactory()));
String hostname = "";
URI uri = null;
try {
uri = new URI(endpoint);
hostname = uri.getHost();
} catch (URISyntaxException e) {
logger.error("URL " + endpoint + " is a malformed URL");
e.printStackTrace();
}
S3Config config = null;
config = new S3Config(new URI(endpoint)).withUseVHost(false);
logger.debug("oUser=" + oUser + ", secret=" + nSecret + ", endpoint=" + endpoint);
config.withIdentity(oUser).withSecretKey(nSecret);
logger.debug("");
config.setSignMetadataSearch(true);
s3client = new S3JerseyClient(config, new URLConnectionClientHandler());
logger.debug("s3client initiated. endpoint: " + endpoint);
} catch (Exception ex) {
logger.error(ex.getMessage(), ex);
}
}
return s3client;
}
private File convertMultiPartFileToFile(final MultipartFile multipartFile) {
final File file = new File(multipartFile.getOriginalFilename());
try (final FileOutputStream outputStream = new FileOutputStream(file)) {
outputStream.write(multipartFile.getBytes());
} catch (IOException e) {
logger.error("Error {} occurred while converting the multipart file", e.getLocalizedMessage());
}
return file;
}
#Override
public void save(final MultipartFile multipartFile) {
try {
final File file = convertMultiPartFileToFile(multipartFile);
logger.info("Uploading file with name {}", file.getName());
final PutObjectRequest putObjectRequest = new PutObjectRequest(nBucket, file.getName(), file);
s3client.putObject(putObjectRequest);
Files.delete(file.toPath()); // Remove the file locally created in the project folder
} catch (AmazonServiceException e) {
logger.error("Error {} occurred while uploading file", e.getLocalizedMessage());
} catch (IOException ex) {
logger.error("Error {} occurred while deleting temporary file", ex.getLocalizedMessage());
}catch(S3Exception ae){
ae.printStackTrace();
logger.error("", ae);
}
}
#Override
public InputStream retrieve(String fileName) {
return s3client.getObject(nBucket, fileName).getObject();
}
}
FileController.java
#RestController
#RequestMapping("/files")
#CrossOrigin(origins = "*", maxAge = 3600)
public class FileController {
private static final String MESSAGE_1 = "Uploaded the file successfully";
private static final String FILE_NAME = "fileName";
#Autowired
protected StorageImpl storageImpl;
#Autowired
protected FileService fileService;
#GetMapping
public ResponseEntity<Object> findByName(#RequestParam("fileName") String fileName) {
return ResponseEntity
.ok()
.cacheControl(CacheControl.noCache())
.header("Content-type", "application/octet-stream")
.header("Content-disposition", "attachment; filename=\"" + fileName + "\"")
.body(new InputStreamResource(storageImpl.retrieve(fileName)));
}
#PostMapping
public ResponseEntity<Object> save(#RequestParam("file") MultipartFile multipartFile) {
storageImpl.save(multipartFile);
return new ResponseEntity<>(MESSAGE_1, HttpStatus.OK);
}
}
What are the possible reasons causing this bug?

file upload functionality fails on production server

I am using Spring Boot on Windows development environment with Java 1.8 open JDK 8.
File uploading functionality works fine on development environment. But, it does not work on production environment when I deploy the WAR file. My production environment has Apache tomcat 8.0.36, Java 1.8 open jdk 8, Ubuntu.
This is the web site :www.samslisting.com
Below is the spring Boot code.
#RequestMapping(value = "/SUB_CATEGORY_1_1_post", method = { RequestMethod.POST })
public ModelAndView categorypost(
#Valid #ModelAttribute("formData") SUB_CATEGORY_1_1 formData,
BindingResult bindingResult,
#RequestParam(value = "image",required = false) MultipartFile[] multipartFile,
HttpSession session, Model model) {
ModelAndView modelAndView = new ModelAndView();
boolean imageNotUploaded = false;
boolean unSupportedFileType = false;
for(int i=0;i<multipartFile.length;i++)
{
if(multipartFile[0].getOriginalFilename().equals(""))
{
imageNotUploaded = true;
}
if(!multipartFile[i].getOriginalFilename().equals("")) {
String fileName = multipartFile[i].getOriginalFilename();
String []fileNames = fileName.split("\\.");
int fileNamesLength = fileNames.length;
List <String > supportedFileTypes = new ArrayList<String >();
supportedFileTypes.add("apng");
supportedFileTypes.add("avif");
supportedFileTypes.add("gif");
supportedFileTypes.add("jpg");
supportedFileTypes.add("jpeg");
supportedFileTypes.add("jfif");
supportedFileTypes.add("pjpeg");
supportedFileTypes.add("pjp");
supportedFileTypes.add("png");
supportedFileTypes.add("svg");
supportedFileTypes.add("webp");
if(supportedFileTypes.contains(fileNames[fileNamesLength-1].toLowerCase()) )
{
}
else {
unSupportedFileType = true;
}
}
}
if (bindingResult.hasErrors() || imageNotUploaded||unSupportedFileType) {
HashMap<String, String> countrylist = null;
try {
countrylist = Common_List.getCountryList(dataSource.getConnection());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(imageNotUploaded) {
modelAndView.addObject("error", "Please upload image!");
}
if(unSupportedFileType) {
modelAndView.addObject("error1", "Please upload image of Type supported! "
+ " .apng, .avif, .gif, .jpg, .jpeg, .jfif, .pjpeg, .pjp, .png, .svg, .webp ");
}
modelAndView.addObject("countrylist", countrylist);
modelAndView.setViewName("SubCategory_1_1");
}else {
formData.setCATEGORY(SystemConstant.intCategory_1);
formData.setSUB_CATEGORY(SystemConstant.intSubCategory_1_1);
String caca = (String)session.getAttribute("USERID");
formData.setUSERID(Long.parseLong(caca));
formData = service.createOrUpdateUser(formData);
for(int i=0;i<multipartFile.length;i++)
{
if(!multipartFile[i].getOriginalFilename().equals(""))
{
String fileName = StringUtils.cleanPath(multipartFile[i].getOriginalFilename());
String rootPath = System.getProperty("catalina.home");
String uploadDir = System.getProperty("user.dir") + File.separator + "user-photos"+ File.separator + SystemConstant.intCategory_1+File.separator+ SystemConstant.intSubCategory_1_1+
File.separator+(String)session.getAttribute("USERID")+ File.separator+formData.getSUB_CATEGORY_1_1_ID();
Path uploadPath = Paths.get(uploadDir);
if (!Files.exists(uploadPath)) {
try {
Files.createDirectories(uploadPath);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
InputStream inputStream = multipartFile[i].getInputStream();
Path filePath = uploadPath.resolve(fileName);
Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING);
IMAGES_1_1 image = new IMAGES_1_1();
image.setUSERID(formData.getUSERID());
image.setSUB_CATEGORY_1_1_ID(formData.getSUB_CATEGORY_1_1_ID());
image.setCATEGORY(SystemConstant.intCategory_1);
image.setSUB_CATEGORY(SystemConstant.intSubCategory_1_1);
image.setNAME(multipartFile[i].getOriginalFilename());
serviceImage.createOrUpdateImage(image);
} catch (IOException ioe) {
try {
throw new IOException("Could not save image file: " + fileName, ioe);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
modelAndView.setViewName("SamList");
}
return modelAndView;
}

I want to upload file without using multipart in spring boot, would be great if I could get you valuable suggestions on this

Shall I remove this from application.properties
spring.http.multipart.enabled=true
What should be my approach towards this file upload without using multipart?
This way, I'm able to uploading file using where I'm using multipart.
#RequestMapping(value = "/dog/create/{name}", method = RequestMethod.POST)
public JsonNode dogCreation(HttpServletRequest httpRequest, #RequestParam(value = "picture", required = false) MultipartFile multipartFile,
#PathVariable("name") String name) throws IOException, InterruptedException {
JSONObject response = new JSONObject();
Dog dog = new Dog();
String DOG_IMAGES_BASE_LOCATION = "resource\\images\\dogImages";
try {
File file = new File(DOG_IMAGES_BASE_LOCATION);
if (!file.exists()) {
file.mkdirs();
}
} catch (Exception e) {
e.printStackTrace();
}
dog = dogService.getDogByName(name);
if (dog == null) {
if (!multipartFile.isEmpty()) {
String multipartFileName = multipartFile.getOriginalFilename();
String format = multipartFileName.substring(multipartFileName.lastIndexOf("."));
try {
Path path = Paths.get(DOG_IMAGES_BASE_LOCATION + "/" + name + format);
byte[] bytes = multipartFile.getBytes();
File file = new File(path.toString());
file.createNewFile();
Files.write(path, bytes);
if (file.length() == 0) {
response = utility.createResponse(500, Keyword.ERROR, "Image upload failed");
} else {
String dbPath = path.toString().replace('\\', '/');
dog = new Dog();
dog.setName(name);
dog.setPicture(dbPath);
dog = dogService.dogCreation(dog);
response = utility.createResponse(200, Keyword.SUCCESS, "Image upload successful");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
return objectMapper.readTree(response.toString());
}
I want to do it without using multipart, what would you suggest?
This is what I've done till now to solve this
#RequestMapping(value = "/dog/create/{name}", method = RequestMethod.POST)
public JsonNode dogCreation(HttpServletRequest httpRequest, #RequestParam("picture") String picture,
#PathVariable("name") String name) throws IOException, InterruptedException {
JSONObject response = new JSONObject();
Dog dog = new Dog();
String DOG_IMAGES_BASE_LOCATION = "resource\\images\\dogImages";
try {
File file = new File(DOG_IMAGES_BASE_LOCATION);
if (!file.exists()) {
file.mkdirs();
}
} catch (Exception e) {
e.printStackTrace();
}
dog = dogService.getDogByName(name);
if (dog == null) {
if (!picture.isEmpty()) {
String dogPicture = picture;
byte[] encodedDogPicture = Base64.encodeBase64(dogPicture.getBytes());
String format = dogPicture.substring(picture.lastIndexOf("."));
try {
} catch (Exception e) {
e.printStackTrace();
}
}
}
return objectMapper.readTree(response.toString());
}
I just have to say that this should probably only be used as a workaround.
On your frontend, convert the file to base64 in js:
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(evt) {
console.log(evt.target.result);
//do POST here - something like this:
$.ajax("/upload64", {
method: "POST",
contentType: "application/text"
data: evt.target.result
}
};
On the server with an example of a decoder - more decoding options here Decode Base64 data in Java
import sun.misc.BASE64Decoder;
#PostMapping("/upload64")
public String uploadBase64(#RequestBody String payload){
BASE64Decoder decoder = new BASE64Decoder();
byte[] decodedBytes = decoder.decodeBuffer(encodedBytes);
//use your bytes
}

Change the name of MultipartFile

I'm trying to change the name of MultipartFile.
I'm using MultipartFile on my controller to call rest service:
#PostMapping("/post")
public ResponseEntity<String> handleFileUpload(#RequestParam("file") MultipartFile file)
{
...
}
Have you please any idea about changing the OriginalFilename of the uploaded file ?.
Big thanks.
You can try the following code.
#PostMapping("/post")
public ResponseEntity<String> handleFileUpload(#RequestParam("file") MultipartFile file)
{
try {
String filename = "random_filename.pdf"; // Give a random filename here.
byte[] bytes = file.getBytes();
String insPath = <DIRECTORY PATH> + filename // Directory path where you want to save ;
Files.write(Paths.get(insPath), bytes);
return ResponseEntity.ok(filename);
}
catch (IOException e) {
// Handle exception here
}
}
You have to remember to add a random string to the file name. If you just hard code the file name, every time you upload a file, the previous file will be replaced.
You can achieve renaming of a file as below. To verify go the uploadDir and you will have a file with "renameTest".
You can append clientId + uploadTime to a filename to avoid the same filenames in database
#PostMapping(value = "/post")
public String renameMultipartFile(#RequestParam("file") MultipartFile file) {
String uploadDir = "yourPath";
String filename = "renameTest";
Path saveTO = Paths.get(uploadDir + filename);
try {
try {
Files.copy(file.getInputStream(), saveTO);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Error : " + e.getMessage());
}
return "File uploaded successfully";
} catch (Exception e) {
e.printStackTrace();
return "Error : " + e.getMessage();
}
}

File upload with in Spring MVC without adding any additional parameter in controller method

I am using spring boot 2. My new task is file uploading. I already did it. But I am asked to do it without adding a additional parameter to controller method like #RequestParam("files") MultipartFile files[]. I want to get this from request instead of adding this parameter.
How can I solve this?
I am adding my current code following.
#RequestMapping(value="/uploadMultipleFiles", method=RequestMethod.POST)
public #ResponseBody String handleFileUpload( #RequestParam("files") MultipartFile files[]){
try {
String filePath="c:/temp/kk/";
StringBuffer result=new StringBuffer();
byte[] bytes=null;
result.append("Uploading of File(s) ");
for (int i=0;i<files.length;i++) {
if (!files[i].isEmpty()) {
bytes = files[i].getBytes();
BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(filePath+files[i].getOriginalFilename())));
stream.write(bytes);
stream.close();
result.append(files[i].getOriginalFilename() + " Ok. ") ;
}
else
result.append( files[i].getOriginalFilename() + " Failed. ");
}
return result.toString();
} catch (Exception e) {
return "Error Occured while uploading files." + " => " + e.getMessage();
}
}
You can get files from HttpRequest:
#RequestMapping(value="/uploadMultipleFiles", method=RequestMethod.POST)
public String handleFileUpload(HttpRequest request){
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> yourFiles = multipartRequest.getFileMap();
return "All is Ok!";
}
My sample code.
#RequestMapping(value = "/multiple/upload", method = RequestMethod.POST)
public #ResponseBody String test(#RequestParam(value = "files[]") List<MultipartFile> files,
HttpServletRequest req) {
MultipartFileWriter writer = new MultipartFileWriter();
String folderPath = "/file/";
for (MultipartFile file : files) {
writer.writeFile(file, folderPath, req);
}
return "success";
}

Resources