A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 梦想飞翔的猪 于 2018-2-1 17:26 编辑

【石家庄校区】总复习系列贴-springMvc(三)



1.      全局异常处理
a)      创建自定义异常处理类
b)      实现HandlerExceptionResolver 实现resolveException方法
c)      在SpringMvc.xml中配置自定义异常处理类
[XML] 纯文本查看 复制代码
<!-- 异常处理器 -->[/align]    <bean id="handlerExceptionResolver" class="cn.itcast.ssm.controller.exceptionResolver.CustomExceptionResolver"/>
2.      图片上传
a)      配置图片上传解析器
[XML] 纯文本查看 复制代码
<!-- 文件上传 -->[/align]    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
       <!-- 设置上传文件的最大尺寸为5MB -->
       <property name="maxUploadSize">
           <value>5242880</value>
       </property>
    </bean>
b)      图片上传页面配置
[XML] 纯文本查看 复制代码
<form id="itemForm"[/align]action="${pageContext.request.contextPath }/item/editItemSubmit.action"
       method="post" enctype="multipart/form-data">
       <input type="hidden" name="pic" value="${item.pic }" />
 
 
<!--file的name与controller形参一致:-->
<tr>
    <td>商品图片</td>
    <td><c:if test="${item.pic !=null}">
           <img src="/pic/${item.pic}" width=100 height=100 />
           <br />
       </c:if> <input type="file" name="pictureFile" /></td>
</tr>
c)      后台代码编写
[Java] 纯文本查看 复制代码
@RequestMapping("/editItemSubmit")[/align]     public String editItemSubmit(Items items, MultipartFile pictureFile)throws Exception{
          //原始文件名称
          String pictureFile_name =  pictureFile.getOriginalFilename();
          //新文件名称
          String newFileName = UUID.randomUUID().toString()+pictureFile_name.substring(pictureFile_name.lastIndexOf("."));
          //上传图片
          File uploadPic = new java.io.File("F:/develop/upload/temp/"+newFileName);
          if(!uploadPic.exists()){
               uploadPic.mkdirs();
          }
          //向磁盘写文件
          pictureFile.transferTo(uploadPic);
.....
3.      拦截器
a)      简介:
Spring Web MVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
b)      常见应用场景
1、日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。
2、权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直接返回到登录页面;
3、性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);
4、通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现。
5、OpenSessionInView:如Hibernate,在进入处理器打开Session,在完成后关闭Session。
本质也是AOP(面向切面编程),也就是说符合横切关注点的所有功能都可以放入拦截器实现。
c)      拦截器接口
[Java] 纯文本查看 复制代码
package org.springframework.web.servlet; [/align]public interface HandlerInterceptor { 
    boolean preHandle( 
            HttpServletRequest request, HttpServletResponse response,  
            Object handler)  
            throws Exception; 
 
    void postHandle( 
            HttpServletRequest request, HttpServletResponse response,  
            Object handler, ModelAndView modelAndView)  
            throws Exception; 
 
    void afterCompletion( 
            HttpServletRequest request, HttpServletResponse response,  
            Object handler, Exception ex) 
            throws Exception; 
} 
                    i.           preHandle预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器(如我们上一章的Controller实现);
                  ii.           返回值:true表示继续流程(如调用下一个拦截器或处理器);
                 iii.           false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;
                 iv.           postHandle后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。
                  v.           afterCompletion整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器的afterCompletion
d)      拦截器适配器
有时候我们可能只需要实现三个回调方法中的某一个,如果实现HandlerInterceptor接口的话,三个方法必须实现,不管你需不需要,此时spring提供了一个HandlerInterceptorAdapter适配器(一种适配器设计模式的实现),允许我们只实现需要的回调方法。
[Java] 纯文本查看 复制代码
public abstract class HandlerInterceptorAdapter implements HandlerInterceptor { [/align]     //省略代码 此处所以三个回调方法都是空实现,preHandle返回true。 
}

e)      执行流程
    i.正常流程
      
第二个拦截器的pre方法返回false
中断流程中,比如是HandlerInterceptor2中断的流程(preHandle返回false),此处仅调用它之前拦截器的preHandle返回true的afterCompletion方法。
总结:
preHandle按拦截器定义顺序调用
postHandler按拦截器定义逆序调用
afterCompletion按拦截器定义逆序调用
postHandler在拦截器链内所有拦截器返成功调用
afterCompletion只有preHandle返回true才调用
a)      配置使用拦截器
                    i.           编写拦截器器
[Java] 纯文本查看 复制代码
package cn.javass.chapter5.web.interceptor; [/align]//省略import  
public class HandlerInterceptor1 extends HandlerInterceptorAdapter {//此处一般继承HandlerInterceptorAdapter适配器即可  
    @Override  
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  
        System.out.println("===========HandlerInterceptor1 preHandle");  
        return true;  
    }  
    @Override  
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {  
        System.out.println("===========HandlerInterceptor1 postHandle");  
    }  
    @Override  
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {  
        System.out.println("===========HandlerInterceptor1 afterCompletion");  
    }  
}  
                  ii.           配置拦截器
[XML] 纯文本查看 复制代码
<!--拦截器 -->[/align]<mvc:interceptors>
       <!--多个拦截器,顺序执行 -->
       <mvc:interceptor>
              <mvc:mapping path="/**"/>
              <bean class="cn.itcast.springmvc.filter.HandlerInterceptor1"></bean>
       </mvc:interceptor>
       <mvc:interceptor>
              <mvc:mapping path="/**"/>
              <bean class="cn.itcast.springmvc.filter.HandlerInterceptor2"></bean>
       </mvc:interceptor>
</mvc:interceptors>

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马