第7章 Spring MVC的高级技术--图片上传基于StandardServletMultipartResolver

来源:互联网 发布:手机用usb使用电脑网络 编辑:程序博客网 时间:2024/06/05 02:28

概述:

有时候网站需要上传头像,这时候用表单如何传递呢?

1、配置multipart解析器

有两种:

  1. CommonsMultipartResolver: 使用Jakarta Commons FileUpload解析multipart请求
  2. StandardServletMultipartResolver:依赖于Servlet3.0对multipart的请求的支持

package com.jack.config;import java.io.IOException;import org.springframework.context.MessageSource;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.ComponentScan.Filter;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.FilterType;import org.springframework.context.support.ReloadableResourceBundleMessageSource;import org.springframework.web.multipart.MultipartResolver;import org.springframework.web.multipart.support.StandardServletMultipartResolver;import org.springframework.web.servlet.ViewResolver;import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.thymeleaf.TemplateEngine;import org.thymeleaf.spring4.SpringTemplateEngine;import org.thymeleaf.spring4.view.ThymeleafViewResolver;import org.thymeleaf.templateresolver.ServletContextTemplateResolver;import org.thymeleaf.templateresolver.TemplateResolver;@Configuration@ComponentScan(basePackages={"com.jack"},excludeFilters={@Filter(type=FilterType.ANNOTATION, value=EnableWebMvc.class)})public class RootConfig {/** * 实现不重启加载资源 * @return */@Beanpublic MessageSource messageSource(){ReloadableResourceBundleMessageSource messageSource =new ReloadableResourceBundleMessageSource();messageSource.setBasename("classpath:messages");messageSource.setDefaultEncoding("UTF-8");messageSource.setCacheSeconds(10);return messageSource;}@Beanpublic TemplateEngine templateEngine(TemplateResolver templateResolver){SpringTemplateEngine templateEngine = new SpringTemplateEngine();templateEngine.setTemplateResolver(templateResolver);return templateEngine;}@Beanpublic ViewResolver viewResolver(SpringTemplateEngine templateEngine) {ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();viewResolver.setTemplateEngine(templateEngine);viewResolver.setCharacterEncoding("UTF-8");return viewResolver;}@Beanpublic TemplateResolver templateResolver(){TemplateResolver templateResolver = new ServletContextTemplateResolver();templateResolver.setPrefix("/WEB-INF/template/");templateResolver.setSuffix(".html");templateResolver.setTemplateMode("HTML5");templateResolver.setCharacterEncoding("UTF-8");return templateResolver;}@Beanpublic MultipartResolver multipartResolver()throws IOException{return new StandardServletMultipartResolver();}}


配置解析器:

@Bean
public MultipartResolver multipartResolver()throws IOException{
return new StandardServletMultipartResolver();
}

如果需要设置上传文件大小限制等相关参数,可以通过 重写customizeRegistration() 方法

package com.jack.config;import javax.servlet.Filter;import javax.servlet.MultipartConfigElement;import javax.servlet.ServletRegistration.Dynamic;import org.springframework.web.filter.CharacterEncodingFilter;import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;/** * 在Servlet3.0环境中,容器会在类路径中查询实现 * javax.servlet.ServletContainerInitializer 接口的类,如果发现的话,就会用它来配置Servlet容器 * @author Administrator * */public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{@Overrideprotected Class<?>[] getRootConfigClasses() {return new Class<?>[]{RootConfig.class};}@Overrideprotected Class<?>[] getServletConfigClasses() {return  new Class<?>[]{WebConfig.class};}/*  * 将DispatchServlet映射到"/" * (non-Javadoc) * @see org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer#getRootConfigClasses() */@Overrideprotected String[] getServletMappings() {return new String[] {"/"};}@Overrideprotected Filter[] getServletFilters() {CharacterEncodingFilter c = new CharacterEncodingFilter();c.setEncoding("UTF-8");c.setForceRequestEncoding(true);return new Filter[] {c};  }/**  * 配置上传的信息 *  (non-Javadoc) * @see org.springframework.web.servlet.support.AbstractDispatcherServletInitializer#customizeRegistration(javax.servlet.ServletRegistration.Dynamic) */@Overrideprotected void customizeRegistration(Dynamic registration) {registration.setMultipartConfig(new MultipartConfigElement("D:/",2097152,419304,0));}}

/** 
* 配置上传的信息
*  (non-Javadoc)
* @see org.springframework.web.servlet.support.AbstractDispatcherServletInitializer#customizeRegistration(javax.servlet.ServletRegistration.Dynamic)
*/
@Override
protected void customizeRegistration(Dynamic registration) {
registration.setMultipartConfig(new MultipartConfigElement("D:/",2097152,419304,0));
}

总结:第一个参数是基础位置,在D盘根目录下,限制文件大小为2M,总共请求的大小不能大于4M


如果是xml配置:

<servlet><servlet-name>SpringMVC</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc.xml</param-value></init-param><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup><async-supported>true</async-supported><multipart-config><location>D:/</location><max-file-size>2097152</max-file-size><max-request-size>419304</max-request-size></multipart-config></servlet>


2、表单增加上传input标签

<html xmlns="http://www.w3.org/1999/xhtml"xmlns:th="http://www.thymeleaf.org"> <!-- 声明Thymeleaf命名空间 --><head><title>Spittr</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  <link rel="stylesheet" type="text/css" th:href="@{/resource/style.css}"></link></head><body><h1>注册</h1><form method="POST" th:object="${spitter}" enctype="multipart/form-data"  ><div class="errors" th:if="${#fields.hasErrors('*')}"><ul><li th:each="err : ${#fields.errors('*')}"th:text="${err}">Input is incorrect</li></ul></div><label th:class="${#fields.hasErrors('firstName')} ? 'error'">First Name</label> :<input type="text" th:field="*{firstName}"th:class="${#fields.hasErrors('firstName')} ? 'error'" /><br/><label th:class="${#fields.hasErrors('firstName')} ? 'error'">Last Name</label> :<input type="text" th:field="*{lastName}"th:class="${#fields.hasErrors('lastName')} ? 'error'"/><br/><label th:class="${#fields.hasErrors('email')} ? 'error'">email</label> :<input type="text" th:field="*{email}"th:class="${#fields.hasErrors('email')} ? 'error'"/><br/><label th:class="${#fields.hasErrors('username')} ? 'error'">Username</label> :<input type="text" th:field="*{username}"th:class="${#fields.hasErrors('username')} ? 'error'"/><br/><label th:class="${#fields.hasErrors('password')} ? 'error'">Last Name</label> :<input type="text" th:field="*{password}"th:class="${#fields.hasErrors('password')} ? 'error'"/><br/><label>Profile Picture</label> :<input type="file" name="profilePicture" accept="image/jpeg,image/png,image/gif"/><br/><input type="submit" value="Reqister"/></form></body></html>

<label>Profile Picture</label> :
<input type="file" name="profilePicture" accept="image/jpeg,image/png,image/gif"/><br/>


accept:表示接受文件类型是图片,且图片格式为jpeg、png、gif


修改一下Controller类:

@RequestMapping(value="/register", method=RequestMethod.POST)
public String processRegistration( @RequestPart("profilePicture")MultipartFile profilePicture, @Valid Spitter spitter,
Errors errors,HttpServletRequest http) throws Exception{
profilePicture.transferTo(new File("/data/spittr/" + profilePicture.getOriginalFilename()));
if(errors.hasErrors()) {
return "registerForm";
}
spitterRepository.save(spitter);

return "redirect:/spitter/" + spitter.getUsername();
}


总结;

1、MultipartFile提供一个处理文件的接口类,有很多实用的方法

2、transferTo就是将上传文件写到D:/data/spittr/ (D盘就是,初始设置的位置)


3、启动tomcat测试:

先创建好文件夹(这可以在代码写好)



上传表单页:


点击提交效果:



当然如果文件存在,就会报

java.io.IOException: java.io.FileNotFoundException: D:\data\spittr (拒绝访问。)

所以在进行判断,如果存在,是替换还是保留取决于你


总结:要实现上传功能,1、配置解析器、2、修改前端标签(且提交方式为:enctype="multipart/form-data")


原创粉丝点击