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

概述:

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

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
	 */
	@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")


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值