import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
@Controller
public class FileUploadController {
@RequestMapping(value="/upload", method=RequestMethod.POST)
public @ResponseBody String handleFileUpload(@RequestParam("name") String name,
@RequestParam("file") MultipartFile file){
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
BufferedOutputStream stream =
new BufferedOutputStream(new FileOutputStream(new File(name + "-uploaded")));
stream.write(bytes);
stream.close();
return "You successfully uploaded " + name + " into " + name + "-uploaded !";
} catch (Exception e) {
return "You failed to upload " + name + " => " + e.getMessage();
}
} else {
return "You failed to upload " + name + " because the file was empty.";
}
}
}
但要使这个controller有效,你需要申明一个解析multipart的resolver,因为spring本身不实现如何解析,
所以你需要告诉DispatcherServlet如何去解析multipart request.
关于文件上传,有这两个解析器.
CommonsMultipartResolver—Resolves multipart requests using Jakarta Commons FileUpload
StandardServletMultipartResolver—Relies on Servlet 3.0 support for multipart requests (since Spring 3.1)
关于这两个,一般推荐是直接选Standard版,不推荐commons,
虽然commons他默认不需要配置上传文件的临时存放位置,他的默认位置是servlet容器的临时位置,(如果standard不显示的配置文件位置,是不能正常运行的) ,,同时和sping独立.不集成在spring里面,
但如果你是使用spring3.0以下,或者不适用spring3.1以上,那你只能适用commons了.
所以下面着重讲standard的.配置时候,
我们需要声明下面这个bean
@Bean
public MultipartResolver multipartResolver() throws IOException {
return new StandardServletMultipartResolver();
}
这是一个无参数的构造器, 没有设置一些限制上传图片大小的,上传图片的位置的设置,很奇妙的,如果你没有声明这些信息,那么这个解析器是不会正常工作的.
如何配置?
1.如果你配置DispatcherServlet在一个实现了WebApplicationInitializer的类.
那么你可以通过调用setMultipartConfig()来配置.
DispatcherServlet ds = new DispatcherServlet();
Dynamic registration = context.addServlet("appServlet", ds);
registration.addMapping("/");
registration.setMultipartConfig(
new MultipartConfigElement("/tmp/spittr/uploads"));
实际长这样
public class Initializer implements WebApplicationInitializer {
private static final String DISPATCHER_SERVLET_NAME = "dispatcher";
@Override
public void onStartup(ServletContext servletContext)
throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(WebAppConfig.class);
servletContext.addListener(new Log4jConfigListener());
servletContext.addListener(new ContextLoaderListener(ctx));
ctx.setServletContext(servletContext);
Dynamic servlet = servletContext.addServlet(DISPATCHER_SERVLET_NAME,
new DispatcherServlet(ctx));
///-----------------注意下面两行--------------/
servlet.addMapping("/");
servlet.setMultipartConfig(
new MultipartConfigElement("/tmp",2048000,4096000,12345678));
servlet.setLoadOnStartup(1);
}
}
public class WebAppConfig {
@Bean
public UrlBasedViewResolver setupViewResolver() {
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setPrefix("/WEB-INF/pages/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
@Bean
public MultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
}
AbstractDispatcherServletInitializer,的类里面,那么你也可以通过如下配置
@Override
protected void customizeRegistration(Dynamic registration) {
registration.setMultipartConfig(
new MultipartConfigElement("/tmp/spittr/uploads"));
}
当然,如果你需要加多文件大小的限制,可以这么写
@Override
protected void customizeRegistration(Dynamic registration) {
registration.setMultipartConfig(
new MultipartConfigElement("/tmp/spittr/uploads",
2097152, 4194304, 0));
}
--------------------------------------------
CommonsMultipartResolver
--------------------------------------------
配置方式如下,是不是感觉简单一点
@Bean
public MultipartResolver multipartResolver() throws IOException {
CommonsMultipartResolver multipartResolver =
new CommonsMultipartResolver();
multipartResolver.setUploadTempDir(
new FileSystemResource("/tmp/spittr/uploads"));
multipartResolver.setMaxUploadSize(2097152);
multipartResolver.setMaxInMemorySize(0);
return multipartResolver;
}
这样就算配置好了.
-------------------------------------------------------------------------------
port
----------------------------------------------------------------
spring从3.0开始支持,作为除了 MultiPartFile 外的另外一个功能选项.
@RequestMapping(value="/register", method=POST)
public String processRegistration(
@RequestPart("profilePicture") Part profilePicture,
@Valid Spitter spitter,
Errors errors) {
...
}
关于part.他的接口是这样的
package javax.servlet.http;
import java.io.*;
import java.util.*;
public interface Part {
public InputStream getInputStream() throws IOException;
public String getContentType();
public String getName();
public String getSubmittedFileName();
public long getSize();
public void write(String fileName) throws IOException;
public void delete() throws IOException;
public String getHeader(String name);
public Collection<String> getHeaders(String name);
public Collection<String> getHeaderNames();
}
In many cases, the Part methods are named exactly the same as the MultipartFile methods. A few have similar but different names; getSubmittedFileName(), for example, corresponds to getOriginalFilename(). Likewise, write() corresponds to
transferTo(), making it possible to write the uploaded file like this:
profilePicture.write("/data/spittr/" +profilePicture.getOriginalFilename());
It’s worth noting that if you write your controller handler methods to accept file uploads via a Part parameter, then you don’t need to configure the StandardServlet-MultipartResolver bean. StandardServletMultipartResolver is required only when you’re working with MultipartFile.
---------------------
最后,看那么多,来看下最后的controller长什么样子吧?
@Controller
@RequestMapping("/upload")
public class UploadImageController {
@Autowired
private HttpServletRequest request;
@RequestMapping(value = "/img", method = RequestMethod.POST)
public String uploadImage(@RequestParam("file") MultipartFile file) throws IOException {
if (file != null) {
System.out.println("filename=" + file.getName() + " size=" + file.getSize() + " oriName=" + file.getOriginalFilename());
String path = request.getSession().getServletContext().getRealPath("upload/photo");
String time = System.currentTimeMillis() + "";
File nfile = new File(path + "/" + time + ".jpg");
File dir = nfile.getParentFile();
if (!dir.exists()) {
dir.mkdirs();
}///记得生成路径啊。。。。
file.transferTo(nfile);
return "success";
} else {
return "faile";
}
}
}