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");
...
}
Related
I have a form that can be dynamically edited - the user can add/remove rows and information
The structure is this:
every element in the multidimensional array has the following elements:
id_material
id_detail
and in the rows that can be added/removed within the form:
name
quantity
file
the form:
<input type="hidden" name="myData[id_material][0]" value="123">
<input type="hidden" name="myData[id_detail][0]" value="456">
<input type="text" name="myData[ime_detail][0][1]" value="foo">
<input type="text" name="myData[quantity][0][1]" value="1">
<input type="file" name="myData[file][0][1]" accept=".pdf, .jpg, .dxf">
<input type="hidden" name="myData[id_material][1]" value="123">
<input type="hidden" name="myData[id_detail][1]" value="456">
<input type="text" name="myData[ime_detail][1][1]" value="foo">
<input type="text" name="myData[quantity][1][1]" value="1">
<input type="file" name="myData[file][1][1]" accept=".pdf, .jpg, .dxf">
<input type="text" name="myData[ime_detail][1][2]" value="bar">
<input type="text" name="myData[quantity][1][2]" value="2">
<input type="file" name="myData[file][1][2]" accept=".pdf, .jpg, .dxf">
My Spring controller:
#RequestMapping(value = myURL, method = RequestMethod.POST, consumes = {"multipart/form-data"})
public #ResponseBody error save(ModelMap model, HttpServletRequest req,
HttpSession session, HttpServletResponse resp,
#PathVariable("locale") String loc,
#RequestParam Map<String, Object> params) {
System.out.println("save() method invoked");
return null;
}
However, the controller method is never invoked when the form is submited. I have tried wrapping the parameters in a class like this:
public class CustomWrapper {
private Map<String, Object> customMap= new HashMap<String, Object>();
public Map<String, Object> getCustomMap() {
return customMap;
}
public void setCustomMap(Map<String, Object> customMap) {
this.customMap = customMap;
}
}
still its not invoked. Do you guys have any idea how to properly submit the form?
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 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;
}
#ModelAttribute annotation(Spring) allows for html to create an object.
For example there is a class
class Vasya{
int id;
String name;
//set get
}
and html form
<form action='path'>
<input type='text' name = 'id'/>
<input type='text' name = 'name'/>
<input type='submit'/>
</form>
#controller method:
#RequestMapping("/path")
public String processSkill( #ModelAttribute Vasya vasya) {...}
here it works.
Question:
how can I write html form using *checkbox*es for id and name that my controller method works?
Dont understand how to pass id using checkbox, but you can pass checkbox value that way:
#RequestMapping(value = "/test", method = RequestMethod.POST)
public String form(#RequestParam(required = false) Integer check) {
if(check != null) { // if checkbox is not selected it is null
System.out.println(check);
}
return "your-view";
}
jsp:
<form action="${home}/test" method="POST">
<input type="checkbox" value="1" name="check" />
<input type="submit" />
</form>