Today I am going to work with files and do it with spring mvc including uploading, saving and downloading files. Here we can practice spring-mvc and its features more and learn how to work with files in spring mvc.
Use case scenario
This is a file repository application. This application is an extension of simpleSpringSecurity application relating Spring Security post. Users can log in to the application. Then the file list page will be shown.
image 1 |
image 2 |
User can create or edit or delete files and folders. both of them are available in the same way. If a folder contains file(s) or folder(s), deleting will not be available and error will be shown. After clicking add button, user see this page
image 3 |
If user check the tick, so the input entry is file otherwise is folder. folders will be shown as link in list page. but files will be downloadable.
Note: each user has his or her own repository and others are not able to visit it.
Design and Class diagram
Files and Folders domain are the same. So we seperate them with a flag. isFile() method will determite if entry is file or folder. we should save file data in database. so in File table we should create a field with LONGBLOB datatype. In domain we use java.sql.Blob datatype. The class diagram is available here:
image 4 |
Most of techniques are the same in past posts. But there are 4 points here:
- Configuration: In spring-servlet.xml we should create a bean:
...
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="100000000"></property>
</bean> - Upload: This phase is so easy. you should just create an input file in your jsp:
<form:form id="fileForm" enctype="multipart/form-data">
<form:hidden path="file.id" id="fileId"/>
<form:hidden path="parentFolder.id" id="fileId"/>
<table>
<tr>
<td><label for="name">name</label></td>
<td><form:input path="file.name" id="name" maxlength="45"/></td>
</tr>
<tr>
<td><label for="file">file</label></td>
<td><input type="file" id="file" name="file"/></td>
</tr>
<tr>
<td><label for="isFile">is file</label></td>
<td><form:checkbox id="isFile" path="file.file"/></td>
</tr>
</table>
<input type="submit" value="save" onclick="setFormAction('<spring:url value="/file/save.html"/>')"/>
<input type="submit" value="back" onclick="setFormAction('<spring:url value="/file/list.html"/>')"/>
</form:form>@RequestMapping("/save")
public String save(@RequestParam(value = "file", required = false) MultipartFile inputFile) throws IOException, SQLException {
if (inputFile.getSize() > 0) {
file.setFileData(getBlobData(inputFile));
}
if (parentFolder != null && parentFolder.getId() != null) {
file.setParentFolder(fileService.findById(parentFolder.getId()));
getModel().addAttribute("parentFolder.id", parentFolder.getId());
}
file.setOwner(getCurrentUser());
fileService.saveOrUpdate(file);
return "redirect:list.html";
} - Save: Here you can convert MultipartFile to Blob:
public Blob getBlobData(MultipartFile file) throws IOException, SQLException {
byte[] bytes = file.getBytes();
return new SerialBlob(bytes);
}if (inputFile.getSize() > 0) {
file.setFileData(getBlobData(inputFile));
} - Download: Nothing changes in download. we should do everything that is done in classic servlet to download a file:
@RequestMapping("/download")
public void download() throws IOException, SQLException {
file = fileService.findById(file.getId());
if (file.getOwner().getId().equals(getCurrentUser().getId())) {
getResponse().setContentType("APPLICATION/OCTET-STREAM");
getResponse().addHeader("Content-Disposition", "attachment; filename=" + file.getName());
OutputStream out = getResponse().getOutputStream();
out.write(file.getFileData().getBytes(1, (int) file.getFileData().length()));
}
}
the admin user specification is:
username: administrator
password: 123456
you can use it to log in for the first time.
You may have exception whenever you'd like to upload a large file. you should change your server and database server configuration to be able to do it. You should increase the value of maxUploadSize field in multipartResolver bean. Then refer to your DBMS configuration and change it to make it able to handle large files. For example in mysql server, open "my.cnf" file (/etc/my.cnf in Linux and [window drive]\Program Files\MySQL\MySQL Server 5.0\my.cnf in MS Windows) then add or change this key:
[mysqld]
...
max_allowed_packet=100M
Ok. Try yourselves.
all rights reserved by Mostafa Rastgar and Programmer Assistant weblog
5 comments:
Hello, there's an error when file.setFileData(getBlobData(inputFile)) is executed, the error says: "ClassCastException: javax.sql.rowset.serial.SerialBlob cannot be cast to [B" could you help me? thanks in advance
hey
well... I think That's because of your jdk version. Please send me the complete stack trace.
But forget Blob. Try these changes:
File.java:
change the fileData field to this:
@Column(name = "file", updatable = false)
@Lob
byte[] fileData;
public byte[] getFileData() {
return fileData;
}
public void setFileData(byte[] fileData) {
this.fileData = fileData;
}
FileController.java:
@RequestMapping("/save")
public String save(...){
if (inputFile.getSize() > 0) {
file.setFileData(inputFile.getBytes());
}
...
}
@RequestMapping("/download")
public void download()...{
...
out.write(file.getFileData(), 0, file.getFileData().length);
...
}
Please try that and notify me.
Thanks
How can we convert blob to multipartfile ?? any suggestions
Thanks for sharing this nice post.
dbms student helper
We the BRS team which stands for Background Removal Services are providing you with highly graphic design and photo editing and obviously the most popular brand identity design at your cost. Do Visit to have the view of creative ideas of designs. Creative designs do help to grab the attraction of the customers. Make your own business flourish with powerful design concept today!
Post a Comment