作者:whisper
链接:http://proprogrammar.com:443/article/373
声明:请尊重原作者的劳动,如需转载请注明出处
拦截器和文件上传算是springmvc中比较高级一点的内容了吧,让我们一起看一下。
下面先说说拦截器。拦截器和过滤器有点像,都可以在请求被处理之前和请求被处理之到做一些额外的操作。
1. 实现HandlerInterceptor接口。
package com.sxt.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class MyInterceptor implements HandlerInterceptor {
/**
* 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等
*
* 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion()
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("最后执行!!!一般用于释放资源!!");
}
/**
* 在业务处理器处理请求执行完成后,生成视图之前执行的动作
* 可在modelAndView中加入数据,比如当前时间
*/
@Override
public void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("Action执行之后,生成视图之前执行!!");
}
/**
* 在业务处理器处理请求之前被调用
* 如果返回false
* 从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链
* 如果返回true
* 执行下一个拦截器,直到所有的拦截器都执行完毕
* 再执行被拦截的Controller
* 然后进入拦截器链,
* 从最后一个拦截器往回执行所有的postHandle()
* 接着再从最后一个拦截器往回执行所有的afterCompletion()
*/
@Override
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
System.out.println("action之前执行!!!");
return true; //继续执行action
}
}
要实现三个方法,比较繁锁,下面看一下第二种。
2. 继承HandlerInterceptorAdapter类。
package com.sxt.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class MyInterceptor2 extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterceptor2.preHandle()");
return true; //继续执行action
}
}
这是个Adapter类,Adapter类在Swing中应该有所接触,只要覆写自己需要用到的方法的就可以了。
配置文件
<mvc:interceptors>
<bean class="com.sxt.interceptor.MyInterceptor"></bean> <!-- 拦截所有springmvc的url! -->
<mvc:interceptor>
<mvc:mapping path="/user.do" /><!-- 拦截指定路径 -->
<!--<mvc:mapping path="/test/*" />-->
<bean class="com.sxt.interceptor.MyInterceptor2"></bean>
</mvc:interceptor>
</mvc:interceptors>
关于拦截器的更多知识,可以看一下下面的文章:
再说说文件上传。分两部分:spring3的文件上传和spring4的文件上传。
1. spring3的文件上传。
页面
<%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>测试springmvc中上传的实现</title>
</head>
<body>
<form action="upload.do" method="post" enctype="multipart/form-data">
<input type="text" name="name" />
<input type="file" name="file" />
<input type="submit" value="单文件上传"/>
</form>
</body>
</html>
控制器
package com.sxt.action;
import java.io.File;
import java.util.Date;
import javax.servlet.ServletContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
@Controller
public class FileUploadController implements ServletContextAware {
// 用来获取上传路径
private ServletContext servletContext;
@Override
public void setServletContext(ServletContext context) {
this.servletContext = context;
}
@RequestMapping(value="/upload.do", method = RequestMethod.POST)
public String handleUploadData(String name,@RequestParam("file") CommonsMultipartFile file){
if (file != null && !file.isEmpty()) {
String path = this.servletContext.getRealPath("/tmp/"); //获取本地存储路径
System.out.println(path);
String fileName = file.getOriginalFilename();
String fileType = fileName.substring(fileName.lastIndexOf("."));
System.out.println(fileType);
File file2 = new File(path,new Date().getTime() + (int)(Math.random() * 1000000) + fileType); //新建一个文件
try {
file.getFileItem().write(file2);
} catch (Exception e) {
e.printStackTrace();
}
return "redirect:upload_ok.jsp";
}else{
return "redirect:upload_error.jsp";
}
}
}
实现了ServletContextAware,用来获取应用上下文,利用它获取上传的文件目录。注意一下方法参数,@RequestParam("file") CommonsMultipartFile file,用来获取保存上传的文件,然后getOriginalFilename获取文件的名字,getFileItem获取上传的文件的相关信息,FileItem的write方法用来写上传文件的内容到另一个文件中。
配置文件
<!-- 处理文件上传 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8" /> <!-- 默认编码 (ISO-8859-1) -->
<property name="maxInMemorySize" value="10240" /> <!-- 最大内存大小 (10240)-->
<property name="uploadTempDir" value="/upload/" /> <!-- 上传后的目录名 (WebUtils#TEMP_DIR_CONTEXT_ATTRIBUTE) -->
<property name="maxUploadSize" value="-1" /> <!-- 最大文件大小,-1为无限止(-1) -->
</bean>
2. spring4的文件上传。
多文件上传页面(单文件上传页面类似spring3文件上传,此处省略)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="upload2.do" method="post" enctype="multipart/form-data">
<table>
<tr>
<th colspan="2">上传文件</th>
</tr>
<tr>
<td>文件一</td>
<td>
<input type="file" name="file"/>
</td>
</tr>
<tr>
<td>文件二</td>
<td>
<input type="file" name="file"/>
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="上传文件"/>
</td>
</tr>
</table>
</form>
</body>
</html>
控制器
package com.java1234.controller;
import java.io.File;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
@Controller
public class FileUploadController {
/**
* 单文件上传
* @param file1
* @param request
* @return
* @throws Exception
*/
@RequestMapping("/upload")
public String uploadFile(@RequestParam("file1") MultipartFile file1,HttpServletRequest request)throws Exception{
String filePath=request.getServletContext().getRealPath("/");
System.out.println(filePath);
file1.transferTo(new File(filePath+"upload/"+file1.getOriginalFilename()));
return "redirect:success.html";
}
/**
* 多文件上传
* @param files
* @param request
* @return
* @throws Exception
*/
@RequestMapping("/upload2")
public String uploadFiles(@RequestParam("file") MultipartFile[] files,HttpServletRequest request)throws Exception{
String filePath=request.getServletContext().getRealPath("/");
System.out.println(filePath);
for(MultipartFile file:files){
file.transferTo(new File(filePath+"upload/"+file.getOriginalFilename()));
}
return "redirect:success.html";
}
}
这里单文件上传文件信息保存在MultipartFile对象中,通过对象的transferTo方法保存到新的文件中。
多文件上传参数@RequestParam("file") MultipartFile[] files,是一个MultipartFile的数组,处理与单文件上传类似,通过transferTo方法保存到新的文件中。
配置文件
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
<property name="maxUploadSize" value="10000000"/>
</bean>
关于文件上传下载的更多内容,可以看下面的文章:
关于springmvc的内容就这么多,照着代码弄的,代码很浅显,更多内容还要靠自己慢慢探索。
一个小疑问:处理器到底是什么?处理器其实就是Controller,是我们编写控制逻辑的地方,那么处理器映射器的作用就是找到某个Controller,处理器适配器的作用就是执行Controller中相应的方法完成相应的逻辑。
亲爱的读者:有时间可以点赞评论一下
全部评论