SpringMVC教程3 一、文件上传 二、文件下载 三、静态资源处理 四、数据校验

SpringMVC教程2

1.引入相关jar包

SpringMVC教程3
一、文件上传
二、文件下载
三、静态资源处理
四、数据校验
maven坐标

 <!-- fileUpload 解析上传的文件用到的jar -->
<dependency>
	<groupId>commons-fileupload</groupId>
	<artifactId>commons-fileupload</artifactId>
	<version>1.3.1</version>
</dependency>
<dependency>
	<groupId>commons-io</groupId>
	<artifactId>commons-io</artifactId>
	<version>2.4</version>
</dependency>

2.页面表单信息

表单提交方式必须是post方式提交,enctype必须是multipart/form-data

<form action="upload" method="post" enctype="multipart/form-data">
	<table>
		<tr>
			<td>用户名</td>
			<td><input type="text" name="username"></td>
		</tr>
		<tr>
			<td>用户密码</td>
			<td><input type="password" name="password"></td>
		</tr>
		
		<tr>
			<td>用户图像</td>
			<td><input type="file" name="userface"></td>
		</tr>
		<tr>
			<td><input type="submit" value="注册"></td>
		</tr>
	</table>
</form>

SpringMVC教程3
一、文件上传
二、文件下载
三、静态资源处理
四、数据校验

3.Controller中接收数据

/**
 * 文件上传案例
 * @author dpb【波波烤鸭】
 *
 */
@Controller
public class UserController {

	/**
	 * 上传的数据通过MultipartFile对象接收
	 * @param username
	 * @param password
	 * @param userface
	 * @throws Exception
	 * @throws IOException
	 */
	@RequestMapping("/upload")
	@ResponseBody
	public void upload(String username,String password
			,MultipartFile userface) throws Exception, IOException{
		System.out.println(username+","+password);
		userface.transferTo(new File("c:/tools/","123.png"));
	}
	
}

4.配置文件中修改

	<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
		 >
		<!-- 设置上传文件信息参数 -->
		<!-- 设置文件上传的最大尺寸 -->
		<property name="maxUploadSize">
			<value>5242880</value>
		</property>
	</bean>

注意:
CommonsMultipartResolver这个Bean的id必须为multipartResolver,
原因:CommonsMultipartResolver Bean是在DispatcherServlet中加载的,而DispatcherServlet是通过名字来查找这个Bean的。而其他的,则是按照类型查找。

二、文件下载

1.方式一:基于ResponseEntity实现

@RequestMapping("/testHttpMessageDown")
public ResponseEntity<byte[]> download(HttpServletRequest request) throws IOException {
    // 需要下载的文件
	File file = new File("E://123.jpg");
    byte[] body = null;
    InputStream is = new FileInputStream(file);
    body = new byte[is.available()];
    is.read(body);
    HttpHeaders headers = new HttpHeaders();
    headers.add("Content-Disposition", "attchement;filename=" + file.getName());
    HttpStatus statusCode = HttpStatus.OK;
    ResponseEntity<byte[]> entity = new ResponseEntity<byte[]>(body, headers, statusCode);
    return entity;
}

方式二:通用下载实现

@RequestMapping("/exportExcel")
public void exportExcel(HttpServletRequest request,HttpServletResponse response) throws IOException{
	File file = new File("d://owned.xls");
	//设置响应头和客户端保存文件名
    response.setCharacterEncoding("utf-8");
    response.setContentType("multipart/form-data");
    response.setHeader("Content-Disposition", "attachment;fileName=" + file.getName());
    try {
        //打开本地文件流
        InputStream inputStream = new FileInputStream(file);
        //激活下载操作
        OutputStream os = response.getOutputStream();
        //循环写入输出流
        byte[] b = new byte[2048];
        int length;
        while ((length = inputStream.read(b)) > 0) {
            os.write(b, 0, length);
        }
        // 这里主要关闭。
        os.close();
        inputStream.close();
    } catch (Exception e){
        
        throw e;
    }
}

三、静态资源处理

在SpringMVC中,默认情况下,所有的静态资源都会被拦截(js,css。html,图片、视频、音频),对于静态资源,需要手动配置静态资源过滤。
解决这个问题的方式有两种:

3.1 在web.xml中配置default servlet

 <!-- 防止资源文件被spring MVC拦截 -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.jpg</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.js</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.css</url-pattern>
    </servlet-mapping>

3.2在配置文件中通过标签设置

 <!--  防止资源文件被spring MVC拦截--> 
     <mvc:resources mapping="/images/**" location="/images/" cache-period="31556926"/>  
     <mvc:resources mapping="/js/**" location="/js/" cache-period="31556926"/>  
     <mvc:resources mapping="/css/**" location="/css/" cache-period="31556926"/> 

例如,浏览器发送http://localhost:8080/static/img/01.png请求,该请求符合/static/img/,此时,代表01.png,那么springmvc会将01.png补充到对应的location后面,进而查找到文件。
这里需要注意:
* 表示一层路径
** 表示多层路径映射

四、数据校验

1. 为什么需要服务端校验?

最早的校验,就是服务端校验。早期的网站,用户输入一个邮箱地址,校验邮箱地址需要将地址发送到服务端,服务端进行校验,校验成功后,给前端一个响应。有了JavaScript,校验工作可以放在前端去执行。那么为什么还需要服务端校验呢? 因为前端传来的数据不可信。前端很容易获取都后端的数据接口,如果有人绕过页面,就会出现非法数据,所以服务端也要数据校验,总的来说:
1.前端校验要做,目的是为了提高用户体验
2.后端校验也要做,目的是为了数据安全

2.普通校验

Springmvc本身没有校验功能,它使用hibernate的校验框架,hibernate的校验框架和orm没有关系

2.1创建项目

2.2引入相关jar包

SpringMVC教程3
一、文件上传
二、文件下载
三、静态资源处理
四、数据校验
如果是maven项目对应的maven坐标是:

<dependency>
  	<groupId>org.hibernate</groupId>
  	<artifactId>hibernate-validator</artifactId>
  	<version>5.3.0.Alpha1</version>
</dependency>

2.3创建properties文件

属性文件用来声明错误提示信息

SpringMVC教程3
一、文件上传
二、文件下载
三、静态资源处理
四、数据校验
如果属性文件乱码的解决办法:
在Eclipse主界面下,打开Window->Perferences->General->ContentTypes:
SpringMVC教程3
一、文件上传
二、文件下载
三、静态资源处理
四、数据校验

2.4在springmvc的配置文件中配置如下

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

	<mvc:annotation-driven validator="validator"></mvc:annotation-driven>
	<context:component-scan base-package="com.dpb.controller"></context:component-scan>
	
	<!--添加对JSR-303验证框架的支持  -->
    <bean >
        <property name="providerClass"  value="org.hibernate.validator.HibernateValidator"/>
        <!--不设置则默认为classpath下的 ValidationMessages.properties -->
        <property name="validationMessageSource" ref="validatemessageSource"/>
    </bean>
   
    <bean >  
        <property name="basename" value="classpath:ValidateMessages"/>  
        <property name="fileEncodings" value="utf-8"/>  
        <property name="cacheSeconds" value="120"/>  
    </bean>	
</beans>

SpringMVC教程3
一、文件上传
二、文件下载
三、静态资源处理
四、数据校验

2.5Bean对象中配置校验规则

	@NotBlank(message="{user.username.empty}")
	@Size(max=6,min=3,message="{user.username.size}")
	private String username;
	@Size(max=6,min=3,message="{user.password.size}")
	private String password;

校验规则

注解 说明
@Null 被注解的元素必须为 null
@NotNull 被注解的元素必须不为 null
@AssertTrue 被注解的元素必须为 true
@AssertFalse 被注解的元素必须为 false
@Min(value) 被注解的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注解的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注解的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注解的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=) 被注解的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注解的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注解的元素必须是一个过去的日期
@Future 被注解的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注解的元素必须符合指定的正则表达式
@NotBlank(message =) 验证字符串非null,且长度必须大于0
@Email 被注解的元素必须是电子邮箱地址
@Length(min=,max=) 被注解的字符串的大小必须在指定的范围内
@NotEmpty 被注解的字符串的必须非空
@Range(min=,max=,message=) 被注解的元素必须在合适的范围内

2.6Controller中校验

/**
 * 数据校验案例
 * 
 * @author dpb【波波烤鸭】
 *
 */
@Controller
public class UserController {

	/**
	 * @Validated book 表示book接收的数据需要根据指定的规则进行校验
	 * BindingResult 封装验证结果,必须紧跟在验证变量之后,
	 * 				如果有多个信息需要验证那么就有多个BindingResult参数
	 * 
	 */
	@RequestMapping("/add")
	public String add(@Validated Book book,BindingResult br,Model m){
		System.out.println(book);
		// 获取验证信息
		List<ObjectError> allErrors = br.getAllErrors();
		for (ObjectError objectError : allErrors) {
			System.out.println(objectError.getDefaultMessage());
		}
		// 将验证信息保存到作用域中
		m.addAttribute("errors", allErrors);
		return "/index.jsp";
	}
}

2.7jsp页面中获取错误信息

<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	hello world<br/>
	<c:if test="${errors ne null }">
		<c:forEach items="${errors}" var="e">
			${e.defaultMessage}<br>
		</c:forEach>
	</c:if>
</body>
</html>

2.8测试

SpringMVC教程3
一、文件上传
二、文件下载
三、静态资源处理
四、数据校验SpringMVC教程3
一、文件上传
二、文件下载
三、静态资源处理
四、数据校验SpringMVC教程3
一、文件上传
二、文件下载
三、静态资源处理
四、数据校验

3.分组校验

为什么需要分组校验?
因为一个对象有多个属性,而不同的controller校验的需求是不一样的,必须c1只需要校验对象的账号是否为空就可以了,而c2不光要校验账号为空还需要校验手机号必须不能为空,这时分组校验就能解决这个问题了。实现步骤如下:

3.1定义分组

SpringMVC教程3
一、文件上传
二、文件下载
三、静态资源处理
四、数据校验

package com.dpb.group;
/**
 * 定义的两个接口什么都没定义为标志接口
 * @author dpb【波波烤鸭】
 *
 */
public interface GroupInferface1 {

}

3.2使用分组

	@NotBlank(message="{user.username.empty}"
			,groups={GroupInferface2.class})
	@Size(max=6,min=3,message="{user.username.size}"
			,groups={GroupInferface1.class})
	private String username;
	
	@Size(max=6,min=3,message="{user.password.size}"
			,groups={GroupInferface1.class})
	private String password;

3.3controller中使用

	/**
	 * @Validated book 表示book接收的数据需要根据指定的规则进行校验
	 * BindingResult 封装验证结果,必须紧跟在验证变量之后,
	 * 				如果有多个信息需要验证那么就有多个BindingResult参数
	 * 
	 */
	@RequestMapping("/add1")
	public String add1(@Validated(value=GroupInferface1.class) Book book,BindingResult br,Model m){
		System.out.println(book);
		// 获取验证信息
		List<ObjectError> allErrors = br.getAllErrors();
		for (ObjectError objectError : allErrors) {
			System.out.println(objectError.getDefaultMessage());
		}
		// 将验证信息保存到作用域中
		m.addAttribute("errors", allErrors);
		return "/index.jsp";
	}

SpringMVC教程3
一、文件上传
二、文件下载
三、静态资源处理
四、数据校验

3.4测试

第一种情况
SpringMVC教程3
一、文件上传
二、文件下载
三、静态资源处理
四、数据校验SpringMVC教程3
一、文件上传
二、文件下载
三、静态资源处理
四、数据校验第二种情况:
SpringMVC教程3
一、文件上传
二、文件下载
三、静态资源处理
四、数据校验SpringMVC教程3
一、文件上传
二、文件下载
三、静态资源处理
四、数据校验上一篇:SpringMVC教程2
下一篇:SpringMVC教程4