SpringMVC小记(二)

Controller接口及其实现类:
    Controller是控制器接口,只有一个方法handlerRequest,用于进行请求的功能处理处理完请求后返回ModelAndView
    Spring默认提供了一些Controller接口的实现类以方便我们的使用。以实现AbstractController为例:
        提供了【可选】的会话的串行访问功能
        //串行访问,线程同步
        public class Aa extends AbstractController{
        @Override
        protected ModelAndView handlerRequestInternal(HttpServletRequest request,HttpServletresponse response) throws Exception{
        String name=request.getParameter("name");
        //ModelAndView对象中包括了要返回的逻辑视图以及数据模型
        ModelAndView mv=new ModelAndView();
        //设置视图名称
        mv.setViewName("hello");
        //设置数据模型
        mv.addObject("name",name);
        
        return mv;
        }
        }
        <bean name="/hello" class="com.a.web.controller.Aa">
        <property name="synchronizeOnSession" value="true"></property>
        </bean>
    直接通过response写响应
        例如: public class Aa extends AbstractController{
        @Override
            protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
                throws Exception {
                response.getWriter().write("Hello");
            //如果想直接写响应,可以通过返回null告诉DispatcherServlet自己已经写出响应了不需要进行视图解析了。
            return null;
                
                }}
        强制请求方法类型
            例如:
            //只支持get,post
            <bean name="/hello" class="com.a.web.controller.Aa">
                <property name="supportedMethods" value="POST,GET"></property>
            </bean>
        当请求的session前置条件检查,如果当前请求没有session,将抛出HttpSessionRequiredException异常
         <bean name="/hello" class="com.a.web.Aa">
            <property name="requireSession" value="true"/>
        </bean>
自定义适配器
        一般情况下,springMVCSimpleControllerHandlerAdapter会是我们常用的适配器,也是SpringMVC中默认的适配器
            主要代码:
            public class SimpleControllerHandlerAdapter implements HandlerAdapter {
        public boolean supports(Object handler) {
            return (handler instanceof Controller);
        }
        public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {

            return ((Controller) handler).handleRequest(request, response);
        }
    }
    可以看出,它首先会判断Handler是否实现了Controller接口,如果实现了,那么会调用Controller接口中的handlerRequest方法。
    那么根据这种方式能看出,我们也可以有自己的适配器的实现,那么就可以让任意类成为SpringMVC中的handler了,无论我们的类是否实现了Controller接口

    例如:
        自己的接口:
        public interface MyHandler {
            public ModelAndView handler_test(HttpServletRequest request, HttpServletResponse response)throws Exception;
        }
        自己的适配器:
        public class MyHandlerAdapter implements HandlerAdapter{
            @Override
            public boolean supports(Object handler) {
                return (handler instanceof MyHandler);
            }

            @Override
            public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
                    throws Exception {
                return ((MyHandler)handler).handler_test(request, response);
            }
            /**
            是否使用缓存页面:
            -1 不使用
            1  使用
            */
            @Override
            public long getLastModified(HttpServletRequest request, Object handler) {
                return -1L;
            }

        }

        自己的hander:(就是我们之前写的Controller)
        public class TestController implements MyController{
            @Override
            public ModelAndView handler_test(HttpServletRequest request, HttpServletResponse response) throws Exception {
                String name = request.getParameter("name");
                ModelAndView mv = new ModelAndView("hello");
                mv.addObject("name", name);
                return mv;
            }
        }

        最后在spring的配置中把我们的适配器进行配置即可正常使用.
处理器拦截器
    .应用场景:1.日志记录
              2.权限检查
              3.性能监控
              4.读取用户cookies
              5.OpenSessionInView
    .拦截器接口
        HandlerInterceptor
            preHandler方法:预处理回调方法,实现处理器的预处理
            返回值 :true表示继续流程    false表示流程中断
            postHandler方法:后处理回调方法,实现处理器的后处理
            afterCompletion方法:整个请求处理完毕回调方法,即在视图渲染完毕后回调。
拦截器适配器
        Spring提供了一个HandlerInterceptorAdapter适配器,允许我们实现需要的回调方法。(对三个方法都进行了空实现,其中preHandle方法的返回值默认是true)。
    拦截器是单例
        因此不管多少用户请求多少次都只有一个拦截器实现(线程不安全),必要时可使用ThreadLocal。
    记录执行Controller所用时间
        public class TimeInterceptor extends HandlerInterceptorAdapter{
            //拦截器是单例,不是线程安全的,所以这里使用ThreadLocal
            private ThreadLocal<Long> local = new ThreadLocal<>();

            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                    throws Exception {
                long start = System.currentTimeMillis();
                local.set(start);
                return true;
            }
            @Override
            public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                    throws Exception {
                long end = System.currentTimeMillis();
                System.out.println("共耗时:"+(end-local.get()));
            }
        }
    登录检查
            public class LoginInterceptor extends HandlerInterceptorAdapter{
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                    throws Exception {
                //请求到登录页面放行
                if(request.getServletPath().startsWith("/login")) {
                    return true;
                }

                //如果用户已经登录放行
                if(request.getSession().getAttribute("username") != null) {
                    return true;
                }

                //重定向到登录页面
                response.sendRedirect(request.getContextPath() + "/login");

                return false;
            }
        }


            注意:推荐能使用servlet规范中的过滤器Filter实现的功能就用Filter实现,因为HandlerInteceptor只有在SpringWebMVC环境下才能使用,因此Filter是最通用的、最先应该使用的。
基于注释的SpringMVC
    用于支持注解的配置
        使用基于注解的配置可以省略很多操作。
        在Spring的xml文件中做如下配置:
        <mvc:annotation-driven/>
        
        在Spring中,
        处理器可以使用  @Controller
        业务逻辑层可以使用 @Service
        数据持久层可以使用 @Repository
        
        如果在处理器上使用@Controller直接,还需要在配置文件中指定哪个包下面的类使用了该注解:
        <context:component-scan base-package="com.a.web.controller"/>
    基于注解的Controller
        使用注解后,就不需要再实现特定的接口,任意一个javaBean对象都可以当做处理器对象,对象中任意一个方法都可以作为处理器方法。
        需要:
        在类上加@Controller
        方法上加@RequestMapping注解
    基于注解的Controller的返回值
        1.返回ModelAndView
        2.返回string,表示跳转的逻辑视图名,模型可以通过参数传过来
        3.声明返回类型为void
Spring4中引入的MVC命名空间
        用来支持MVC的配置
        需要声明出这个命名空间及其对应的schemalocation中的值
        <mvc:annotation-driven/>
            自动注册基于注解分格的处理器和适配器
        <mvc:interceptors>
            配置自定义的处理器拦截器
            <mvc:interceptors>
                <mvc:interceptor>
                <mvc:mapping path="/**"/>
                <ref bean="handlerInterceptor1"/>
                </mvc:interceptor>
            </mvc:interceptors>
        <mvc:view-controller>
            收到相应请求后直接选择相应的视图,例如:<mvc:view-controller path="/hello" view-name="test"></mvc:view-controller>
        <mvc:resources>
            <mvc:resources mapping="/images/**" location="/images/"/>
            <mvc:resources mapping="/js/**" location="/js/"/>
            <mvc:resources mapping="/css/**" location="/css/"/>
        <mvc:default-servlet-handler>
            当在web.xml中DispatcherServlet使用<url-pattern>/</url-pattern>映射的时候,会将静态资源也映射了,如果配置了这个mvc标签,那么再访问静态资源的时候就转交给默认的Servlet来响应静态文件。
Spring2.5中引入注释对处理器支持
        @Controller
        用于表示是处理器类
        @RequestMapping
        请求到处理器功能方法的映射规则
        @RequestParam
        写在参数列表上
        请求中的数据和处理方法参数的绑定
        @ModelAttribute
        请求参数到命令对象的绑定
        @SessionAttributes
        用于声明session级别存储的属性,放置在处理器类上
        @InitBinder
        自定义数据绑定注册支持,用于将请求参数转换到命令对象属性的对应类型。
Spring4引入了更多的注解,其中包含了对RESTful架构风格的支持
        @CookieValue
        cookie数据到处理器功能处理方法的方法参数上的绑定;

        @RequestHeader
        请求头数据到处理器功能处理方法的方法参数上的绑定;
        @RequestBody
        请求的body体的绑定
        @ResponseBody
        处理器功能处理方法的返回值作为响应体
        @ResponseStatus
        定义处理器功能处理方法/异常处理器返回的状态码和原因;
    
        @ExceptionHandler
        注解式声明异常处理器;
        写在方法
        如果发生指定异常-->执行下面方法

        @PathVariable
        请求URI 中的模板变量部分到处理器功能处理方法的方法参数上的绑定,从而支持RESTful架构风格的URI;
请求映射分类:
        URL路径映射
            使用URL映射到处理器的功能处理方法
        请求方法映射限定
            例如限定功能处理方法支持力get请求
        请求参数映射限定
            例如限定只处理包含username参数的请求
        请求头限定映射

猜你喜欢

转载自www.cnblogs.com/JSB-Li/p/11771064.html