1. 文件上传

  • Spring 使用 Jakarta Commons FileUpload 技术实现了一个 MultipartResolver 实现类:

    CommonsMultipartResolver;
  • SpringMVC 上下文中默认没有装配 MultipartResolver,因此默认情况下不能处理文件的上传;

    若要使用上传功能,需要在上下文中配置 MultipartResolver;
// 1. 导入 jar 包
/* commons-fileupload;
* commons-io;
*/ // 2. 配置 MultipartResolver(多媒体解析器)
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"></property> <!-- 文件大小 1M -->
<property name="maxUploadSize" value="1048576"/>
</bean> // index.jsp
<h2>文件上传</h2>
<form action="${pageContext.request.contextPath}/testUpload" method="post"
enctype="multipart/form-data">
file1:<input type="file" name="upload"/><br/>
file2:<input type="file" name="upload"/><br/>
file3:<input type="file" name="upload"/><br/>
<input type="submit" value="上传"/><br/>
</form> // Demo.java
@RequestMapping(value="/testUpload",method=RequestMethod.POST)
public String testUpload(@RequestParam("upload") MultipartFile[] file)
throws IllegalStateException, IOException { for(MultipartFile mf : file){
if(!mf.isEmpty()){
mf.transferTo(new File("/Users/用户名/Documents/上传/"+
mf.getOriginalFilename()));
}
}
return "ok";
}

2. 自定义拦截器

  1. 自定义的拦截器必须实现 HandlerInterceptor 接口:

    • preHandle():这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求 request 进行

      处理;如果拦截处理后,还需要调用其他的拦截器,或者是业务处理器,则返回 true; 否则,返回false;
    • postHandle():这个方法在业务处理器处理完请求后,但是,DispatcherServlet 向客户端返回

      响应前被调用,处理用户的 request请求;
    • afterCompletion():这个方法在 DispatcherServlet 完全处理完请求后被调用,可以在该方

      法中进行一些资源清理的操作;
// FirstInterceptor.java
public class FirstInterceptor implements HandlerInterceptor{
public boolean preHandle(HttpServletRequest req,HttpServletResponse resp,
Object handler)throws Exception{
System.out.println("FirstInterceptor.....preHandle");
return true;
} public void postHandle(HttpServletRequest req, HttpServletResponse resp,
Object handler, ModelAndView modelAndView)throws Exception{
System.out.println("FirstInterceptor.....postHandle");
} public void afterCompletion(HttpServletRequest req,HttpServletResponse resp,
Object handler,Exception ex) throws Exception{
System.out.println("FirstInterceptor.....afterCompletion");
}
} // 注册该拦截器
<mvc:interceptors>
<bean id="firstInterceptor"
class="cn.itcast.springmvc.interceptor.firstInterceptor"/>
</mvc:interceptors> // index.jsp
示例:<a href="${pageContext.request.contextPath}/helloworld">点击这里</a> // Demo.java
@Controller
public class Demo{
@RequestMapping(value="/hellowrold",method=RequestMethod.GET)
public String helloworld(){
System.out.println("======helloworld");
return "ok";
}
}
运行结果:

2.1 拦截器配置

// 自定义两个拦截器
// FirstInterceptor.java(同上)
// SecondInterceptor.java
public class SecondInterceptor implements HandlerInterceptor{
public boolean preHandle(HttpServletRequest req,HttpServletResponse resp,
Object handler)throws Exception{
System.out.println("SecondInterceptor.....preHandle");
return true;
} public void postHandle(HttpServletRequest req, HttpServletResponse resp,
Object handler, ModelAndView modelAndView)throws Exception{
System.out.println("SecondInterceptor.....postHandle");
} public void afterCompletion(HttpServletRequest req,HttpServletResponse resp,
Object handler,Exception ex) throws Exception{
System.out.println("SecondInterceptor.....afterCompletion");
}
} // 注册拦截器
<mvc:interceptors>
<bean id="firstInterceptor"
class="cn.itcast.springmvc.interceptor.FirstInterceptor"/> <mvc:interceptor>
<mvc:mapping path="/emps"></mvc:mapping>
<bean id="secondInterceptor"
class="cn.itcast.springmvc.interceptor.SecondInterceptor"/>
</mvc:interceptor>
</mvc:interceptors> // Demo.java
@Controller
public class Demo{
@RequestMapping(value="/emps",method=RequestMethod.GET)
public String list(Map<String,Object> map){ System.out.println("emps .... 执行");
map.put("employees",employeeService.getAll());
return "list";
}
} // index.jsp
查询所有员工: <a href="${pageContext.request.contextPath}/emps">查询所有</a>
结果分析
  • 第一个拦截器 preHandler 返回 true,第二个也为 true;

  • 第一个拦截器返回 false,第二个为true或false;

  • 第一个拦截器返回 true,第二个为 false;

3. 异常处理

  1. SpringMVC 通过 HandlerExceptionResolver接口处理程序的异常,包括Handler映射,数据绑定以

    及目标方法执行时,发生的异常;
  2. SpringMVC 提供的 HandlerExceptionResolver接口的实现类:
    • ExceptionHandlerExceptionResolver;
    • DefaultHandlerExceptionResolver;
    • ResponseStatusExdeptionResolver;
    • SimpleMappingExceptionResolver;

3.1 HandlerExceptionResolver

  • @ExceptionHandler只处理当前 handler 方法中抛出的异常
// index.jsp
异常示例:<a href="{pageContext.request.contextPath}/testHandler?age=5">异常处理1</a> // Demo.java
@Controller
public class Demo{ @RequestMapping(value="/testHandler",method=RequestMethod.GET)
public String testHandler(@RequestParam("age") Integer age){
int result = 10 / age;
System.out.println(result);
return "ok";
} // 如果请求参数 age=0, 会报异常 // error.jsp
<body>
抱歉,系统繁忙,请稍候在试....
</body> // 第一种方式: 返回到错误页面,不带异常信息
@ExceptionHandler(value={ArithmeticException.class})
public String dealHandlerExceptionResolver(Exception e){ System.out.println("111111"+e.getMessage());
return "error";
} // 第二种方式: 将异常信息返回到错误页面, 需要使用 ModelAndView, 不能使用 Map
@ExceptionHandler(value={ArithmeticException.class})
public ModelAndView dealHandlerExceptionResolver(Excetption e){ System.out.println("22222"+e.getMessage());
ModelAndView mv = new ModelAndView();
mv.addObject("myexception",e.getMessage());
mv.setViewName("error");
return mv;
} // error.jsp
<body>
抱歉,系统繁忙,请稍候在试....<br/>
异常信息:${requestScope.myexception}
</body> // 异常优先级问题
// ArithmeticExcetion 继承了 RuntimeException
// 如果一个类中既有ArithmeticException, 也有 RuntimeException
// 如果出现 ArithmeticException, 会执行ArithmeticException
@ExceptionHandler(value={RuntimeException.class})
public ModelAndView dealHandlerExceptionResolver2(Excetption e){ System.out.println("33333"+e.getMessage());
ModelAndView mv = new ModelAndView();
mv.addObject("myexception",e.getMessage());
mv.setViewName("error");
return mv;
}
}

3.2 @ControllerAdvice

  • 将所有异常存放在 exception 包下,将业务方法和处理异常的方法分离;
  • @ExceptionHandler中找不到的话,就去@ControllerAdvice标记的类里面查找标记了

    @ExceptionHandler的方法;
// cn.itcast.springmvc.exception.CommonHelperException 类

@ControllerAdvice
public class CommonHelperException{
@ExceptionHandler(value={ArithmeticException.class})
public ModelAndView dealHandlerExceptionResolver(Excetption e){ System.out.println("44444"+e.getMessage());
ModelAndView mv = new ModelAndView();
mv.addObject("myexception",e.getMessage());
mv.setViewName("error");
return mv;
}
}

3.3 ReponseStatusExceptionResolver

// 模拟账户锁定,自定义一个 MyUserLockException 继承了 RuntimeException 的异常类

// index.jsp
账户锁定异常:
<a href="${pageContext.request.contextPath}/testResponse?username=lisi">异常示例</a> // cn.itcast.springmvc.exception.MyUserLockException 类
@ResponseStatus(value=HttpStatus.LOCKED,reason="账户被锁定,请拨打10086")
public class MyUserLockException extends RuntimeException{
private static final long serialVersionUID = 1L;
} // Demo.java
@Controller
public class Demo{
@RequestMapping(value="/testResponse",method=RequestMethod.GET)
public String testResponse(@RequestParam("username") String username){ // username=zhangsan, 抛出异常
if("zhangsan".equalsIgnoreCase(username)){
throw new MyUserLockException();
}
return "ok";
} //第二种用法,@ResponseStatus 用在方法上
// 如果 name=zhangsan, 报 MyUserLockException,
// 如果 name 为其他,报 Not Found
@RequestMapping(value="/testResponse",method=RequestMethod.GET)
@ResponseStatus(value=HttpStatus.NOT_FOUND,reason="测试...")
public String testResponse(@RequestParam("username") String username){ // username=zhangsan, 抛出异常
if("zhangsan".equalsIgnoreCase(username)){
throw new MyUserLockException();
}
return "ok";
}
}

3.4 SimpleMappingExceptionResolver

// 示例: 数组下标越界异常

// springDispatcherServlet-servlet.xml 配置
<bean id="simpleMappingExceptionResolver"
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <!-- 可以自定义 requestScope.异常名称 --
<property name="exceptionAttribute" value="自定义异常名称"/> <property name="exceptionMappings">
<props>
<prop key="java.lang.ArrayIndexOutOfBoundsException">error</prop>
</props>
</property>
</bean> // index.jsp
异常示例:<a href="${pageContext.request.contextPath}/testSimple?id=3">数组下标越界</a> // error.jsp
<body>
抱歉,系统繁忙,请稍候在试!<br/>
数组下标越界:${requestScope.exception}<br/>
</body> // Demo.java
@Controller
public class Demo{
@RequestMapping(value="/testSimple",method=RequestMethod.GET)
public String testSimple(@RequestParam("id") Integer id){ int[] arr = new int[10];
System.out.println(arr[id]);
return "ok";
}
}

参考资料

SpringMVC 之拦截器和异常处理的更多相关文章

  1. SpringMVC——自定义拦截器、异常处理以及父子容器配置

    自定义拦截器: 一.若想实现自定义拦截器,需要实现 org.springframework.web.servlet.HandlerInterceptor 接口. 二.HandlerIntercepto ...

  2. SpringMVC入门一:基础知识(依赖、注解、文件上传/下载、拦截器、异常处理等)

    为了使Spring可插入MVC架构,SpringFrameWork在Spring基础上开发SpringMVC框架,从而使用Spring进行WEB开发时可以选择使用Spring的SpringMVC框架作 ...

  3. SpringMVC经典系列-14自己定义SpringMVC的拦截器---【LinusZhu】

    注意:此文章是个人原创.希望有转载须要的朋友们标明文章出处.假设各位朋友们认为写的还好,就给个赞哈.你的鼓舞是我创作的最大动力,LinusZhu在此表示十分感谢,当然文章中如有纰漏,请联系linusz ...

  4. springmvc中拦截器与springmvc全局异常处理器的问题

    最近在做一个练手的小项目, 系统架构中用了springmvc的全局异常处理器, 做了系统的统一异常处理. 后来加入了springmvc的拦截器, 为了一些需求, 在拦截器中的 preHandle 方法 ...

  5. springmvc的拦截器

    什么是拦截器                                                         java里的拦截器是动态拦截action调用的对象.它提供了一种机制可以使 ...

  6. SpringMVC利用拦截器防止SQL注入

    引言 随着互联网的发展,人们在享受互联网带来的便捷的服务的时候,也面临着个人的隐私泄漏的问题.小到一个拥有用户系统的小型论坛,大到各个大型的银行机构,互联网安全问题都显得格外重要.而这些网站的背后,则 ...

  7. 基于注解风格的Spring-MVC的拦截器

    基于注解风格的Spring-MVC的拦截器 Spring-MVC如何使用拦截器,官方文档只给出了非注解风格的例子.那么基于注解风格如何使用拦截器呢? 基于注解基本上有2个可使用的定义类,分别是Defa ...

  8. SpringMVC 学习-拦截器 HandlerInterceptor 类

    一.拦截器 HandlerInterceptor 类的作用 SpringMVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理. 二.怎么使用呢? 1. ...

  9. springMVC的拦截器工作流程

    首先,springmvc的拦截器配置在这就不多说了.主要讲一下拦截器的三个方法的执行顺序. preHandle方法一定是最先执行的方法,如果它返回为false下面的方法均不执行. postHandle ...

随机推荐

  1. 【Android界面实现】View Animation 使用介绍

        转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992     我们能够使用view animation 动画系统来给View控件加入tween动画(下称& ...

  2. Objective-C之成魔之路【5-选择结构】

    郝萌主倾心贡献.尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主.捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 Objec ...

  3. IOS,objective_C中用@interface和 @property 方式声明变量的区别

    转自:http://www.cnblogs.com/letmefly/archive/2012/07/20/2601338.html 一直有疑问,在objective_C中声明变量会有 2种方式,今天 ...

  4. NSCharacterSet 去除NSString中的空格

    转自:http://blog.sina.com.cn/s/blog_5421851501014xif.html 去除 username中的空格,table newline,nextline 代码如下: ...

  5. jQuery 语法(一)

    通过 jQuery,您可以选取(查询,query) HTML 元素,并对它们执行“操作”(actions). jQuery 语法实例 $(this).hide() 演示 jQuery hide() 函 ...

  6. Ecmall二次开发-增删改查操作

    Ecmall二次开发-增删改查操作 Model目录includes/models 自己添加需要的model class OrdercomplainModel extends BaseModel //类 ...

  7. ASP.NET Web API 使用Swagger生成在线帮助测试文档,支持多个GET

    以下为教程: 在现有webapi项目中,nuget安装以下两个插件 swagger.net.ui swashbuckle 安装完毕后可以卸载Swagger.NET,此处不需要! 安装完毕后屏蔽以下代码 ...

  8. Linux压缩解压缩命令学习笔记

    Linux中主要的压缩文件有:*.gz   *.tar  *.tar.gz  *.zip  *.bz2  *.tar.bz2 .zip这种古老的压缩格式,在window和Linux中都不需要安装软件可 ...

  9. python+pandas+openpyxl下载xls illegalCharacterError

    仅仅是urllib2.unquote_plus解码是不够的,需要将特殊字符去掉 ILLEGAL_CHARACTERS_RE = re.compile(r'[\000-\010]|[\013-\014] ...

  10. java简易excel导入导出工具(封装POI)

    Octopus 如何导入excel 如何导出excel github项目地址 Octopus Octopus 是一个简单的java excel导入导出工具. 如何导入excel 下面是一个excel文 ...