关于spring文件上传的配置

一般我们写上传文件,controller直接可能是就是这么写的

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();
    } 


}





2.如果你配置  DispatcherServlet 在一个拓展 AbstractAnnotationConfigDispatcherServletInitializer 或者

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";
        }
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值