zoukankan      html  css  js  c++  java
  • SpringMVC源代码学习(五)九大组件下

    5. RequestToViewNameTranslator

    ViewResolver根据ViewName查找View,但有的Handler处理完并没有设置View,也没有设置viewName,这时就需要从request中获取viewName。也就是RequestToViewNameTranslator的任务。它是个接口,代码如下:

    public interface RequestToViewNameTranslator {
        String getViewName(HttpServletRequest request) throws Exception;
    }

    就像之前说的,他只有一个getViewName方法,能够从request获取到viewName就可以了。下面是一个简单实现的示例:

    if(request.getRequestURI().toString().startsWith("/todou")&&request.getMethod().equalsIgnoreCase("GET"))
        return "maidigua";
    else
        return "404";

    RequestToViewNameTranslator在spring MVC容器中只能配置一个,所以所有request到ViewName的转换规则都要在一个Translator里面实现。

    6. LocaleResolver

    还记得ViewResolver有两个参数,viewname和Locale,viewname来自Handler或RequestToViewNameTranslator。locale变量就来自LocaleResolver。 
    LocaleResolver用于从request解析出Locale。

    Locale就是zh-cn之类的,表示一个区域。有了这个就可以对不同区域的用户显示不同的结果,这就是il18n(国际化)的基本原理。

    LocaleResolver是个接口,代码如下:

    public interface LocaleResolver {
        Locale resolveLocale(HttpServletRequest request);
        void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale);
    
    }

    一共只有两个方法,第一个方法就是起到获取Locale的作用,在介绍doService方法时说过,容器会将localeResolver设置到request的attribute中。 
    代码如下:

    request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE,this.localeResolver);
    

    切换Locale: 
    第二个方法可以将Locale设置到request中。 
    SpringMVC提供了统一修改request中Locale的机制,就是我们在分析doDispatch时见过的Interceptor。SpringMVC已经写好现成的了,配置一下就可以,也就是org.springframework.web.servlet.i18n.LocaleChangeInterceptor. 
    配置方法如:

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/*"/>
            <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
            //这里也可以自定义参数的名称,如:
            //<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang"/>
        </mvc:interceptor>
    </mvc:interceptors>

    这样通过request的locale参数就可以修改Locale了,如:http://localhost:8080?locale=zh_CN 
    http://localhost:8080?locale=en 
    用到Locale的地方有两处,1、ViewResolver解析视图的时候。2、使用到国际化资源或者主题的时候。国际化资源或主题主要使用RequestContext的getMessage和getThemeMessage方法。

    7.ThemeResolver

    它是个接口,源码如下:

    public interface ThemeResolver {
        String resolveThemeName(HttpServletRequest request);
        void setThemeName(HttpServletRequest request, HttpServletResponse response, String themeName);
    }

    SpringMVC中一套主题对应一个properties文件,里面存放着跟当前主题相关的所有资源,如图片、css样式表等,如:

    #theme.properties
    logo.pic=/images/default/logo.jpg
    logo.word=excelib
    style=/css/default/style.css

    SpringMVC跟主题有关的类主要有ThemeResolver、ThemeSource和Theme。 
    1. ThemeResolver的作用是从request解析出主题名。 
    2. ThemeSource的作用是根据主题名找到具体的主题。 
    3. Theme是ThemeSource找出的一个具体的主题。 
    看一下如下代码:

        //org.springframework.web.servlet.support.RequestContext;
        public String getThemeMessage(String code, Object[] args, String defaultMessage) {
            return getTheme().getMessageSource().getMessage(code, args, defaultMessage, this.locale);
        }
        public Theme getTheme() {
            if (this.theme == null) {
                // Lazily determine theme to use for this RequestContext.
                this.theme = RequestContextUtils.getTheme(this.request);
                if (this.theme == null) {
                    // No ThemeResolver and ThemeSource available -> try fallback.
                    this.theme = getFallbackTheme();
                }
            }
            return this.theme;
        }
        //org.springframework.web.servlet.support.RequestContextUtils
        public static Theme getTheme(HttpServletRequest request) {
            ThemeResolver themeResolver = getThemeResolver(request);
            ThemeSource themeSource = getThemeSource(request);
            if (themeResolver != null && themeSource != null) {
                String themeName = themeResolver.resolveThemeName(request);
                return themeSource.getTheme(themeName);
            }
            else {
                return null;
            }
        }

    从RequestContextUtils的代码中就可以看到ThemeResolver和ThemeSource的作用。ThemeResolver的默认实现是org.springframework.web.servlet.theme.FixedThemeResolver 
    在讲SpringMVC容器创建时介绍过WebApplicationContext是在FrameworkServlet中创建的,默认使用的是XmlWebApplicationContext,它的父类是AbstractRefreshableWebApplicationContext,这个类实现了ThemeSource接口,实现方式是在内部封装了一个ThemeSource属性,然后将具体工作交给它。 
    这里可以把ThemeSource理解成一个配置文件,默认使用的是WebApplicationContext。ThemeResolver默认使用的是FixedThemeResolver。这些我们可以自己配置,例如:

    <bean id="themeSource" class="org.springframework.ui.context.support.ResourceBundleThemeSource" p:basenamePrefix="com.excelib.themes."/>
    <bean id="themeResolver" class="org.springframework.web.servlet.theme.CookieThemeResolver" p:defaultThemeName="default"/>

    这里配置了themeResolver,themeSource默认主题名为default,配置文件在comexcelib.themes包下。
    切换Theme:同切换Locale相同,依然是使用Interceptor。配置如下:

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/" />
            <bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor" p:paramName="theme"/>
        </mvc:interceptor>
    </mvc:interceptors>

    可以通过paramName设置修改主题的参数名,默认使用”theme”。下面的请求可以切换为summer主题。

    8.MultipartResolver

    用于处理上传请求,处理方法时将普通的request包装成MultipartHttpServletRequest,后者可以直接调用getFile方法获取File,如果上传多个文件,还可以调用getFileMap得到FileName->File结构的Map,这样就使得上传请求的处理变得非常简单。 
    然后,其实不包装直接用request也可以。所以SpringMVC中此组件没有提供默认值。MultipartResolver代码如下:

    public interface MultipartResolver {
        boolean isMultipart(HttpServletRequest request);//判断是不是上传请求
        MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException;//将request包装成MultipartHttpServletRequest
        void cleanupMultipart(MultipartHttpServletRequest request);//清除上传过程中产生的临时资源
    }

    9.FlashMapManager

    FlashMap在之前的文章1中提到过了,主要用在redirect中传递参数。而FlashMapManager是用来管理FlashMap的,定义如下:

    public interface FlashMapManager {
        FlashMap retrieveAndUpdate(HttpServletRequest request, HttpServletResponse response);//恢复参数,将恢复过的和超时的参数从保存介质中删除;
        void saveOutputFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response);//用于将参数保存起来。
    }

    默认实现是org.springframework.web.servlet.support.SessionFlashMapManager。它将参数保存在session中,实现原理就是利用session作为中转站保存request中的参数,达到redirect传递参数的。

  • 相关阅读:
    .net 笔试面试总结(3)
    .net 笔试面试总结(2)
    .net 笔试面试总结(1)
    依赖注入
    ssh远程连接vm 安装的ubuntu
    ubuntu 安装vm-tool
    go调度: 第二部分-go调度器
    go调度: 第一部分-OS调度(操作系统调度)
    thrift简单示例 (go语言)
    thrift简单示例 (基于C++)
  • 原文地址:https://www.cnblogs.com/fupengpeng/p/7382782.html
Copyright © 2011-2022 走看看