概述:
有时候网站需要上传头像,这时候用表单如何传递呢?
1、配置multipart解析器
有两种:
- CommonsMultipartResolver: 使用Jakarta Commons FileUpload解析multipart请求
- 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
*/
@Bean
public MessageSource messageSource(){
ReloadableResourceBundleMessageSource messageSource =
new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:messages");
messageSource.setDefaultEncoding("UTF-8");
messageSource.setCacheSeconds(10);
return messageSource;
}
@Bean
public TemplateEngine templateEngine(TemplateResolver templateResolver){
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
return templateEngine;
}
@Bean
public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine);
viewResolver.setCharacterEncoding("UTF-8");
return viewResolver;
}
@Bean
public TemplateResolver templateResolver(){
TemplateResolver templateResolver =
new ServletContextTemplateResolver();
templateResolver.setPrefix("/WEB-INF/template/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
templateResolver.setCharacterEncoding("UTF-8");
return templateResolver;
}
@Bean
public 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{
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{RootConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{WebConfig.class};
}
/*
* 将DispatchServlet映射到"/"
* (non-Javadoc)
* @see org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer#getRootConfigClasses()
*/
@Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
@Override
protected 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)
*/
@Override
protected 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")