Upload file in jsp - java

i am trying to upload file using this code :
package controle;
#WebServlet("/upload")
#MultipartConfig
public class FileUploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
String id;
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
uploadFile(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
id = (String) request.getAttribute("id");
uploadFile(request, response);
}
private void uploadFile(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
for (Part part : request.getParts()) {
String name = part.getName();
InputStream is = request.getPart(name).getInputStream();
String fileName = getUploadedFileName(part);
FileOutputStream fos = new FileOutputStream(
"//C:/Users/achraf/workspace19/guidepro/WebContent/WEB-INF/imagesapp/profileapp"
+ fileName);
int data = 0;
while ((data = is.read()) != -1) {
fos.write(data);
}
fos.close();
is.close();
response.sendRedirect("success.jsp");
}
}
private String getFormat(String fileName) {
String format = "none";
int index = fileName.lastIndexOf(".");
if (index > 0) {
format = fileName.substring(index + 1);
format = format.toLowerCase();
}
return format;
}
private String getUploadedFileName(Part p) {
String file = "", header = "Content-Disposition";
String[] strArray = p.getHeader(header).split(";");
for (String split : strArray) {
if (split.trim().startsWith("filename")) {
file = split.substring(split.indexOf('=') + 1);
file = file.trim().replace("\"", "");
System.out.println("File name : " + file);
}
}
return file;
}
}
but when irun my application i get this error message:
java.io.FileNotFoundException: C:\Users\achraf\workspace19\guidepro\WebContent\WEB-INF\imagesapp\profileapp (Accès refusé)
java.io.FileOutputStream.open(Native Method)
java.io.FileOutputStream.<init>(Unknown Source)
java.io.FileOutputStream.<init>(Unknown Source)
controle.FileUploadServlet.uploadFile(FileUploadServlet.java:45)
controle.FileUploadServlet.doPost(FileUploadServlet.java:31)
javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
what went wrong????

Make sure there is a folder by the name imagesapp under the WEB-INF and as you have
//C:/Users/achraf/workspace19/guidepro/WebContent/WEB-INF/imagesapp/profileapp"
which means it will append the fileName to profileapp and store it in imagesapp.But if you are assuming that the file will be kept under profileapp then just put a slash atfer it like this
C:/Users/achraf/workspace19/guidepro/WebContent/WEB-INF/imagesapp/profileapp/"

In uploadFile method:
String name = part.getName();
InputStream is = request.getPart(name).getInputStream();
You already has the part to get the input stream and are using getPart(name) to get the same instance part above.
I will not recommend to get the input stream to write after to a file with some output stream.
Instead if it do the following:
String fileName = part.getHeader("content-disposition").replaceAll(".+filename=\"(.+)\"", "$1");
String fileFormat = fileName.replaceAll(".+[.](.+)$", "$1");
part.write("//C:/Users/achraf/workspace19/guidepro/WebContent/WEB-INF/imagesapp/profileapp/" + filename);
note here:
"//C:/Users/achraf/workspace19/guidepro/WebContent/WEB-INF/imagesapp/profileapp"
+ fileName
is what you did. The final / is missing in profileapp.
The message error throws:
java.io.FileNotFoundException: C:\Users\achraf\workspace19\guidepro\WebContent\WEB-INF\imagesapp\profileapp
profileapp is a folder. The message shows that your method return an empty string defined as "" at the begin of the method. If your method returns "SOME_STRING", you will see the following message error if the folder imagesapp doesn't exists:
java.io.FileNotFoundException: C:\Users\achraf\workspace19\guidepro\WebContent\WEB-INF\imagesapp\profileappSOME_STRING
Otherwise you will create the profileappSOME_STRING file inside imagesapp folder.
If your profileapp folder doesn't exists, you would create the file profileapp inside imagesapp folder without exception. Not that you had an Access refuse. You are trying to write the content in a folder as a file.

Related

How to solve ERROR java.nio.file.AccessDeniedException: D:\workspace_intellij_forKiri\Kiri\server\kiri\temp\28004d6bc31cfiles.png

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.

Passing a method value to member of a class in java

I have a class dedicated to encode and decode files. The encode method receives in its signature a string corresponding to the file path to encode. The encodeFileToBase64Binary is returning a simple String that I use to build a JSON object.
My objective would be to get the file name to the decode folder in order to create a new file. Those two methods are called at distinct moments.
public class FileConverterBase64 {
private ApplicationProperties properties = new ApplicationProperties();
private String toSignFilePath;
public String encodeFileToBase64Binary(String filePath) throws IOException {
this.toSignFilePath = filePath;
byte[] fileContent = FileUtils.readFileToByteArray(new File(filePath));
return Base64.getEncoder().encodeToString(fileContent);
}
public void stringDecodeFileToPdf(String encodedFile) throws IOException {
System.out.println("toSignFilePath : " + toSignFilePath);
// deposit repository
String folder = properties.getProperty("document.signed");
LocalDateTime now = LocalDateTime.now();
String outputFileName = folder + "\\" + now + "" + toSignFilePath + "-signed";
byte[] decodedBytes = Base64.getDecoder().decode(encodedFile);
FileUtils.writeByteArrayToFile(new File(outputFileName), decodedBytes);
}
}

Reading file data from shared folder with authentication (FileNotFound Exception)

Following is the code I use to access file from a share folde by authenticating and reading data from the file.(using JCIFs)
public void findFiles() throws Exception{
String url = rs.getString("addPolicyBatchFolder_login_url"); //username, url, password are specified in the property file
String username = rs.getString("addPolicyBatchFolder_login_userName");
String password = rs.getString("addPolicyBatchFolder_login_password");
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(null, username, password);
SmbFile dir = null;
dir = new SmbFile(url, auth);
SmbFilenameFilter filter = new SmbFilenameFilter() {
#Override
public boolean accept(SmbFile dir, String name) throws SmbException {
return name.startsWith("starting string of file name");//picking files which has this string on the file name
}
};
for (SmbFile f : dir.listFiles(filter))
{
addPolicyBatch(f.getCanonicalPath()); //passing file path to another method
}
}
With this code, I'm successfully authenticating and I'm able to list the files. And I tried printing canonical path(i tried with just f.path() also) and im able to print the complete path.
Following is the next method.
public void addPolicyBatch(String filename) throws Exception{
File csvFile = new File(filename);
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(csvFile)); //FileNotFound exception
while((line = br.readLine()) != null){
//more code
In the above method, when it comes to bufferReader, its showing FleNotFoundException.
If I print the canonical path, following is the output.
smb://sharePath/file.csv correct path
But in the second method(where I get Exception), the exception is as follows.
java.io.FileNotFoundException: smb:\sharePath\file.csv (The filename, directory name, or volume label syntax is incorrect)
As you can see, there is only one \ after smb:.
I'm not sure why its not passing the exact file path as printed in the first method.
If you remove the leading smb: from the name it should work.
Alternatively, you can change your method as follows and use the smb file to create a reader:
public void addPolicyBatch(SmbFile smbFile) throws Exception {
BufferedReader br = null;
try {
SmbFileInputStream smbStream = new SmbFileInputStream(smbFile);
br = new BufferedReader(new InputStreamReader(smbStream));
String line;
while((line = br.readLine()) != null){
//....
Edit, renaming a file.
If you want to use SmbFile to rename, you need the authentication object
public static void renameSmbFile(SmbFile srcFile, String completeUrl,
NtlmPasswordAuthentication auth) throws Exception {
SmbFile newFile = new SmbFile(completeUrl,auth);
srcFile.renameTo(newFile);
}
Wenn using a File object, that is not neccessary:
public static void renameFile(SmbFile srcFile, String nameWithoutProtocol,
NtlmPasswordAuthentication auth) throws Exception {
String fileName = srcFile.getCanonicalPath();
fileName = fileName.substring(4);//removing smb-protocol
new File(fileName).renameTo(new File(nameWithoutProtocol));
}

how to get getServletContext() in spring mvc Controller

I need to upload images in my project. How to get the upload path in SpringMVC.
The path is;
/home/cme/project/eclipse/workspace_12_11/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/fileUploadTester/upload
The following error;
The method getServletContext() is undefined for the type HomePageController
appears when I use this code;
String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIRECTORY;
My code is
public ModelAndView UploadPhoto(#ModelAttribute User user, HttpServletRequest request, HttpServletResponse response) throws IOException {
final String UPLOAD_DIRECTORY = "upload";
final int THRESHOLD_SIZE = 1024 * 1024 * 3; // 3MB
final int MAX_FILE_SIZE = 1024 * 1024 * 40; // 40MB
final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; // 50MB
String value[] = new String[10];
int i = 0;
// checks if the request actually contains upload file
if (!ServletFileUpload.isMultipartContent(request)) {
PrintWriter writer = response.getWriter();
writer.println("Request does not contain upload data");
writer.flush();
return; //here is error This method must return a result of type ModelAndView
}
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(THRESHOLD_SIZE);
factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setFileSizeMax(MAX_FILE_SIZE); //here error The method setFileSizeMax(int) is undefined for the type ServletFileUpload
upload.setSizeMax(MAX_REQUEST_SIZE);
String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIRECTORY; // here error The method getServletContext() is undefined for the type Homepage Controller
// creates the directory if it does not exist
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}
try {
List < FileItem > items = upload.parseRequest(request); // request is HttpServletRequest
for (FileItem item: items) {
if (item.isFormField()) { // text fields, etc...
String fieldName = item.getFieldName();
System.out.print("fieldname" + fieldName);
value[i] = item.getString();
System.out.print("from uploader" + value[i]);
i++;
} else {
//String fileName=new File(item.getName()).getName(); Use this to use default file name
String name = value[0];
System.out.println("file uploader name" + name);
String filePath = uploadPath + File.separator + name;
System.out.println(filePath);
File storeFile = new File(filePath);
try {
item.write(storeFile);
} catch (Exception ex) {
}
}
}
System.out.println("uploaded successfully");
} catch (Exception ex) {
System.out.println("error not uploaded");
}
return new ModelAndView("ChangePhoto");
}
Three error
This method must return a result of type ModelAndView
The method setFileSizeMax(int) is undefined for the type ServletFileUpload
The method getServletContext() is undefined for the type Homepage Controller
Use below code to autowire ServletContext object in SpringMVC
#Autowired
ServletContext context;
and after that try to execute your code like
String uploadPath = context.getRealPath("") + File.separator + UPLOAD_DIRECTORY;
You can get it in your controller like this;
private ServletContext context;
public void setServletContext(ServletContext servletContext) {
this.context = servletContext;
}
but for this your controller must implement ServletContextAware interface
Try this:
#Autowired
ServletContext servletContext;
This is just another alternative
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getServletContext()
The parameters you passed or set to the ServletContext object, are stored into HttpServletRequest object, you can access them anywhere in application in following way:
public void method(HttpServletRequest request){
String email=request.getServletContext().getInitParameter(“email”);
}

Error with GwtUpload Servlet

I'm trying to implement the Basic example for the GwtUpload library, as found here.
In my server code, I get the following error:
Exception java.lang.ClassCastException: org.apache.commons.fileupload.disk.DiskFileItem cannot be cast to org.apache.commons.fileupload.FileItem
I can't figure out why this is happening. DiskFileItem is a subclass of FileItem and should work. I've stepped through in the debugger and confirmed that the two classes are what they appear to be, yet the assignment fails.
Even more strangely, when I attempt to call the FileItem methods in the watch window, I have no problems, but if I attempt to access them in the code, I get the error.
Here is my Servlet code:
public class GwtUploadServlet extends UploadAction
{
private static final long serialVersionUID = 1L;
/**
* Maintain a list with received files and their content types.
*/
Hashtable<String, String> receivedContentTypes = new Hashtable<String, String>();
/**
* Maintain a list with received files.
*/
Hashtable<String, File> receivedFiles = new Hashtable<String, File>();
/**
* Override executeAction to save the received files in a custom place and
* delete this items from session.
*/
#Override
public String executeAction(HttpServletRequest request,
List<FileItem> sessionFiles) throws UploadActionException
{
String response = "";
int cont = 0;
for ( int i = 0 ; i < sessionFiles.size(); i++ )
{
if (false == sessionFiles.get(i).isFormField())
{
cont++;
try
{
// / Create a temporary file placed in the default system
// temp folder
File file = File.createTempFile("upload-", ".bin");
sessionFiles.get(i).write(file);
// / Save a list with the received files
receivedFiles.put(sessionFiles.get(i).getFieldName(), file);
receivedContentTypes.put(sessionFiles.get(i).getFieldName(),
sessionFiles.get(i).getContentType());
// / Send a customized message to the client.
response += "File saved as " + file.getAbsolutePath();
}
catch (Exception e)
{
throw new UploadActionException(e);
}
}
}
// / Remove files from session because we have a copy of them
removeSessionFileItems(request);
// / Send your customized message to the client.
return response;
}
/**
* Get the content of an uploaded file.
*/
#Override
public void getUploadedFile(HttpServletRequest request,
HttpServletResponse response) throws IOException
{
String fieldName = request.getParameter(PARAM_SHOW);
File f = receivedFiles.get(fieldName);
if (f != null)
{
response.setContentType(receivedContentTypes.get(fieldName));
FileInputStream is = new FileInputStream(f);
copyFromInputStreamToOutputStream(is, response.getOutputStream());
}
else
{
renderXmlResponse(request, response, ERROR_ITEM_NOT_FOUND);
}
}
/**
* Remove a file when the user sends a delete request.
*/
#Override
public void removeItem(HttpServletRequest request, String fieldName)
throws UploadActionException
{
File file = receivedFiles.get(fieldName);
receivedFiles.remove(fieldName);
receivedContentTypes.remove(fieldName);
if (file != null)
{
file.delete();
}
}
}
Make sure you don't have multiple versions of commons-fileupload on the classpath.

Categories