zoukankan      html  css  js  c++  java
  • Spring学习笔记之五----Spring MVC

    1. Spring MVC通常的执行流程是:当一个Web请求被发送给Spring MVC Application,Dispatcher Servlet接收到这个请求,通过HandlerMapping找到Controller,将这个请求委派给Controller的某个Handler Method处理,这个Handler Method处理完这个请求,返回一个ModelAndView给Dispatcher Servlet,Dispatcher Servlet利用View Name,请求View Resolver,View Resolver返回相应的view;Dispatcher Servlet拿到View后,将Model传递给View,然后将Response返回;
    2. 对于每一个Controller里面的Handler Method,它可以接收以下的参数:
      • HttpServletRequest或HttpServletResponse类型的对象;
      • 任意类型的请求参数,使用@RequestParam标注,这些请求参数的值来自于Url中的request parameter;
      • 任意类型的Path Variable,使用@PathVariable来标注,这些参数的值来自于请求Path中的一部分,在使用这个的前提是你必须在这个Handler Method标注的@RequestMapping里面使用占位符;
      • Model类型的对象;你可以向这个对象里面添加attributes;
      • 任意类型的Cookie属性值,使用@CookieValue标注;
      • Map或者ModelMap类型的对象,Handler Method可以用来向Model里面添加属性;
      • Errors或者BindingResult类型的对象,Handler Method用来访问Model对象的验证结果;
      • SessionStatus类型的对象,Handler Method可以用来设置一个Session的完成;
      Handler Method可以有两种类型的返回值:
      • 一种是String,表示视图名;
      • 另外一种是void,这要取决于Handler Method接收的参数,如果其接收了ModelAndView类型的参数,并在这个参数中设置了视图名,那么这个视图名将被以后的View Resolver所使用,否则Spring会根据在@RequestMapping中配置的URL,将URL最后那部分默认的视图名,如果@RequestMapping中配置的URL最后那部分是一个通配符(*),则会将当前Handler Method的方法名作为View Name;
    3. 在一个基于SpringMVC的Web应用程序里面,一般有两种配置文件:
      • 一个是Web Application的配置文件(web.xml),你需要在里面指定一个或者多个servlet实例以及url到servlet的映射关系:
        <servlet>
            <servlet-name>servlet name</servlet-name>
            <servlet-class>
                org.springframework.web.servlet.DispatcherServlet
            </servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>servlet name</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
        在比较大的应用程序里,指定多个DispatcherServlet实例尤其重要,这样可以让每个DispatcherServlet服务于不同的功能,拥有不同的并完全隔离的Spring Container;
      • 另外一个是Spring MVC配置文件,在没指定的情况下,每一个DispatcherServlet都会去WEB-INF目录下加载一个名为{servlet name}-servlet.xml的Spring配置文件;你也可以通过一个名为contextConfigLocation的servlet parameter来指定;
        你还可以指定一个Root Application的配置文件,这个配置文件中的bean会被每一个DispatcherServlet的配置文件中的bean访问或者复写,这个配置文件必须通过一个ContextLoaderListener类型的Listener来加载,你可以通过一个名为contextConfigLocation的context parameter来指定这个配置文件名,默认情况下这个文件是/WEB-INF/applicationContext.xml。
    4. 在你在创建Web Application的Controller之前,你需要在Application Context配置文件中添加<context:component-scan base-package="…" />去Scan所有的标记有@Controller和@RequestMapping annotations的类;或者在你的配置类上加上@ComponentScan annotation,并设置basePackages属性;
      除此之外,我们需要让Spring MVC能预注册一些Bean,所以我们需要在Application Context配置文件中加上<mvc:annotation-driven />;你也可以在你的配置类上加上@EnableWebMvc annotation达到相同的效果;
    5. 在Handler Method返回视图名之后,你需要在Application Context配置文件中添加一个ViewResolver的Bean,这个Bean负责将一个View name解析为一个View的实现;
    6. 如果我们要将一个请求映射到Controller中的一个方法,我们必须要将这个方法用@RequestMapping annotation来标注,并在这个annotation中指定映射的路径,这个路径可以是一个明确的路径,也可以包含通配符,也可以包含一些Path Variable的占位符;如果在@RequestMapping annotation中没有指定路径,则默认这个Handler Method将使用其所在Controller上配置的@RequestMapping annotation中指定的路径,你也可以在@RequestMapping中限定Request Type;
    7. Servlet API提供了Servlet Filter在Servlet被执行之前或者执行之后去拦截Web请求,Spring MVC也提供了名为Handler interceptor的组件,它用来在一个请求被Handler Method处理之前或者之后,或者在视图已经被渲染之后去拦截这个请求;Handler interceptor相对于Servlet Filter来说,它被配置在Application Context里面,所以它能利用很多Spring Container的特征,比如说可以用来引用Spring Container中的bean;为了定义一个Handler interceptor,我们要么是实现HandlerInterceptor接口,要么是继承HandlerInterceptorAdapter类;它包含3个Method:
      • preHandle()这个方法用于在Handler Method被执行之前被调用,一般返回true,否则DispatcherServlet会认为这个方法已经处理了这个请求,可以立刻将Response返回给用户;
      • postHandler()方法用于在Handler Method被执行之后被调用,在这个方法里面我们能够访问或者修改在Handler Method中生成的ModelAndView;
      • afterCompletion()方法用于在整个请求流程完成之后被调用;
      为了注册一个Interceptor到Spring Container中,我们要做一些特殊的操作:
      • 首先,我们需要将这个自定义的Handler interceptor在配置类中定义为一个bean;
      • 让配置类继承自WebMvcConfigurerAdapter类,并复写addInterceptors方法,该方法包含一个InterceptorRegistry类型的参数;
      • 调用InterceptorRegistry.addInterceptor()方法传入Handler interceptor Bean;
      默认情况下Handler Interceptor会应用到所有@Controller中的所有Handler Methods,我们也可以在addInterceptor()方法后调用addPathPatterns()去指明这个Handler Interceptor应该用到哪些URL,当然我们也可以调用excludePathPatterns()方法用于指明哪些URLs它不应该用到;
    8. 为了让Web Application支持本地化,我们需要在Spring Container中添加一个实现了LocalResolver的Bean,该Bean的name必须是localResolver;这个LocalResolver通过检测客户端提供的某些信息获取客户端Locale信息,然后设置当前请求的Locale;Spring默认提供了以下几种LocalResolver:
      • AcceptHeaderLocaleResolver:该Resolver通过读取Http Request中的accept-language header信息来获取客户端Locale信息;
      • SessionLocaleResolver:从Session中读取一个预定义的属性值,如果这个属性不存在,则从Http Request中的accept-language header中读取;你也可以通过SessionLocaleResolver的DefaultLocale属性来设置一个默认值;
      • CookieLocaleResolver:从用户浏览器的Cookie中读取一个属性值,如果这个属性不存在,则从Http Request中的accept-language header中读取;你可以通过设置CookieLocaleResolver的cookieName和cookieMaxAge属性来设置这个Cookie的属性名和最大的过期时间;你也可以通过SessionLocaleResolver的DefaultLocale属性来设置一个默认值;
      如何修改一个Request中的Locale,你可以通过直接调用LocaleResolver.setLocale()方法,也可以注册一个LocaleChangeInterceptor并将其应用到所有的请求,在LocaleChangeInterceptor中你可以通过一个paramName属性指定一个参数名,当LocaleChangeInterceptor在当前请求中检测到有这个参数出现时,则会使用这个参数的值作为当前请求的Locale;
    9. 我们通过LocalResolver能够获得客户端的Locale信息,那么我们就可以使用这些Locale信息向用户渲染不同的内容,这里我们要使用Message Source,我们需要在Spring Container中创建一个名为messageSource的bean,该bean的类型是ResourceBundleMessageSource;我们需要设置这个bean的basename到适当的resource bundle,那么我们就可以在jsp文件中使用<spring:message code="message code"/>去获得message;
    10. 在Spring MVC的Web Application中,使用一个或多个ViewResolver将Handler Method返回的view name解析为一个View对象;Spring MVC提供了以下几个ViewResolver:
      • InternalResourceViewResolver:通过指定一个Prefix和Sufix属性将Handler Method返回的View name拼凑成一个View文件的路径,然后再找到该视图文件编译后生成一个类型为JstlView的对象,我们也可以通过设置InternalResourceViewResolver的viewClass属性来设置该对象的类型;InternalResourceViewResolver比较简单,但是只能在找到整个应用程序中内部存在的资源视图;InternalResourceViewResolver还可以解析Redirect视图,如果某个Handler Method返回一个redirect:XXX的视图名,InternalResourceViewResolver会将这个视图名解析为到redirect:后面那一部分代表的URL的请求;
      • XmlViewResolver:我们可以将视图以bean的形式创建在Spring Container中,然后我们可以使用XmlViewResolver将视图名解析为一个View Bean;这些View Bean可以定义在当前的配置文件中,也可以定义在一个独立的Spring配置文件中,我们可以通过设置XmlViewResolver的location属性指定这个配置文件;默认是/WEB-INF/views.xml;
      • ResourceBundleViewResolver:我们可以通过ResourceBundleViewResolver来将一个Viewname解析为一个View对象,需要为ResourceBundleViewResolver对象的baseName属性指定一个Resource Bundle,这个Resource Bundle文件的格式应该是:
        {View name}.(class)={View class full name}
        {View name}.url={View file path}
      在一个SpringMVC的Web Application中可以创建多个ViewResolver的Bean,如果这种情况存在,你需要指定每一个ViewResolver的在Resolve View时的顺序,具体的做法是设置ViewResolver的order属性,这个属性的值越小代表具有越高的优先级;
    11. ContentNegotiatingViewResolver并不负责将一个View Name解析为一个View对象,它只负责根据Request决定客户端需要什么类型的Response,然后再委托给其他的ViewResolver处理,因此ContentNegotiatingViewResolver应在其他所有的ViewResolver之前执行,所以它应该具有最高优先级,它一般通过下面两个属性来判断客户端需要的内容:
      • 用户请求的URL中的扩展名;
      • 用户请求中的HTTP Accept Header。
    12. Exception Resolver和ContentNegotiatingViewResolver相似,它并不负责将一个View Name解析为一个View对象,它仅仅做的是根据Handler Method中抛出的异常返回一个View Name,然后再委托给其他的ViewResolver处理;你可以创建一个自定义的Exception Resolver,它必须实现自HandlerExceptionResolver接口,Spring MVC提供了一个内置的SimpleMappingExceptionResolver,这个类的ExceptionMappings属性允许你去配置映射不同的异常类型到不同的视图,如果某个异常类型不在这个映射中,你可以通过它的defaultErrorView属性指定一个默认的视图名;
      在视图页面,异常能通过能通过变量${exception}来访问;
      为了将Exception Resolver注册到Spring Container中,我们需要让配置类继承自WebMvcConfigurerAdapter,然后通过复写configureHandlerExceptionResolvers方法把Exception Resolver注册到这个添加到这个方法的参数里;
      注意,通过Exception Resolver方式能捕获Spring Container中所有Handler Method抛出的异常,如果仅仅想针对某一个Controller中所有Handler Method抛出的异常,我们可以在Controller中创建一个public方法,并标记上@ExceptionHandler annotation,这个annotation中可以指定要捕获的异常,如果不指定,则默认是所有异常;这个Public方法可以包含一个异常类型的参数,并返回一个字符串值,用于指定异常发生后要渲染的View Name;尽管使用@ExceptionHandler标记方法是非常的灵活和强大,但是缺点是你不得不把他们放在Controller里,并且仅仅针对controller中的Handler Method有效;如果我们想让它对其它所有的Controller中的Handler Method起作用,我们可以将它们提取到一个标记有@ControllerAdvice annotation的类中;
  • 相关阅读:
    目前加尼福尼亚自动驾驶公司测试公司————20150529
    DDR3
    Linux mysql 5.7: ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
    macOS 10.12,解决如何打开隐私中的任何来源方法
    git查看某个文件的提交历史
    ios-deploy命令
    sed简用
    啊,栈溢出了
    二叉树题目总结(一)
    线段树(二)
  • 原文地址:https://www.cnblogs.com/cdutedu/p/4779394.html
Copyright © 2011-2022 走看看