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”);
}
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 am newbie to restful webservice.My requirement is to upload a multiple files.i successfully write the code for uploading multiple files in restful web service.Below is my code.
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces("text/plain")
#Path("/multipleFiles")
public String registerWebService(#Context HttpServletRequest request)
{
String responseStatus = SUCCESS_RESPONSE;
String candidateName = null;
//checks whether there is a file upload request or not
if (ServletFileUpload.isMultipartContent(request))
{
final FileItemFactory factory = new DiskFileItemFactory();
final ServletFileUpload fileUpload = new ServletFileUpload(factory);
try
{
/*
* parseRequest returns a list of FileItem
* but in old (pre-java5) style
*/
final List items = fileUpload.parseRequest(request);
if (items != null)
{
final Iterator iter = items.iterator();
while (iter.hasNext())
{
final FileItem item = (FileItem) iter.next();
final String itemName = item.getName();
final String fieldName = item.getFieldName();
final String fieldValue = item.getString();
if (item.isFormField())
{
candidateName = fieldValue;
System.out.println("Field Name: " + fieldName + ", Field Value: " + fieldValue);
System.out.println("Candidate Name: " + candidateName);
}
else
{
final File savedFile = new File(FILE_UPLOAD_PATH + File.separator
+ itemName);
item.write(savedFile);
}
}
}
}
catch (FileUploadException fue)
{
responseStatus = FAILED_RESPONSE;
fue.printStackTrace();
}
catch (Exception e)
{
responseStatus = FAILED_RESPONSE;
e.printStackTrace();
}
}
return responseStatus;
}
Is it good to upload multifiles in single request?
I want to consume the above restful webservice using restful template or jersey or any other java client.
Can anybody please guide me to write the client code for consuming the above webservice?
Any help will be greatly appreciated!!!
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.
This question already has answers here:
Recommended way to save uploaded files in a servlet application
(2 answers)
Closed 6 years ago.
<body>
<form method="post" action="DemoServlet" enctype="multipart/form-data" name="form1">
<input type="file" name="file" />
Image_Name:<input type="text" name="file"/>
<input type="submit" value="Go"/>
</form>
</body>
this is my index.jsp page.
This Servlet is DemoServlet when user click on submit button it will go here.while in jsp page suppose Image_Name given by user is IPL and actual name of image is funny.jpg then while saving the image it should store as IPL.png,here i'm able to upload image correctly with funny.jpg,but i need to save image as given name in text field of index.jsp page
public class DemoServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Date date = new Date();
response.setContentType("text/html");
PrintWriter out = response.getWriter();
boolean isMultiPart = ServletFileUpload.isMultipartContent(request);
if (isMultiPart) {
ServletFileUpload upload = new ServletFileUpload();
try {
FileItemIterator itr = upload.getItemIterator(request);
while (itr.hasNext()) {
FileItemStream item = itr.next();
if (item.isFormField()) {
String fieldname = item.getFieldName();
InputStream is = item.openStream();
byte[] b = new byte[is.available()];
is.read(b);
String value = new String(b);
response.getWriter().println(fieldname + ":" + value + "</br>");
} else {
String TempPath = getServletContext().getRealPath("");
String path = TempPath.substring(0, TempPath.indexOf("build"));
if (FileUpload.processFile(path, item)) {
out.println("File Uploaded on:" + date + "<br>");
response.getWriter().println("Image Upload Successfully");
} else {
response.getWriter().println("Failed.....Try again");
}
}
}
} catch (FileUploadException fue) {
fue.printStackTrace();
}
}
}
}
and this is java class
public class FileUpload {
public static boolean processFile(String path, FileItemStream item) {
try {
File f = new File(path + File.separator + "web/images");
if (!f.exists()) {
f.mkdir();
}
File savedFile = new File(f.getAbsolutePath() + File.separator + item.getName());
FileOutputStream fos = new FileOutputStream(savedFile);
InputStream is = item.openStream();
int x = 0;
byte[] b = new byte[1024];
while ((x = is.read(b)) != -1) {
fos.write(b, 0, x);
}
fos.flush();
fos.close();
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
Could anybody guide me how to change this dynamically.Thanks in advance.
I don't know how Servlet's and the like work however i can give you a rundown of what you need to do.
In DemoServlet you need to take in the input of the Image_Name field and make that one of your parameters of FileUpload
public static boolean processFile(String path, FileItemStream item, String fileName){
//Method Code
}
Because currently your processFile method is taking the name of the file from your FileItemStream. You need to change it from that to your actual fileName
File savedFile = new File(f.getAbsolutePath() + File.separator + item.getName());
to
File savedFile = new File(f.getAbsolutePath() + File.separator + fileName + ".png");
You can change the name of image in your java class code.
public class FileUpload {
public static boolean processFile(String path, FileItemStream item , String name) {
try {
File f = new File(path + File.separator + "web/images");
if (!f.exists()) {
f.mkdir();
}
File savedFile = new File(f.getAbsolutePath() + File.separator + item.getName()); // instead of item.getName() you can give your name.
FileOutputStream fos = new FileOutputStream(savedFile);
InputStream is = item.openStream();
int x = 0;
byte[] b = new byte[1024];
while ((x = is.read(b)) != -1) {
fos.write(b, 0, x);
}
fos.flush();
fos.close();
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
you will have to pass the file name in the method.
instead of item.getName() you can give your name.
List fileItems = upload.parseRequest(request);
Iterator i = fileItems.iterator();
System.out.println("In >>>>>>>>>>>>>>> :: "+fileItems);
while(i.hasNext()){
FileItem fi = (FileItem) i.next();
System.out.println("Val <<<<>>>>>>:: "+fi);
if(fi.isFormField()){
String fieldName = fi.getFieldName();
String val = fi.getString();
System.out.println(fieldName+" :: Val :: "+val);
}else{
String fileName = fi.getName();
String root = getServletContext().getRealPath("/");
File path = new File(root+"/uploads");
if (!path.exists()) {
boolean status = path.mkdir();
}
File uploadFile = new File(path+"/"+fileName);
fi.write(uploadFile);
}
In the code above you can change the file name at any time and it will automatically save with this name.
//How does not work in this way?Please tell me another way.
import java.io.File;
public class RenameFileExample {
public static void main(String[] args)
{
File oldfile =new File("oldfile.txt");
File newfile =new File("newfile.txt");
File file = new File("oldfilename.png");
file.renameTo(new File("newfilename.png"));
System.out.println("Rename To:"+file.getName());
if(oldfile.renameTo(newfile)){
System.out.println("Rename succesful");
}else{
System.out.println("Rename failed");
}
}
}
I'm using jsp and a servlet to do this.
I have a contact form that send a email with some data (name, subject, question,contact email etc) and a file.
when I submit the form, and get the servlet response only the first thing is returned.
String file= fileUpload(request); //upload the client's file and return the absolute path of the file in the server
//testing the rest of parameters
out.println("REQUEST LIST"
"\n" request.getParameter("name")
"\n" request.getParameter("mail")
"\n" request.getParameter("subject")
"\n" request.getParameter("ask")
"\n");
In this order the file is uploaded succesfully, but the other parameters (name, mail etc) are null.
In the order below, the parameters are ok, they return the data correctly. But the file is not uploaded.
//testing the rest of parameters
out.println("REQUEST LIST"
"\n" request.getParameter("name")
"\n" request.getParameter("mail")
"\n" request.getParameter("subject")
"\n" request.getParameter("ask")
"\n");
String file= fileUpload(request); //upload the client's file and return the absolute path of the file in the server
How can I have both?
Thanks!
You should extract the request parameters using the same API (e.g. Apache Commons FileUpload) as you've extracted the uploaded file. This is usually not interchangeable with calling getParameter() as the request body can be parsed only once (the enduser ain't going to send the same request twice, one to be parsed by the file upload parsing API and other to be parsed by getParameter()).
See also:
How to upload files to server using JSP/Servlet?
Look if the following code helps you. This is just an example. You may have to tweak it
Create a class called FileUploader which returns ServletFileUpload object
public class FileUploader
{
private static ServletFileUpload uploader;
private FileUploader()
{
}
public static synchronized ServletFileUpload getservletFileUploader(String tempDir, int maxSizeInMB)
{
if(uploader == null)
{
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(1024 * 1024);
factory.setRepository(new File(tempDir));
uploader = new ServletFileUpload(factory);
uploader.setFileSizeMax(maxSizeInMB * 1024 * 1024);
}
return uploader;
}
}
Now you can process a request and read all the data
protected MultiPartFormData handleMultiPartRequest(HttpServletRequest request)
throws FileSizeLimitExceededException
{
if(!isMultipartRequest(request))
return null;
ServletFileUpload upload = FileUploader.getservletFileUploader(tempDir, 50);
MultiPartFormData data = new MultiPartFormData();
try
{
List<FileItem> items = upload.parseRequest(request);
for (FileItem item : items)
{
if(item.isFormField())
{
data.getParameters().put(item.getFieldName(), item.getString());
}
else
{
String filename = item.getName();
//Internet explorer and firefox will send the file name differently
//Internet explorer will send the entire path to the file name including
//the backslash characters etc ... we should strip it down
//THIS IS HACKY
if(filename.indexOf("\\") != -1)
{
int index = filename.lastIndexOf("\\");
filename = filename.substring(index + 1);
}
if(filename == null || filename.equals(""))
{
//do nothing
}
else
{
File uploadFile = new File(uploadDir + File.separator + randomFileName);
item.write(uploadFile);
data.addFile(item.getFieldname(), item.getString());
}
}
}
}
catch(FileSizeLimitExceededException e)
{
throw e;
}
catch(Exception e)
{
e.printStackTrace();
}
return data;
}
After parsing the request I am storing it in some object called MultipartFormData which can be used to get request parameters
public class MultiPartFormData {
private Hashtable<String, String> parameters;
private Hashtable<String, String> uploadedFiles;
public MultiPartFormData()
{
this.parameters = new Hashtable<String, String>();
this.uploadedFiles = new Hashtable<String, String>();
}
public Hashtable<String, String> getParameters() {
return parameters;
}
public void setParameters(Hashtable<String, String> parameters) {
this.parameters = parameters;
}
public void getParameter(String paramName) {
if(this.parameters.contains(paramName))
return tyhis.parameters.get(paramName);
return null;
}
public void addFile(String key, String filename) {
uploadedFile.put(key, filename);
}
public void getFilename(String key) {
uploadedFile.get(key);
}
}