SpringMVC文件上传下载和拦截器
一、文件上传:文件上传是项目开发中最常用的功能。为了能上传文件,必须将表单的method设置为post,将enctype设置为multipart/form-data。只有在这种情况下,浏览器才会把用户选择的文件二进制数据发送给服务器
1、导入相应的jar包(上传组件):
commons-fileupload.jar
common-io.jar
2、上传的页面文件:
<form action="upload" enctype="multipart/form-data" method="post">
<label>请选择文件:</label>
<input type="file" name="file">
<br><br>
<input type="submit" value="上传">
</form>
3、上传控制器:
@Controller
public class FileUploadController {
@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file) throws Exception{
//如果文件不为空
if(!file.isEmpty()) {
String path = "E:\\upload";//上传路径
String filename = file.getOriginalFilename();//获取上传文件的原名
File filepath = new File(path,filename);
//判断路径是否存在,如果不存在就创建一个
if(!filepath.getParentFile().exists()) {
filepath.getParentFile().mkdirs();
}
//将上传文件保存到一个目标文件中
file.transferTo(new File(path+File.separator+filename));
System.out.println("上传路径为:"+(path+File.separator+filename));
return "success";
}else {
return "error";
}
}
}
4、配置SpringMVC
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize">
<value>10345789</value>
</property>
<property name="defaultEncoding">
<value>utf-8</value>
</property>
</bean>
5、MultipartFile对象:SpringMVC回将上传文件绑定到MultipartFile对象。MultipartFile对象提供了获取上传文件内容、文件名等方法。通过transferTo()方法可以将文件上传。MultipartFile对象中的常用方法如下:
(1)byte[] getBytes():获取文件数据
(2)String getContentType():获取文件MIME类型,如image/jpeg等
(3)InputStream getInputStream():获取文件流
(4)String getName():获取表单中文件组件的名称
(5)String getOriginalFilename():获取上传文件的原名
(6)long getSize():获取文件的字节大小,单位为byte
(7)boolean isEmpty():是否有上传文件
(8)void transferTo(File dest):将上传文件保存到一个目标文件中
6、实例:使用对象接收上传文件
(1)上传页面:
<form action="objectUploade" enctype="multipart/form-data" method="post"
<label>用户名:</label>
<input type="text" name="username">
<br><br>
<label>请选择头像:</label>
<input type="file" name="image">
<br><br>
<input type="submit" value="上传">
</form>
(2)接收上传文件的类:
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String username;
private MultipartFile image;
}
(3)上传控制器:
@PostMapping("/objectUploade")
public String register(HttpServletRequest request,
@ModelAttribute User user,
Model model) throws Exception {
System.out.println(user.getUsername());
if(!user.getImage().isEmpty()) {
String path = request.getServletContext().getRealPath("/images");
String filename = user.getImage().getOriginalFilename();
File filepath = new File(path,filename);
if(!filepath.getParentFile().exists()) {
filepath.getParentFile().mkdirs();
}
user.getImage().transferTo(new File(path+File.separator+filename));
model.addAttribute("filename",user.getImage().getOriginalFilename());
System.out.println("上传文件路径:"+(path+File.separator+filename));
return "userInfo";
}else {
return "error";
}
}
(4)下载页面(userInfo.jsp)
<a href="javascript:window.location.href='download?filename='+encodeURIComponent('${requestScope.filename }')">
${requestScope.filename }
</a>
注:因为传递的文件名有可能是中文字符,所以超链接中使用了encodeURIComponent函数进行编码
二、文件下载:SpringMVC提供了ResponseEntity类型,使用它可以很方便的定义返回的BodyBuilder、HttpHeaders和HttpStatus
BodyBuilder对象用来构建返回的Body;
HttpHeaders代码Http协议中的头信息
HttpStatus代表Http协议中的状态
接上例,定义下载的控制器:
@GetMapping("/download")
public ResponseEntity<byte[]> download(HttpServletRequest request,
@RequestParam("filename") String filename,
@RequestHeader("User-Agent") String userAgent) throws Exception{
String path =request.getServletContext().getRealPath("/images");
File file = new File(path+File.separator+filename);
BodyBuilder builder = ResponseEntity.ok();//ok表示http协议中的状态200
builder.contentLength(file.length());//内容长度
//application_octet_stream二进制流数据(最常见的文件下载),MediaType表示互联网媒体类型,即MIME类型
builder.contentType(MediaType.APPLICATION_OCTET_STREAM);
//使用URLEncoder.encode对文件名进行解码
filename = URLEncoder.encode(filename,"utf-8");
//设置实际的响应文件名,告诉浏览器文件要以附件的形式打开
//不同的浏览器,处理方式不同,要根据浏览器版本进行区别判断
if(userAgent.indexOf("MSIE")>0) {
//如果是IE,只需要用utf-8字符集进行URL编码即可
builder.header("Content-Disposition","attachment;filename="+filename);
}else {
//如果是fireFox、Chrome等浏览器,则需要说明编码的字符集
//注意在filename后面有个*号,在utf-8后面有两个单引号
builder.header("Content-Disposition", "attachment;filename*=utf-8''"+filename);
}
return builder.body(FileUtils.readFileToByteArray(file));
}
三、拦截器:Inteceptor拦截器是SpringMVC中非常重要的功能,它的主要作用是拦截用户的请求并进行相应的处理。比如通过拦截器来进行用户权限验证、或判断用户是否已经登录等。
1、SpringMVC拦截器是可插拔的。如果需要只需在配置文件中配置即可,如果不需要在配置文件取消配置即可
2、SpringMVC拦截器拦截请求是通过实现HandlerInterceptor接口来完成的,在该接口中定义了三个方法来对用户的请求进行拦截
(1)boolean preHandle(request,response,object):该方法在请求处理之前进行调用
(2)void postHandle(request,response,handler,modelAndView)在Controller方法调用之后执行
(3)void afterHandle(request,response,handler,modelAndView):进行资源清理
3、示例:实现登录验证
(1)请求控制器:模拟在数据库中查找用户,判断用户登录
@PostMapping(value="/login")
public ModelAndView login(String loginname,String password,
ModelAndView mv,HttpSession session) {
if(loginname!=null&&loginname.equals("jaskon")&&password!=null&&password.equals("12345")) {
User user = new User();
user.setLoginname(loginname);
user.setPassword(password);
user.setUsername("管理员");
session.setAttribute("user",user);
mv.setViewName("redirect:main");
}else {
mv.addObject("message","登录名或密码错误,请重新输入!");
mv.setViewName("loginForm");
}
return mv;
}
(2)主页面控制器(main)
@Controller
public class BookController {
@RequestMapping(value="/main")
public String Main(Model model) {
model.addAttribute("Info","欢迎管理员");
return "main";
}
}
(3)自定义拦截器:MyInterceptor
public class MyInterceptor implements HandlerInterceptor {
private static final String[] IGNORE_URI = {"/loginForm","/login"};
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("MyInterceptor preHandle...");
boolean flag = false;
String servletPath = request.getServletPath();
for(String s : IGNORE_URI) {
if(servletPath.contains(s)) {
flag = true;
break;
}
}
if(!flag) {
User user= (User)request.getSession().getAttribute("user");
if(user == null) {
System.out.println("MyInterceptor拦截请求");
request.setAttribute("message","请先登录");
request.getRequestDispatcher("/WEB-INF/views/loginForm.jsp").forward(request, response);
}else {
System.out.println("MyInterceptor放行请求");
flag = true;
}
}
return flag;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor postHandle...");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("MyInterceptor afterCompletion...");
}
}
(4)配置拦截器:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/*"/>
<bean class="com.cn.filter.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
(5)页面(main.jsp)
<h2>${sessionScope.user.username }</h2>
<h2>${Info }</h2>