zoukankan      html  css  js  c++  java
  • SpringMVC高级开发(RestFul风格对url的规范,拦截器)

    一. RestFul风格,  对url的规范

     之前的url给后台传递数据:

           localhost:8888/spring10/user/findById.action?K1=v1&k2=v2....

    RestFul风格的url:

      localhost:8888/spring10/user/findById/v1/v2

    SpringMVC 支持restFull风格:

    前端控制器: 拦截url:之前写法:

    <servlet-mapping>
        <servlet-name>springMVC</servlet-name>
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>

    请求的url 只要包含.action, 这个url进入到SpringMVC的前端控制器,  前端控制器调用处理器映射器,  根据url 查找处理器,

    *.html  访问的html页面,  这个url 进入到SpringMVC的前端控制器,前端控制器调用处理器映射器,  根据url 查找处理器, 没找到, 返回404

    1、restFull风格的前端控制器:

    <servlet-mapping>
        <servlet-name>springMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    所有的url( 静态资源[图片,css,js,html]),Controller 的url 都会到前端控制器, ,前端控制器调用处理器映射器, 

    根据url 查找处理器, 静态资源找不到对应的处理器,  404

    注意:不能写成 /*, 包括, 静态资源的url, Controller的url, jsp  都进入到前端控制器

    2、restFul风格对静态资源的处理:   映射到真实的静态资源

    //在spring3.0 之后, 提供了静态资源处理器, 只需要在springMVC配置文件中,配置那些url是静态资源
    <!-- 静态资源处理器 -->
    <!-- /** 表示该文件夹下的所有子文件夹 -->
    <mvc:resources location="/css/" mapping="/css/**" />
    <mvc:resources location="/images/" mapping="/images/**" />
    <mvc:resources location="/page/" mapping="/page/**" />
    <mvc:resources location="/scripts/" mapping="/scripts/**" />

    3、传递参数

    // {名字}  参数占位符   /hello/嘻嘻   --> {name}: 嘻嘻
    @GetMapping("/hello/{uname}/{cid}")
    // @PathVariable("uname") 加在参数名前面, 把url的指定名字的占位符的值 赋值到方法参数上
    public String hello(@PathVariable("uname") String name,@PathVariable("cid") Integer id) {
    System.out.println(name);
    System.out.println(id);
    return "hello";
    }

    4、url写法:

    http://localhost:8080/test/hello/张三/123456

    传值方式只能是少量字段,如果传入多值或者对象还需要使用原来的url方式,不冲突

    二、拦截器

       功能与过滤器一样, 都是拦截用户的请求,  

    与过滤器(Filter)的区别, 执行的先后顺序,   过滤器在前, 拦截器在后,    /*  过滤器拦截所有请求,   /*  进入到前端控制器之后的请求

    SpringMVC的拦截器(Interceptor):

    1、编写一个类实现HandlerInterceptor接口

    public class Interceptor1  implements HandlerInterceptor{
        //preHandle()   在处理器方法之前执行     可以阻止执行处理器的方法
        // true: 放行             false: 拦截
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            System.out.println("Interceptor1的preHandle()....");
            return true;
        }
        //  postHandle() 在处理器执行完, 页面还没有响应之前执行.
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                ModelAndView modelAndView) throws Exception {
            System.out.println("Interceptor1的postHandle()....");
        }
        // 在响应完成之后,执行,   资源的清理  日志的记录
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
            System.out.println("Interceptor1的afterCompletion()....");
        }
    }

    可配置多个不同功能的拦截器

    2、在springMVC的配置文件中进行拦截器的配置

    <!-- 配置拦截器: 配置一组拦截器: 拦截器链 -->
    <mvc:interceptors>
    <!-- 多个拦截器preHandle() 执行顺序根据 mvc:interceptor 
        postHandle() afterCompletion() 与 mvc:interceptor 顺序相反
    -->
    <!-- 一个一个的拦截器 -->
        <mvc:interceptor>
        <!-- 设置拦截的url
            /** 拦截所有url  本级目录以及所有子目录
    /test/aaa            /test/bbb
    /test/aaa/bbb        /test/hello
        -->
            <mvc:mapping path="/test/**"/>
                
            <!-- 排除那些不拦截 -->
            <!-- <mvc:exclude-mapping path="/test/hello/"/> -->
                
            <!-- 指明拦截器 -->
            <bean class="com.zl.house.web.interceptor.Interceptor1"></bean>
        </mvc:interceptor>
            
        <mvc:interceptor>
            <mvc:mapping path="/test/**"/>
            <!-- 指明拦截器 -->
            <bean class="com.zl.house.web.interceptor.Interceptor2"></bean>
            </mvc:interceptor>
        </mvc:interceptors>

    1) 拦截器执行顺序,  拦截器的afterCompletion()执不执行, 由拦截器的preHandle()放回在决定, 如果拦截器的preHandle()返回true, 执行, 如果为false,不执行

    2) 处理器方法执不执行, 由拦截器链所有的preHandle()决定, 只要有一个返回值为false, 不执行.

    测试:

    1 、两个拦截器都放行

    HandlerInterceptor1...preHandle
    HandlerInterceptor2...preHandle 
    HandlerInterceptor2...postHandle
    HandlerInterceptor1...postHandle
    
    HandlerInterceptor2...afterCompletion
    HandlerInterceptor1...afterCompletion
    
    总结:
    preHandle方法按顺序执行,
    postHandle和afterCompletion按拦截器配置的逆向顺序执行。

    2、拦截器1放行,拦截器2不放行

    HandlerInterceptor1...preHandle
    HandlerInterceptor2...preHandle
    HandlerInterceptor1...afterCompletion
    
    总结:
    拦截器1放行,拦截器2 preHandle才会执行。
    拦截器2 preHandle不放行,拦截器2 postHandle和afterCompletion不会执行。
    只要有一个拦截器不放行,postHandle不会执行。

    3、拦截器1不放行,拦截器2不放行

    HandlerInterceptor1...preHandle
    
    拦截器1 preHandle不放行,postHandle和afterCompletion不会执行。
    拦截器1 preHandle不放行,拦截器2不执行。

    4、小结

    preHandle按拦截器定义顺序调用
    postHandler按拦截器定义逆序调用
    afterCompletion按拦截器定义逆序调用
    postHandler在拦截器链内所有拦截器返成功调用
    afterCompletion只有preHandle返回true才调用

     

  • 相关阅读:
    一种在【微服务体系】下的【参数配置神器】
    阅读源代码之“那是我的青春”
    我谈防御式编程
    博客开篇
    redis-sentinel-cluster-codis
    redis-复制
    redis-持久化
    redis-事件
    圆角矩形精度条
    小程序---canvas画图,生成分享图片,画图文字换行
  • 原文地址:https://www.cnblogs.com/64Byte/p/13159543.html
Copyright © 2011-2022 走看看