I am trying to upload a file using Spring MVC.
Here is the form in the .jsp page
<form:form method="post" commandName="file" enctype="multipart/form-data">
Upload your file please:
<input type="file" name="file" />
<input type="submit" value="upload" />
<form:errors path="file" cssStyle="color: #ff0000;" />
</form:form>
In my controller I have the GET and POST methods:
#RequestMapping(method = RequestMethod.GET)
public String getForm(Model model) {
File fileModel = new File();
model.addAttribute("file", fileModel);
return "file";
}
#RequestMapping(method = RequestMethod.POST)
public String fileUploaded(Model model, #Validated File file, BindingResult result) {
String returnVal = "successFile";
logger.info("I am here!!!");
if (result.hasErrors()) {
returnVal = "file";
}else{
MultipartFile multipartFile = file.getFile();
}
return returnVal;
}
The validation is just to check if the file size is zero:
public void validate(Object target, Errors errors) {
File imageFile = (File)target;
logger.info("entered validator");
if(imageFile.getFile().getSize()==0){
errors.rejectValue("file", "valid.file");
}
}
The method GET works fine and returns the file view, however the POST method in the controller does not get called. Nothing happens when the upload button is clicked.
I hope this will help you:
controller code
#RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public String uploadInputFiles(#RequestParam("file1") MultipartFile file,
#RequestParam("fileName") String fileName,
#RequestParam("fileType") String fileType){
System.out.println("Upload File Controller has been called");
}
Form submission:
<form method="POST" action="uploadFile" enctype="multipart/form-data">
File to upload: <input type="file" name="file"><br />
Name: <input type="text" name="name"><br /> <br />
<input type="submit" value="Upload"> Press here to upload the file!
</form>
I think your configuration should be like below in mvc-servlet.xml file.
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="500000" />
</bean>
and change your post api like below.
#RequestMapping(method = RequestMethod.POST,value = "/uploadFile")
public String fileUploaded(Model model, #RequestParam("file") MultipartFile file, BindingResult result) {
String result = "not uploaded";
if(!file.isEmpty()){
MultipartFile multipartFile = file.getFile();
//code for storing the file in server(in db or system)
}
else{
result = "can not be empty;"
}
return result;
}
Related
I am trying to create a file upload utility and am getting the following error when I click on the submit button. It starts uploading and then suddenly has this error:
There was an unexpected error (type=Bad Request, status=400).
Required request part 'file' is not present
I don't have a stacktrace, that's all that's displayed in my window or my console. I've looked for other solutions and they all ended up being someone forgot to include name="file" in their html file. I have made sure it's included and am still getting the error.
Below is my upload form:
<div id="custom-search-input">
<label>Select a file to upload</label>
<form action="/upload" enctype="multipart/form-data" method = "post">
<div class="input-group col-md-12">
<input type="file" name="file" class="search-query form-control"/>
<span class="input-group-btn">
<button type="submit" class="btn btn-success">Upload </button>
</span>
</div>
</form>
</div>
This is my controller method for uploading:
#Value("${upload.path}")
private String path;
#RequestMapping("/upload")
public String upload(#RequestParam("file") MultipartFile file, Model model, HttpSession session) throws IOException {
if(!file.isEmpty()) {
//Get the user
User user = (User) session.getAttribute("user");
//Get the file name
String fileName = file.getOriginalFilename();
InputStream is = file.getInputStream();
//Store the uploaded file into the users directory in the system path
Files.copy(is, Paths.get(path + user.getNetworkId() + "\\" + fileName),StandardCopyOption.REPLACE_EXISTING);
return "redirect:/success.html";
} else {
return "redirect:/index.html";
}
}
Also would like to note I tried this for my upload method:
public String upload(#RequestParam(name="file",required=true) MultipartFile file, Model model, HttpSession session)
For reference, this is what I was referrencing.
As per some of the answers below, I tried creating a PostMapping method stand alone, as well as #RequestMapping(value="/upload", method = RequestMethod.POST) I am still getting the error.
After a while, I was able to solve this issue: In my application.properties file I added the following:
spring.servlet.multipart.max-file-size=128MB
spring.servlet.multipart.max-request-size=128MB
spring.http.multipart.enabled=true
upload.path=/export/home/
Your <form> in your view code is with method as POST
<form action="/upload" enctype="multipart/form-data" method = "post">
In controller change #RequestMapping("/upload") to below
#RequestMapping(value = "/upload", method = RequestMethod.POST)
you need something to handle loading the form a #GetMapping.
The #RequestMapping i think defaults to get. So when you are "getting" the page it tries to hit your method that is expecting a file. take a look at my example
I would recommend using #RequestPart. If you are uploading a file using from-data try to rewrite the code like below:
#PostMapping("/upload")
public ResponseEntity<CustomResponse> uploadFile(#RequestPart(value = "file",required = true) MultipartFile file,
#RequestPart(value = "metadata",required = true) Metadata metadata,
HttpServletResponse response)
I have had similar issue, in my case the reason was the name of the input tag of the form was not matching with #RequestParam("fileUpload") annotation parameters.
#PostMapping("/add")
public String addFile(#RequestParam("fileUpload") MultipartFile fileUpload, Model model, Authentication authentication) {
User loggeduser = userService.getUser(authentication.getName());
File newFile = new File();
String fileName = StringUtils.cleanPath(fileUpload.getOriginalFilename());
File fileaux = filesService.getFileByName(fileName);
int result = -1;
if (fileaux != null) {
model.addAttribute("result", false);
model.addAttribute("message", "File already exists");
return "result";
} else {
try {
newFile.setFilename(StringUtils.cleanPath(fileName));
newFile.setContentType(fileUpload.getContentType());
newFile.setFileSize(String.valueOf(fileUpload.getSize()));
newFile.setUserId(loggeduser.getUserid());
newFile.setFileData(fileUpload.getBytes());
result = filesService.addFile(newFile);
} catch (Exception e) {
e.printStackTrace();
}
}
if (result < 0) {
model.addAttribute("result", false);
} else {
model.addAttribute("result", true);
}
return "result";
}
it must match with the input form tag in the HTML file.
<form action="#" enctype="multipart/form-data" th:action="#{/file/add}" method="POST">
<div class="container">
<div class="row" style="margin: 1em;">
<div class="col-sm-2">
<label for="fileUpload">Upload a New File:</label>
</div>
<div class="col-sm-6">
<input type="file" class="form-control-file" id="fileUpload" name="fileUpload">
</div>
<div class="col-sm-4">
<button type="submit" class="btn btn-dark" id="uploadButton">Upload</button>
</div>
</div>
</div>
How to upload files to the #ModelAttribute using Thymeleaf?
I'am doing something that:
upload.html
<form method="POST" action="#" th:action="#{/sending}" th:object="${collage}" enctype="multipart/form-data" >
<input type="file" th:field="*{picture}" />
<input type="file" th:field="*{picture}" />
<input type="submit" value="upload" />
</form>
My controller:
#Controller
public class MainController {
#GetMapping(value = { "/" })
public String index(){
return "upload";
}
#GetMapping("/collage")
public String paintPicture(Model model){
return "collage";
}
#PostMapping("/sending")
public String redirect(#ModelAttribute(value="collage") Collage collage, RedirectAttributes redirectAttr) {
Collections.shuffle(Arrays.asList(collage.getCollage()));
redirectAttr.addFlashAttribute("pictures",collage.getCollage());
return "redirect:/collage";
}
}
Collage.class:
public class Collage {
private MultipartFile[] pictures;
public Collage(){}
public MultipartFile[] getCollage() {
return pictures;
}
public void setCollage(MultipartFile[] pictures) {
this.pictures = pictures;
}
}
I'm getting: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'collage' available as request attribute in the console and a text on "/" page:
One picture is better than 1000 words:
Now code example to upload an array of multipartfiles inside of Entity:
<form action="#" th:action="#{/distribution/save}" class="form-horizontal"
role="form" method="post" th:object="${news}" enctype="multipart/form-data">
<input type="hidden" name="id" value="id" th:field="*{id}"> <div class="form-group has-label"> <label for="inputTitle" th:text="#{news.title}">TÃtulo</label>
<input type="text" class="form-control" id="inputTitle" th:placeholder="#{news.title}" th:field="*{title}"></div>
<input type="file" name = "multipartFilesDocument" value="multipartFilesDocument" th:field="*{multipartFilesDocument}" multiple="multiple"/>
<button type="submit" class="btn btn-default"><span th:text="#{common.save}"></span></button>
</div>
</form>
Controller Code:
#PostMapping("/save")
public String saveMultiparthFile(Model model,#ModelAttribute NewsDTO eventDTO){
eventDTO.getId();
return getrDetail(model);
}
Entity code:
public class NewsDTO {
private List<MultipartFile> multipartFilesDocument;
public List<MultipartFile> getMultipartFilesDocument() {
return multipartFilesDocument;
}
public void setMultipartFilesDocument(List<MultipartFile> multipartFilesDocument) {
this.multipartFilesDocument = multipartFilesDocument;
}
}
In this code is really important enctype="multipart/form-data" and name = "multipartFilesDocument" value="multipartFilesDocument" in form
you can apply this changes
1) change #ModelAttibute to #RequestParam
2) use MultipartFile[] as param and only use a single input file html
//name of input html should be collage
#PostMapping("/sending")
public String redirect(#RequestParam("collage") MultipartFile[] files, RedirectAttributes redirectAttr) {
Collections.shuffle(Arrays.asList(files));
redirectAttr.addFlashAttribute("pictures",files);
return "redirect:/collage";
}
and your html page
<form method="POST" th:action="#{/sending}" enctype="multipart/form-data" >
<input type="file" name="collage" multiple="multiple"/>
<input type="submit" value="upload" />
</form>
I'm sending an object to spring controller via jsp form.
JSP:
<form:form modelAttribute="uploadItem" action="/uploadObject" method="post" enctype="multipart/form-data">
<form:input path="fileData" accept="audio/mpeg" type="file" id="file-upload" name="file-upload" />
<form:input type="text" path="title" id="upload-title" name="upload-title"/>
<input type="image" src="..." alt="Upload"/>
</form:form>
ModelService:
public void fillUploadMelodyModel(Model model) {
fillAdminRootModel(model);
model.addAttribute("uploadItem", new UploadedItem());
}
UploadedItem:
public class UploadedItem {
private CommonsMultipartFile fileData;
private String title;
}
Controller:
#RequestMapping(value = "/uploadObject", method = RequestMethod.POST)
public String doUpload(UploadedItem uploadItem, BindingResult result, Principal principal) {
//at this point I get an empty object (null null values)
}
What is the problem? How to pass object to controller in jsp?
Try changing then your controller like this
#RequestMapping(value = "/uploadObject", method = RequestMethod.POST)
public String doUpload(UploadedItem uploadItem,
BindingResult result,
#RequestParam("fileData") MultipartFile file,
#RequestParam("title") String title,
Principal principal) {
//Here you should receive your parameters
}
I think the names you have used for the file (file-upload) and title (upload-title) are not in sync with your domain object attribute names. Change your names to fileData and title in your Jsp page.
I need to load an unknown number of files at once.
I found an example, and it works for a known amount of files:
markup:
<form method="POST" enctype="multipart/form-data">
<input name="files[0]" type="file" />
<input name="files[1]" type="file" />
<input type="submit" value="Send"/>
</form>
code:
#RequestMapping(method = RequestMethod.POST)
public String savePhoto(#ModelAttribute("album") Album album, BindingResult result, SessionStatus status, MultiPartFileUploadBean file)
{
List<MultipartFile> images = file.getFiles();
for (MultipartFile photo : images) {
...
}
return "redirect:/albums/"+album.getId();
}
MultiPartFileUploadBean:
public class MultiPartFileUploadBean {
private List<MultipartFile> files;
public void setFiles(List<MultipartFile> files) {
this.files = files;}
public List<MultipartFile> getFiles() {
return files;}
}
Yes, it works, but I do not know how the user wants to upload a photo in the album.
And I use:
<input name="files[]" type="file" multiple="multiple" />
I'll get a error.
Request processing failed; nested exception is
java.lang.NumberFormatException: For input string: ""
I was looking for how to use multiple = "multiple", but found none. I hope for your help.
In your XHTML:
<input name="files" type="file" multiple="multiple" />
Alter the request-mapped method:
#RequestMapping(method = RequestMethod.POST)
public String savePhoto(MultipartRequest multipartRequest, ...)
{
List<MultipartFile> images = multipartRequest.getFiles("files");
...
}
#RequestMapping(value = "{fileName:.+}", method = RequestMethod.POST, consumes = { MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<ResponseEnvelope<String>> uploadFile(
#RequestParam("ownerId") Long ownerId,
#PathVariable("fileName") String fileName,
#RequestBody MultipartFile file)
throws Exception {
ResponseEnvelope<String> env;
if(null == certFileContent) {
env = new ResponseEnvelope<String>("fail");
return new ResponseEntity<ResponseEnvelope<String>>(env, HttpStatus.OK);
}
service.uploadCertificate(ownerId, fileName, certFileContent.getBytes());
env = new ResponseEnvelope<String>("success");
return new ResponseEntity<ResponseEnvelope<String>>(env, HttpStatus.OK);
}
Why I always get the file value is null, I've configure the multipart support,see below,
The file should be binded to a RequestParam instead of the RequestBody as follows:
public ResponseEntity<ResponseEnvelope<String>> uploadFile(
#RequestParam("ownerId") Long ownerId,
#PathVariable("fileName") String fileName,
#RequestParam(value = "file") MultipartFile file)
This would correspond with the following HTML form:
<form method="post" action="some action" enctype="multipart/form-data">
<input type="file" name="file" size="35"/>
</form>
Then in your dispatcher configuration specify the CommonsMultiPartResolver
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="5000000"/>
</bean>
This is what worked for me,
Previously my input field was defined as,
<input type="file" />
I was getting null file with the above line but when I added the name="file" everything worked fine!
<input type="file" name="file" />
Hope this helps!