框架学习07 - SpringMVC 其他功能实现

一. 拦截器实现HandlerInterceptor 接⼝

SpringMVC 中的 Interceptor 拦截器也是相当重要和相当有⽤的,它的主要作⽤是拦截⽤户的请求并进⾏相应的处理。⽐如通过它来进⾏权限验证,或者是来判断⽤户是否登陆等操作。对于 SpringMVC 拦截器的定义⽅式有两种:

实现接⼝:org.springframework.web.servlet.HandlerInterceptor

继承适配器:org.springframework.web.servlet.handler.HandlerInterceptorAdapter

1.拦截器实现HandlerInterceptor 接⼝

java 复制代码
/**
 1. 
 2. 拦截器实现 HandlerInterceptor 接⼝    
 */
 public class MyInterceptor01 implements HandlerInterceptor {
 /**
 3. 在 ⽬标Handler(⽅法)执⾏前 执⾏    
 4. 返回 true:执⾏handler⽅法
 5. 返回 false:阻⽌⽬标handler⽅法执⾏
 6. @param request
 7. @param response
 8. @param handler
 9. @return
 10. @throws Exception
 */
 @Override
 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
Object handler) throws Exception {
 System.out.println("⽬标Handler执⾏前执⾏MyInterceptor01 --> preHandle⽅法...");
 /**
 11. 返回 true:执⾏handler⽅法
 12. 返回 false:阻⽌⽬标handler⽅法执⾏
 */
 return true;
    }
 /**
 13. 在 ⽬标Handler(⽅法)执⾏后,视图⽣成前 执⾏
 14. @param request
 15. @param response
 16. @param handler
 17. @param modelAndView
 18. @throws Exception
 */
 @Override
 public void postHandle(HttpServletRequest request, HttpServletResponse response, 
Object handler, ModelAndView modelAndView) throws Exception {
 System.out.println("⽬标Handler执⾏后,视图⽣成前执⾏MyInterceptor01 --> 
postHandle⽅法...");
    }
 /**
 19. 在 ⽬标Handler(⽅法)执⾏后,视图⽣成后 执⾏
 20. @param request
 21. @param response
 22. @param handler
 23. @param ex
 24. @throws Exception
 */
 @Override
 public void afterCompletion(HttpServletRequest request, HttpServletResponse 
response, Object handler, Exception ex) throws Exception {
System.out.println("⽬标Handler执⾏后,视图⽣成后执⾏MyInterceptor01 --> 
afterCompletion⽅法...");
    }
 }

2.拦截器xml配置

xml 复制代码
 <mvc:interceptors>
 <!-
	定义在 mvc:interceptor 下⾯,可以⾃定义需要拦截的请求
	如果有多个拦截器满⾜拦截处理的要求,则依据配置的先后顺序来执⾏-->
 <mvc:interceptor>
 <!-- 通过 mvc:mapping 配置需要拦截的资源。⽀持通配符。可配置多个。 -->
 <mvc:mapping path="/**"/> <!-- "/**"表示拦截所有的请求。 -->
 <!-- 通过 mvc:mapping 配置不需要被拦截的资源。⽀持通配符。可配置多个。 -->
 <mvc:exclude-mapping path="/url/*"/>  <!-- "/url/*"表示放⾏url路径下的请求。 -->
 <bean class="com.xxxx.springmvc.interceptor.MyInterceptor01"/>
 </mvc:interceptor>
 </mvc:interceptors>

二.继承 HandlerInterceptorAdapter

实际上最终还是 HandlerInterceptor 接⼝实现。

  1. ⼦类实现类
java 复制代码
/**
 1. 拦截器实现     
 2. 继承 HandlerInterceptorAdapter 适配器
 */
 public class MyInterceptor02 extends HandlerInterceptorAdapter {
 /**
 3. 在 ⽬标Handler(⽅法)执⾏前 执⾏  
 4. 返回 true:执⾏handler⽅法   
 5. 返回 false:阻⽌⽬标handler⽅法执⾏
 6. @param request
 7. @param response
 8. @param handler
 9. @return
 10. @throws Exception
 */
 @Override
 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
Object handler) throws Exception {
 System.out.println("⽬标Handler执⾏前执⾏MyInterceptor02 --> preHandle⽅法...");
 /**
 11. 返回 true:执⾏handler⽅法
 12. 返回 false:阻⽌⽬标handler⽅法执⾏
 */
  return true;
    }
 }
  1. 拦截器xml配置
xml 复制代码
<mvc:interceptors>
 <mvc:interceptor>
 <!-- 拦截的资源 -->
 <mvc:mapping path="/**"/>
 <!-- 放⾏的资源 -->
 <mvc:exclude-mapping path="/url/test01"/>
 <mvc:exclude-mapping path="/url/test02"/>
 <bean class="com.xxxx.springmvc.interceptor.MyInterceptor02"/>
 </mvc:interceptor>
 </mvc:interceptors>
  1. 多个拦截器实现
xml 复制代码
<mvc:interceptors>
 <!-
	拦截器链(多个拦截器)
	如果有多个拦截器满⾜拦截处理的要求,则依据配置的先后顺序来执⾏
	先配置的拦截器的 preHandle ⽅法先执⾏
	先配置的拦截器的 postHandle、afterCompletion ⽅法后执⾏-->
 <mvc:interceptor>
 <!-- 拦截所有请求 -->
 <mvc:mapping path="/**" />
 <bean class="com.xxxx.springmvc.interceptor.MyInterceptor01" />
 </mvc:interceptor>
 <mvc:interceptor>
 <!-- 拦截所有请求 -->
<mvc:mapping path="/**" />
 <bean class="com.xxxx.springmvc.interceptor.MyInterceptor02" />
 </mvc:interceptor>
 </mvc:interceptors>

三. ⽂件上传

  1. pom.xml⽂件修改
xml 复制代码
<!-- 添加 commons-fileupload 依赖 -->
 <dependency>
 <groupId>commons-fileupload</groupId>
 <artifactId>commons-fileupload</artifactId>
 <version>1.3.2</version>
 </dependency>
  1. servlet-context.xml修改
xml 复制代码
<!-- ⽂件上传 -->
 <bean id="multipartResolver"
 class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
 <!-- 允许⽂件上传的最⼤尺⼨ -->
 <property name="maxUploadSize">
 <value>104857600</value>
 </property>
 <!-- 
设置⽂件放⼊临时⽂件夹的最⼤⼤⼩限制。
此值是阈值,低于此值,则保存在内存中,如⾼于此值,则⽣成硬盘上的临时⽂件。-->
 <property name="maxInMemorySize">
 <value>4096</value>
 </property>
 </bean>

四.RestFul URL

Restful ⻛格的 API 是⼀种软件架构⻛格,设计⻛格⽽不是标准,只是提供了⼀组设计原则和约束条件。它主要⽤于客户端和服务器交互类的软件。基于这个⻛格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

在Restful ⻛格中,⽤户请求的 url 使⽤同⼀个 url,⽤请求⽅式:get,post,delete,put...等⽅式对请求的处理⽅法进⾏区分,这样可以在前后台分离式的开发中使得前端开发⼈员不会对请求的资源地址产⽣混淆和⼤量的检查⽅法名的麻烦,形成⼀个统⼀的接⼝。

在 Restful ⻛格中,现有规定如下:

GET(SELECT):从服务器查询,可以在服务器通过请求的参数区分查询的⽅式。

POST(CREATE):在服务器端新建⼀个资源,调⽤ insert 操作。

PUT(UPDATE):在服务器端更新资源,调⽤ update 操作。

PATCH(UPDATE):在服务器端更新资源(客户端提供改变的属性)。(⽬前 jdk7 未实现,tomcat7 不⽀持)。

DELETE(DELETE):从服务器端删除资源,调⽤ delete 语句。

  1. Get 请求配置
java 复制代码
/**
 * restful --> get 请求,执⾏查询操作
* @param id
 * @return
 */
 @GetMapping("account/{id}")
 @ResponseBody
 public Account queryAccountById(@PathVariable Integer id){
 return accountService.selectById(id);
 }
  1. Delete 请求配置
java 复制代码
/* restful-->delete 请求 执⾏删除操作
 * @param id
 * @return
 */
@DeleteMapping("account/{id}")
 @ResponseBody
 public Map<String,Object> deleteAccount(@PathVariable Integer id){
 int result = accountService.delAccount(id);
 Map<String,Object> map=new HashMap<String,Object>();
 if(result == 1 ){      
map.put("msg","success");
 map.put("code",200);      
    } 
else {
 map.put("msg","error");
 map.put("code",500);
    }
 return map;
 }
  1. Post 请求配置
java 复制代码
/* restful --> post 请求,执⾏添加操作
 * @return
 */
 @PostMapping("account")
 @ResponseBody
 public Map<String,Object> saveAccount(@RequestBody  Account account){
 int result = accountService.saveAccount(account);
 Map<String,Object> map=new HashMap<String,Object>();
 if(result == 1 ){      
map.put("msg","success");
 map.put("code",200);      
    } 
else {
 map.put("msg","error");
 map.put("code",500);
    }
 return map;
 }
  1. Put 请求配置
java 复制代码
/* restful-->put 请求执⾏更新操作
 * @param id
 * @param account
 * @return
 */
 @PutMapping("account")
 @ResponseBody
 public Map<String,Object> updateAccount(@RequestBody  Account account){
 int result = accountService.updateAccount(account);
 Map<String,Object> map=new HashMap<String,Object>();
 if(result == 1 ){      
map.put("msg","success");
 map.put("code",200);      
    } 
else {
 map.put("msg","error");
 map.put("code",500);
    }
 return map;
 }

五.全局异常统⼀处理

在 JavaEE 项⽬的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的、不可预知的异常需要处理。每个过程都单独处理异常,系统的代码耦合度⾼,⼯作量⼤且不好统⼀,维护的⼯作量也很⼤。

SpringMVC 对于异常处理这块提供了⽀持,通过 SpringMVC 提供的全局异常处理机制,能够将所有类型的异常处理从各处理过程解耦出来,既保证了相关处理过程的功能较单⼀,也实现了异常信息的统⼀

处理和维护。

全局异常实现⽅式 Spring MVC 处理异常有 3 种⽅式:

  1. 使⽤ Spring MVC 提供的简单异常处理器 SimpleMappingExceptionResolver
  2. 实现 Spring 的异常处理接⼝ HandlerExceptionResolver ⾃定义⾃⼰的异常处理器
  3. 使⽤ @ExceptionHandler 注解实现异常处理
  • 全局异常处理⽅式⼀

    1. 配置简单异常处理器

      java 复制代码
      <!-- 配置全局异常统⼀处理的 Bean (简单异常处理器) -->
       <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
       <!-- ⻚⾯在转发时出现异常,设置默认的错误⻚⾯ (error代表的是⼀个视图) -->
       <property name="defaultErrorView" value="error"></property>
       <!-- 异常发⽣时,设置异常的变量名 -->
       <property name="exceptionAttribute" value="ex"></property>
       </bean>

      可以在处理异常的⻚⾯获取异常信息 使用 ${ex}

    2. 使⽤⾃定义异常

      java 复制代码
      /**
       * ⾃定义异常:参数异常 
       */
       public class ParamsException extends RuntimeException {
       private Integer code = 300;
       private String msg = "参数异常!";
       public ParamsException() {
       super("参数异常!");
          }
       public ParamsException(String msg) {
       super(msg);
       this.msg = msg;
          }
       public ParamsException(Integer code) {
       super("参数异常!");
       this.code = code;
          }

      使⽤ SimpleMappingExceptionResolver 进⾏异常处理,具有集成简单、有良好的扩展性、对已有代码没有⼊侵性等优点,但该⽅法仅能获取到异常信息,若在出现异常时,对需要获取除异常以外的数据的
      情况不适⽤。

  • 全局异常处理⽅式⼆(推荐)

    1. 实现 HandlerExceptionResolver 接⼝

      java 复制代码
      /**
       * 全局异常统⼀处理
      */
       @Component
       public class GlobalExceptionResolver implements HandlerExceptionResolver {
       @Override
       public ModelAndView resolveException(HttpServletRequest httpServletRequest, 
      HttpServletResponse httpServletResponse, Object handler, Exception ex) {
       ModelAndView mv = new ModelAndView("error");
       mv.addObject("ex","默认错误信息");
       return mv;
          }
       }
    2. ⾃定义异常处理

      java 复制代码
      /**
       * 全局异常统⼀处理
      */
       @Component
       public class GlobalExceptionResolver implements HandlerExceptionResolver {
       @Override
       public ModelAndView resolveException(HttpServletRequest httpServletRequest, 
      HttpServletResponse httpServletResponse, Object handler, Exception ex) {
       ModelAndView mv = new ModelAndView("error");
       mv.addObject("ex","默认错误信息");
       // 判断是否是⾃定义异常
      if (ex instanceof ParamsException) {
       mv.setViewName("params_error");
       ParamsException e = (ParamsException) ex;
       mv.addObject("ex", e.getMsg());
              }
       if (ex instanceof BusinessException) {
       mv.setViewName("business_error");
       BusinessException e = (BusinessException) ex;
       mv.addObject("ex", e.getMsg());
              }
       return mv;
          }
       }

    使⽤实现 HandlerExceptionResolver 接⼝的异常处理器进⾏异常处理,具有集成简单、有良好的扩展性、对已有代码没有⼊侵性等优点,同时,在异常处理时能获取导致出现异常的对象,有利于提供更详细的异常处理信息。

  • 全局异常处理⽅式三

    • ⻚⾯处理器继承 BaseController

      java 复制代码
       public class BaseController {
       @ExceptionHandler
       public String exc(HttpServletRequest request,HttpServletResponse 
      response,Exception ex){
       request.setAttribute("ex", ex);
       if(ex instanceof ParamsException){
       return "error_param";
              }
       if(ex instanceof BusinessException){
       return "error_business";
              }
       return "error";
          }
       }

    使⽤ @ExceptionHandler 注解实现异常处理,具有集成简单、有扩展性好(只需要将要异常处理的 Controller 类继承于 BaseController 即可)、不需要附加Spring 配置等优点,但该⽅法对已有代码存在⼊侵性(需要修改已有代码,使相关类继承于 BaseController),在异常处理时不能获取除异常以外的数据

  • 未捕获异常的处理

    对于 Unchecked Exception ⽽⾔,由于代码不强制捕获,往往被忽略,如果运⾏期产⽣了Unchecked Exception,⽽代码中⼜没有进⾏相应的捕获和处理,则我们可能不得不⾯对尴尬的 404、 500......等服务器内部错误提示⻚⾯。此时需要⼀个全⾯⽽有效的异常处理机制。⽬前⼤多数服务器也都⽀持在 web.xml 中通过(Websphere/Weblogic)或者(Tomcat)节点配置特定异常情况的显示⻚⾯。修改 web.xml ⽂件,增加以下内容:

    xml 复制代码
    <!-- 出错⻚⾯定义 -->
     <error-page>
     <exception-type>java.lang.Throwable</exception-type>
     <location>/500.jsp</location>
     </error-page>
     <error-page>
     <error-code>500</error-code>
     <location>/500.jsp</location>
     </error-page>
     <error-page>
     <error-code>404</error-code>
     <location>/404.jsp</location>
     </error-page>
相关推荐
旧日之血_Hayter10 分钟前
docker里的jenkins迁移
java·docker·jenkins
Duck Bro40 分钟前
MySQL:表的增删改查(CRUD)
android·java·数据库·c++·mysql
BAGAE2 小时前
tomcat,appche,nginix,jboss区别
java·linux·数据库·ubuntu·tomcat
GGBondlctrl2 小时前
【Spring MVC】如何获取cookie/session以及响应@RestController的理解,Header的设置
java·spring·mvc·cookie·session·header·restcontroller
大梦百万秋2 小时前
Spring Boot开发实战:从入门到构建高效应用
java·spring boot
数懒女士2 小时前
Java常见的锁策略
java·算法
大只因bug2 小时前
基于Springboot的流浪宠物管理系统
java·spring boot·mysql·流浪宠物管理系统·在线宠物管理系统源码·javaweb宠物管理系统·宠物网站系统源码
終不似少年遊*2 小时前
图论1基础内容
数据结构·python·学习·算法·图论
疯一样的码农2 小时前
Maven 如何配置忽略单元测试
java·单元测试·maven
老牛源码2 小时前
Z2400024基于Java+SSM+mysql+maven开发的社区论坛系统的设计与实现(附源码 配置 文档)
java·mysql·maven·ssm