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才调用

 

 

posted @ 2020-06-18 20:03  64Byte  阅读(821)  评论(0编辑  收藏  举报