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"/>  
posted @ 2020-05-25 23:27  ciyelc  阅读(100)  评论(0)    收藏  举报