当前位置 : 主页 > 编程语言 > java >

SpringMVC核心技术

来源:互联网 收集:自由互联 发布时间:2021-08-21
目录 请求重定向和转发 请求转发 请求重定向 异常处理 SpringMVC拦截器 拦截器过滤器的区别 SpringMVC执行流程理解 SpringMVC执行流程分析 总结 请求重定向和转发 当处理器对请求处理完毕
目录
  • 请求重定向和转发
    • 请求转发
    • 请求重定向
    • 异常处理
    • SpringMVC拦截器
  • 拦截器过滤器的区别
    • SpringMVC执行流程理解
    • SpringMVC执行流程分析
  • 总结

    请求重定向和转发

    当处理器对请求处理完毕后,向其它资源进行跳转是,有两种跳转方式:请求转发与重定向。而根据索要跳转的资源类型,又可分为两类:跳转到页面与跳转到其他处理器。

    注意:对于请求转发的页面,可以是WEB-INF中页面,而重定向的页面,是不能为WEB-INF中的,因为重定向相当于用户再次发出一次请求,而用户不能直接访问WEB-INF中的资源。

    SpringMVC框架把原来Servlet中的请求转发和重定向操作进行了封装,现在可以使用简单的方式实现转发和重定向。

    forward:表示转发,实现request.getRequestDispathcer("xx.jsp").forward();

    redirect:表示重定向,实现response.sendRediect("xxx.jsp");

    请求转发

    处理器方法返回 ModelAndView 时,需在 setViewName()指定的视图前添加 forward:,且此时的视图不再与视图解析器一同工作,这样可以在配置了解析器时指定不同位置的视图。视图页面必须写出相对于项目根的路径。forward 操作不需要视图解析器。处理器方法返回 String,在视图路径前面加入 forward: 视图完整路径。

    @RequestMapping(value = "/some",produces = "text/plain;charset=utf-8")
    public ModelAndView testForward(String name,Integer age){
        ModelAndView mv = new ModelAndView();
        mv.addObject("name",name);
        mv.addObject("age",age);
        mv.setViewName("forward:/WEB-INF/view/show.jsp");
        return mv;
    }

    请求重定向

    在处理器方法返回的视图字符串的前面添加 redirect:,则可实现重定向跳转。

    @RequestMapping(value = "/other")
    public ModelAndView testRedirect(String name,Integer age){
        ModelAndView mv = new ModelAndView();
        mv.addObject("name",name);
        mv.addObject("age",age);
        mv.setViewName("redirect:/other.jsp");
        return mv;
    }

    异常处理

    使用注解@ExceptionHandler 可以将一个方法指定为异常处理方法。该注解只有一个可选属性 value,为一个 Class<?>数组,用于指定该注解的方法所要处理的异常类,即所要匹配的异常。而被注解的方法,其返回值可以是 ModelAndView、String,或 void,方法名随意,方法参数可以是 Exception 及其子类对象、HttpServletRequest、HttpServletResponse 等。系统会自动为这些方法参数赋值。对于异常处理注解的用法,也可以直接将异常处理方法注解于 Controller 之中。

    代码演示

    第一步:自定义两个异常类

    public class MyException extends Exception {
        public MyException() {
            super();
        }
        public MyException(String message) {
            super(message);
        }
    }
    
    public class AgeException extends MyException {
        public AgeException() {
            super();
        }
        public AgeException(String message) {
            super(message);
        }
    }
    public class NameException extends MyException {
        public NameException() {
            super();
        }
        public NameException(String message) {
            super(message);
        }
    }
    

    第二步:在controller方法中抛出异常

    @RequestMapping(value = "exception")
    public ModelAndView askForException(String name,Integer age) throws MyException {
        ModelAndView mv = new ModelAndView();
        if(!"zs".equals(name)){
            throw new NameException("姓名不正确!!!");
        }
        if (age == null || age > 80){
            throw new AgeException("年龄太大了!!!");
        }
        mv.addObject("name",name);
        mv.addObject("age",age);
        mv.setViewName("show");
        return mv;
    

    第三步:定义三个异常响应页面

    nameError.jsp
    <br/>
    提示信息:${msg}
    <br/>
    系统信息:${ex.message}
    ageError.jsp
    <br/>
    提示信息:${msg}
    <br/>
    系统信息:${ex.message}
    otherError.jsp
    <br/>
    提示信息:${msg}
    <br/>
    系统信息:${ex.message}

    第四步:定义全局异常处理类

    @ControllerAdvice
    public class GlobalExceptionHandler {
        @ExceptionHandler(value = NameException.class)
        public ModelAndView nameException(Exception ex){
            ModelAndView mv = new ModelAndView();
            mv.addObject("msg","姓名不是zs");
            mv.addObject("ex",ex);
            mv.setViewName("nameError");
            return mv;
        }
        @ExceptionHandler(value = AgeException.class)
        public ModelAndView ageException(Exception ex){
            ModelAndView mv = new ModelAndView();
            mv.addObject("msg","年龄超过80岁啦");
            mv.addObject("ex",ex);
            mv.setViewName("ageError");
            return mv;
        }
        @ExceptionHandler
        public ModelAndView otherException(Exception ex){
            ModelAndView mv = new ModelAndView();
            mv.addObject("msg","未知异常");
            mv.addObject("ex",ex);
            mv.setViewName("otherError");
            return mv;
        }
    }
    

    第五步:在spring配置controller和handler的注解扫描

    <!--开启Controller注解扫描-->
    <context:component-scan base-package="school.xauat.controller"></context:component-scan>
    <!--配置视图解析器-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
    <!--开启注解驱动-->
    <mvc:annotation-driven></mvc:annotation-driven>
    <!--开启ControllerAdvice注解扫描-->
    <context:component-scan base-package="school.xauat.handler"></context:component-scan>

    SpringMVC拦截器

    SpringMVC 中的 Interceptor 拦截器是非常重要和相当有用的,它的主要作用是拦截指定的用户请求,并进行相应的预处理与后处理。其拦截的时间点在“处理器映射器根据用户提交的请求映射出了所要执行的处理器类,并且也找到了要执行该处理器类的处理器适配器,在处理器适配器执行处理器之前”。当然,在处理器映射器映射出所要执行的处理器类时,已经将拦截器与处理器组合为了一个处理器执行链,并返回给了中央调度器。

    定义拦截器类

    public class myInterceptor implements HandlerInterceptor {
        private Long beginTime;
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("preHandle方法执行");
            beginTime = System.currentTimeMillis();
            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方法执行");
            Long endTime = System.currentTimeMillis();
            System.out.println("程序执行时间" + (endTime - beginTime) + "ms");
        }
    }
    

    在springMVC配置文件注册拦截器

    <mvc:interceptors>
         <mvc:interceptor>
              <mvc:mapping path="/**"/>
              <bean class="school.xauat.handler.MyInterceptor"></bean>
         </mvc:interceptor>
    </mvc:interceptors>

    自定义拦截器,需要实现 HandlerInterceptor 接口。而该接口中含有三个方法:

    preHandle(request,response, Object handler):

    该方法在处理器方法执行之前执行。其返回值为 boolean,若为 true,则紧接着会执行处理器方法,且会将 afterCompletion()方法放入到一个专门的方法栈中等待执行。

    postHandle(request,response, Object handler,modelAndView):

    该方法在处理器方法执行之后执行。处理器方法若最终未被执行,则该方法不会执行。由于该方法是在处理器方法执行完后执行,且该方法参数中包含 ModelAndView,所以该方法可以修改处理器方法的处理结果数据,且可以修改跳转方向。

    afterCompletion(request,response, Object handler, Exception ex):

    当 preHandle()方法返回 true 时,会将该方法放到专门的方法栈中,等到对请求进行响应的所有工作完成之后才执行该方法。即该方法是在中央调度器渲染(数据填充)了响应页面之后执行的,此时对 ModelAndView 再操作也对响应无济于事。

    afterCompletion 最后执行的方法,清除资源,例如在 Controller 方法中加入数据

    拦截器中方法和处理器方法的执行顺序如下图

    当有多个拦截器时

    拦截器过滤器的区别

    拦截器和过滤器的区别

    1、过滤器是Servlet中的对象。拦截器是框架中的对象

    2、过滤器是实现Filter接口的对象。拦截器是实现HandlerInterceptor接口

    3、过滤器用来设置request和response的参数、属性。

    4、过滤器是在拦截器之前先执行的

    5、过滤器是Tomcat服务器中创建的对象,拦截器是springmvc容器中创建的对象

    6、过滤器是一个执行时间点,拦截器有三个执行时间点

    7、过滤器可以处理jsp、js、html等,拦截器是侧重拦截对controller的对象,如果你的请求不能被中央调度器接受,这个请求就不会执行拦截内容

    SpringMVC执行流程理解

    SpringMVC执行流程分析

    (1)浏览器提交请求到中央调度器

    (2)中央调度器直接将请求转给处理器映射器。

    (3)处理器映射器会根据请求,找到处理该请求的处理器,并将其封装为处理器执行链后返回给中央调度器。

    (4)中央调度器根据处理器执行链中的处理器,找到能够执行该处理器的处理器适配器。

    (5)处理器适配器调用执行处理器。

    (6)处理器将处理结果及要跳转的视图封装到一个对象 ModelAndView 中,并将其返回给处理器适配器。

    (7)处理器适配器直接将结果返回给中央调度器。

    (8)中央调度器调用视图解析器,将 ModelAndView 中的视图名称封装为视图对象。

    (9)视图解析器将封装了的视图对象返回给中央调度器

    (10)中央调度器调用视图对象,让其自己进行渲染,即进行数据填充,形成响应对象。

    (11)中央调度器响应浏览器。

    总结

    本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注自由互联的更多内容!

    网友评论