SpringMVC WEB应用上传照片的实现
使用是SpringMVC+Hibernate搭建的WEB应用,使用jsp写的前端页面。
如何将文件上传到服务器呢?我这里使用的是Multipart的形式将文件上传。
这里有两大步:一是配置multipart解析器,二是处理multipart请求。
DispatcherServlet并没有实现任何解析multipart请求数据的功能。它将这个任务委托给Spring中的MultipartResolver 接口来实现。Spring3.1开始,Spring内置了两个MultipartResolver的实现。
①、CommonsMultipartResolver:使用Jakarta Commons FileUpload解析multipart 请求;
使用这个实现需要依赖其他jar包。commons-fileupload jar包和 commons-io jar包
如果你的WEB应用的容器是Servlet3.0以下的,那么就需要使用CommonsMultipartResolver来解决了。比如你使用的是Tomcat,那么如果是7.0以前的版本就是servlet3.0以下的(不太确定)。
②、StandardServletMultipartResolver:依赖于Servlet3.0对multipart请求的支持。
下面我使用的是第一种解析器:CommonsMultipartResolver 来完成上传文件的任务
一、使用CommonsMultipartResolver 来完成上传文件的任务
一)、配置解析器
①、添加commons-fileupload-1.3.2 jar包、commons-io-2.5 jar包
②、创建一个配置类,配置 MultipartResolver
package com.zcd.config; import java.io.IOException; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.FileSystemResource; import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.multipart.commons.CommonsMultipartResolver; @Configuration @ComponentScan public class MyConfig { @Bean public MultipartResolver multipartResolver() throws IOException { CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); //指定上传文件的临时存储路径。 multipartResolver.setUploadTempDir(new FileSystemResource("E:/fileUploadTest_1")); return multipartResolver; } }
二)、处理multipart请求
①、先用jsp写一个表单,如下:
<form:form action="${pageContext.request.contextPath}/userController/save" method="POST" modelAttribute="user" enctype="multipart/form-data" > <form:hidden path="id"/> 姓名:<form:input path="name"/> <br> <form:hidden path="photo"/> 照片:<input type="file" name="photo1" accept="image/jpeg,image/png,image/gif" > <br> <input type="submit" name="Submit" value="保存" > </form:form>
表单对应的前端界面:
②、响应的Controller中的方法,这里以字节数组的形式接受上传的文件。
/* * 以字节数组的形式接收上传的文件,如果要是上传多个文件的话,就要在加一个参数。这样会非常不方便。 */ @RequestMapping(value="save", method=RequestMethod.POST) public String save(@RequestPart(value="photo1") byte[] photo, User user) { /* * 表单中的name属性值必须和@RequestPart的value属性值相等,而且还要以字节数组的形式接受上传的文件。 * 以字节数组的方式接收就不能查看文件的相关信息。 */ //这里如何将的photo的全路径获取??????不能获取就不能将文件的路径保存到数据库中。 userService.save(user); return "success"; }
文件上传到了配置解析器时指定的目录中:
--------------------------------------------------------------------------------------------------------------------
如果想上传多个文件呢??怎么办???可以MultipartFile数组的形式接收上传的文件。
jsp代码:
<form:form action="${pageContext.request.contextPath}/userController/uploadPotos" method="POST" modelAttribute="user" enctype="multipart/form-data" > <form:hidden path="id"/> 姓名:<form:input path="name"/> <br> <form:hidden path="photo"/> 图片1:<input type="file" name="files" accept="image/jpeg,image/png,image/gif" > <br> 图片2:<input type="file" name="files" accept="image/jpeg,image/png,image/gif" > <br> <input type="submit" name="Submit" value="保存" > </form:form>
注意:①、本例中name属性中的属性值files,要和Controller中的方法的相应的参数名相同如: @RequestPart MultipartFile[] files
②、本例中的User对象只有一个photo字段,所以只能保存一个文件在磁盘上的路径,这里是为了方便,没有再增加一个字段来保存第二张图片的路径。这里仅仅是为了示范如何以MultipartFile数组的形式接收多个文件的。
可以使用MultipartFile接口接收上传的文件。需要修改Controller中的处理方法。代码如下:
/* * 以MultipartFile的形式接收文件,而且可以只需要一个@RequestPart 注解,以MultipartFile[] 数组的形式接收上传的文件。 */ @RequestMapping(value="uploadPotos") public String uploadPotos(@RequestPart MultipartFile[] files, User user) throws IllegalStateException, IOException { //将第一个file对象的全路径作为User的photo字段的值保存到数据库中。 MultipartFile file = files[0]; String filePath = "E:/fileUploadTest_1/" + file.getOriginalFilename(); user.setPhoto(filePath); userService.save(user); for(MultipartFile f : files) { System.out.println("文件原始名称:" + f.getOriginalFilename()); /* * 以MultipartFile的形式接受上传的文件,那么之前在配置解析器的时候指定的保存上传文件的目录就不行了。 * 这里使用MultipartFile给我们提供的transferTo()方法将文件保存到文件系统中。 */ f.transferTo(new File("E:/fileUploadTest_1/" + f.getOriginalFilename())); } return "success"; }
将文件保存到系统目录后的截图
二、使用StandardServletMultipartResolver 解析器来完成上传文件的任务
一)、配置StandardServletMultipartResolver 解析器
这个不需要依赖额外的jar包
package com.zcd.config; import java.io.IOException; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.multipart.support.StandardServletMultipartResolver; @Configuration @ComponentScan public class MyConfig { @Bean public MultipartResolver multipartResolver() throws IOException { return new StandardServletMultipartResolver(); } }
为上传的文件指定一个临时路径、还可以配置其他的如文件的大小等等
使用web.xml来配置
<servlet> <servlet-name>springDispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> <!-- 支持文件上传 --> <multipart-config> <!-- 指定上传的文件的临时存储目录 --> <location>E:/multipartTest4</location> </multipart-config> </servlet>
二)、处理Multipart请求
@RequestMapping(value="uploadPotos") public String uploadPotos(@RequestPart MultipartFile[] files, User user) throws IllegalStateException, IOException { for(MultipartFile f : files) { System.out.println("文件原始名称:" + f.getOriginalFilename().substring(f.getOriginalFilename().lastIndexOf("\\") + 1)); /* * 以MultipartFile的形式接受上传的文件,那么之前在配置解析器的时候指定的保存上传文件的目录就不行了。 * 这里使用MultipartFile给我们提供的transferTo()方法将文件保存到文件系统中。 * 使用StandardServletMultipartResolver解析器与CommonsMultipartResolver解析器有一个不同的地方,就是getOriginalFileName()方法获取得到的名称不一样,一个是获取到全路径,一个仅仅是获取文件名称。 */ String filePath = "E:/fileUploadTest_2/" + f.getOriginalFilename().substring(f.getOriginalFilename().lastIndexOf("\\") + 1); f.transferTo(new File(filePath)); user.setPhoto(filePath); userService.save(user); } return "list2"; }