1 概述

  • SpringMVC文件上传
  • SpringMVC拦截器快速入门
  • SpringMVC异常处理机制

2 文件上传

2.1 客户端表单实现

文件上传客户端表单需要满足:

表单项type=“file”

表单的提交方式是post

表单的enctype属性是多部分表单形式,及enctype=“multipart/form-data”

springmvc 使用map接收表单数据_java

2.2 文件上传原理

当form表单修改为多部分表单时,request.getParameter()将失效。

enctype=“application/x-www-form-urlencoded”时,form表单的正文内容格式是:key=value&key=value&key=value

当form表单的enctype取值为Mutilpart/form-data时,请求正文内容就变成多部分形式:

springmvc 使用map接收表单数据_java_02

2.3 单文件上传代码实现

步骤:

  • 导入fileupload和io坐标
  • 配置文件上传解析器
  • 编写文件上传代码
  1. 导入fileupload和io坐标
<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.3</version>
</dependency>
  1. 在spring-mvc中配置文件上传解析器
<!--配置文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!--上传文件的编码类型-->
    <property name="defaultEncoding" value="UTF-8"/>
    <!--上传文件总大小-->
    <property name="maxUploadSize" value="500000"/>
    <!--上传单个文件的大小-->
	<property name="maxUploadSizePerFile" value="5242800"/>
</bean>
  1. 编写代码
@RequestMapping("/quick22")
@ResponseBody
public void save22(String username, MultipartFile uploadFile) throws IOException {
    System.out.println(username);
    String originalFilename = uploadFile.getOriginalFilename();
    uploadFile.transferTo(new File("C:\\upload\\"+originalFilename));
}

3 拦截器

Spring MVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理后处理

将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(Interceptor Chain)。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是AOP思想的具体实现。

3.1 拦截器和过滤器的区别

区别

过滤器

拦截器

使用范围

是 servlet 规范中的一部分,任何 Java Web 工程都可以使用

是 SpringMVC 框架自己的,只有使用了 SpringMVC 框架的工程才能用

拦截范围

在 url-pattern 中配置了/*之后,可以对所有要访问的资源拦截

只会拦截访问的控制器方法,如果访问的是 jsp,html,css,image 或者 js 是不会进行拦截的

3.2 自定义拦截器

  • 创建拦截器类实现HandlerInterceptor接口
  • 配置拦截器
  • 测试拦截器的拦截效果
  1. 在spring-mvc.xml中配置权限拦截器
<!--配置权限拦截器-->
<mvc:interceptors>
    <mvc:interceptor>
        <!--配置对哪些资源执行拦截操作-->
        <mvc:mapping path="/**"/>
        <!--配置哪些资源排除拦截操作-->
        <mvc:exclude-mapping path="/user/login"/>
        <bean class="com.itheima.interceptor.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>
  1. 创建拦截器类
public class MyInterceptor1 implements HandlerInterceptor {

    // 在目标方法执行之前 执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        String param = request.getParameter("param");
        if("yes".equals(param)) {
            return true;
        }else {
            request.getRequestDispatcher("/error.jsp").forward(request,response);
            return false;
        }
    }

    // 在目标方法执行之后,视图返回之前
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        modelAndView.addObject("name","itheima");
        System.out.println("postHandle");

    }

    // 在整个流程都执行完毕后执行
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
}

3.3 拦截器总结

当拦截器的preHandle方法返回true则会执行目标资源,如果返回false则不执行目标资源

多个拦截器情况下,配置在前的先执行,配置在后的后执行

拦截器中的方法执行顺序是:preHandler-------目标资源----postHandle---- afterCompletion

三个方法说明:

方法名

说明

preHandle()

方法将在请求处理之前进行调用,该方法的返回值是布尔值Boolean类型的,当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方法

postHandle()

该方法是在当前请求进行处理之后被调用,前提是preHandle 方法的返回值为true 时才能被调用,且它会在DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作

afterCompletion()

该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行,前提是preHandle 方法的返回值为true 时才能被调用

4 异常处理

4.1 异常处理思路

系统中异常包括两类:预期异常运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试等手段减少运行时异常的发生。

在SpringMVC中异常在系统的DaoServiceController出现都通过throws Exception向上抛出,最后由SpringMVC前端控制器交由异常处理器进行异常处理,如下图:

springmvc 使用map接收表单数据_java_03

4.2 SpringMVC异常处理的方式

  • 使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver
  • 实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器

**方式一:**简单异常处理器SimpleMappingExceptionResolver

SpringMVC已经定义好了该类型转换器,在使用时可以根据项目情况进行相应异常与视图的映射配置

在Spring-mvc.xml中添加如下配置

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="defaultErrorView" value="error"/>;  默认错误视图
    <property name="exceptionMappings">
        <map>
            <entry key="java.lang.ClassCastException" value="error1"/>  异常类型和错误视图
            <entry key="com.itheima.exception.MyException" value="error2"/>
        </map>
    </property>
</bean>

方式二:自定义异常处理步骤

①创建异常处理器类实现HandlerExceptionResolver

public class MyExceptionResolver implements HandlerExceptionResolver {    
    @Override  
    public ModelAndView resolveException(HttpServletRequest request, 
    HttpServletResponse response, Object handler, Exception ex) {
        //处理异常的代码实现    
        //创建ModelAndView对象      
        ModelAndView modelAndView = new ModelAndView();       				
        modelAndView.setViewName("exceptionPage");       
        return modelAndView;
    }
}

②配置异常处理器

<bean id="exceptionResolver"        
      class="com.itheima.exception.MyExceptionResolver"/>

③编写异常页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
        <head>    
            <title>Title</title>
        </head>
        <body>    
            这是一个最终异常的显示页面
        </body>
    </html>

④测试异常跳转

@RequestMapping("/quick22")
@ResponseBody
public void quickMethod22() throws IOException, ParseException {   
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    simpleDateFormat.parse("abcde");
}

4.3 异常处理总结

异常处理方式

  • 配置简单异常处理器SimpleMappingExceptionResolver
  • 自定义异常处理器

自定义异常处理步骤

①创建异常处理器类实现HandlerExceptionResolver

②配置异常处理器

③编写异常页面

④测试异常跳转