03-SpringMVC其它操作
一、SpringMVC文件上传
1.1、文件上传回顾
(1)、前提
- form 表单的 enctype 取值必须是: multipart/form-data(默认值是:application/x-www-form-urlencoded)
enctype:是表单请求正文的类型 - method 属性取值必须是 Post
- 提供一个文件选择域
<input type="file" />
(2)、原理
当 form 表单的 enctype 取值不是默认值后, request.getParameter()将失效。enctype=”application/x-www-form-urlencoded”时, form 表单的正文内容是:key=value&key=value&key=value
当 form 表单的 enctype 取值为 Mutilpart/form-data 时,每一部分都是 MIME 类型描述的正文,请求正文内容就变成:
-----------------------------7de1a433602ac //分界符
Content-Disposition: form-data; name="userName" //协议头
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa //协议的正文
-----------------------------7de1a433602ac
Content-Disposition: form-data; name="file";
filename="C:\Users\zhy\Desktop\fileupload_demofile\b.txt"
Content-Type: text/plain 协议的类型( MIME 类型)
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
(3)、借助第三方上传
使用 Commons-fileupload 组件实现文件上传,需要导入该组件相应的支撑 jar 包: Commons-fileupload 和commons-io。 commons-io 不属于文件上传组件的开发 jar 文件,但Commons-fileupload 组件从 1.1 版本开始需要 commons-io 包的支持 。
1.2、SpringMVC传统文件上传
传统方式的文件上传, 指的是我们上传的文件和访问的应用存在于同一台服务器上。并且上传完成之后,浏览器可能跳转。
(1)、表单
<form action="/fileUpload" method="post" enctype="multipart/form-data">
名称: <input type="text" name="picname"/><br/>
图片: <input type="file" name="uploadFile"/><br/>
<input type="submit" value="上传"/>
</form>
(2)、文件上传控制器
@Controller("fileUploadController")
public class FileUploadController {
/**
* 文件上传
*/
@RequestMapping("/fileUpload")
public String testResponseJson(String picname,MultipartFile
uploadFile,HttpServletRequest request) throws Exception{
//定义文件名
String fileName = "";
//1.获取原始文件名
String uploadFileName = uploadFile.getOriginalFilename();
//2.截取文件扩展名
String extendName = uploadFileName.substring(uploadFileName.lastIndexOf(".")+1,uploadFileName.length());
//3.把文件加上随机数,防止文件重复
String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
//4.判断是否输入了文件名
if(!StringUtils.isEmpty(picname)) {
fileName = uuid+"_"+picname+"."+extendName;
}else {
fileName = uuid+"_"+uploadFileName;
}
System.out.println(fileName);
//2.获取文件路径
ServletContext context = request.getServletContext();
String basePath = context.getRealPath("/uploads");
//3.解决同一文件夹中文件过多问题
String datePath = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
//4.判断路径是否存在
File file = new File(basePath+"/"+datePath);
if(!file.exists()) {
file.mkdirs();
}
//5.使用 MulitpartFile 接口中方法,把上传的文件写到指定位置
uploadFile.transferTo(new File(file,fileName));
return "success";
}
}
(3)、配置文件解析器
<!-- 配置文件上传解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为 5MB -->
<property name="maxUploadSize">
<value>5242880</value>
</property>
</bean>
<!--注意:文件上传的解析器 id 是固定的,不能起别的名称,否则无法实现请求参数的绑定。(不光是文件,其他
字段也将无法绑定)-->
1.3、SpringMVC跨服文件上传
二、SpringMVC拦截器
2.1、作用
Spring MVC 的处理器拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。用户可以自己定义一些拦截器来实现特定的功能。
过滤器个拦截器的区别:
- 过滤器是 servlet 规范中的一部分, 任何 java web 工程都可以使用。
- 拦截器是 SpringMVC 框架自己的,只有使用了 SpringMVC 框架的工程才能用。
- 过滤器在 url-pattern 中配置了/*之后,可以对所有要访问的资源拦截。
- 拦截器它是只会拦截访问的控制器方法,如果访问的是 jsp, html,css,image 或者 js 是不会进行拦截的。
2.2、HandleInterceptor接口说明
public interface HandlerInterceptor {
/**
* 预处理回调方法,实现处理器的预处理(如检查登陆),第三个参数为响应的处理器,自定义Controller
* 返回值:true表示继续流程(调用下一个拦截器或处理器);false表示流程中断,不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;*/
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {
return true;
}
/**
* 后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。*/
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,@Nullable ModelAndView modelAndView) throws Exception {
}
/**
* 整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中*/
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,@Nullable Exception ex) throws Exception {
}
}
多个拦截器执行流程

2.3、自定义拦截器
(1)、实现HandleInterceptor接口
public class HandlerInterceptorDemo1 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {
System.out.println("preHandle 拦截器拦截了");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,Object handler,ModelAndView modelAndView) throws Exception {
System.out.println("postHandle 方法执行了");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {
System.out.println("afterCompletion 方法执行了");
}
}
(2)、配置拦截器
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" /><!-- 用于指定对拦截的 url -->
<mvc:exclude-mapping path=""/><!-- 用于指定排除的 url-->
<bean id="handlerInterceptorDemo1" class="com.web.interceptor.HandlerInterceptorDemo1"></bean>
</mvc:interceptor>
</mvc:interceptors>
三、SpringMVC异常处理
3.1、异常说明
系统中 dao、 service、 controller 都有可能出现预期异常和运行时异常(RuntimeException ),这些都通过 throws Exception 向上抛出,最后由 springmvc 前端控制器交由异常处理器进行异常处理。

3.2、异常处理
(1)、编写异常类
public class CustomException extends Exception {
private String message;
public CustomException(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
(2)、自定义异常处理器
public class CustomExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex) {
ex.printStackTrace();
CustomException customException = null;
//如果抛出的是系统自定义异常则直接转换
if(ex instanceof CustomException){
customException = (CustomException)ex;
}else{
//如果抛出的不是系统自定义异常则重新构造一个系统错误异常。
customException = new CustomException("系统错误,请与系统管理 员联系! ");
}
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("message", customException.getMessage());
modelAndView.setViewName("error");
return modelAndView;
}
}
(3)、配置异常处理器
<bean id="handlerExceptionResolver" class="com.exception.CustomExceptionResolver"/>

浙公网安备 33010602011771号