SpringMVC源代码学习(五)九大组件下
来源:互联网 发布:华为网管软件 告警 编辑:程序博客网 时间:2024/06/05 09:33
以下内容基于书:《看透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.propertieslogo.pic=/images/default/logo.jpglogo.word=excelibstyle=/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传递参数的。
- http://blog.csdn.net/xia4820723/article/details/51345559 SpringMVC源代码学习外传(二)如何在重定向时传递参数&FlashMap。 ↩
- SpringMVC源代码学习(五)九大组件下
- SpringMVC源代码学习(四)九大组件上
- SpringMVC源代码学习(四)九大组件
- springmvc九大组件之HandlerMapping
- 学习SSM框架笔记五:利用五大组件采取配置文件和SpringMVC模式写HelloWorld
- SpringMVC的九大组件完成的任务粗解。
- Android学习笔记之----初识四大(五大)组件
- SpringMVC学习 (五)
- springMVC五大组件案例--生成系统时间
- 深度学习框架五大组件
- SpringMVC学习笔记(九)
- PMP学习笔记(二):九大知识领域和五大过程组
- SpringMVC 9大组件
- SpringMVC学习笔记(五)
- android五大组件
- 五大基本组件
- 3五大组件
- Android五大组件
- Java - PAT - 1023. 组个最小数 (20)
- 实用正则表达式
- Demo_对应条目置顶
- 动态规划1006
- [bzoj 1600]建造栅栏 递推
- SpringMVC源代码学习(五)九大组件下
- 数字滤波算法汇集
- 袁腾飞——秦国
- 118.[Leetcode]Pascal's Triangle
- 最新Eclipse TomCat 进行JRebel热部署插件安装、破解及配置
- iOS开发之沙盒机制
- Struts2中使用Session的两种方法
- 袁腾飞——汉
- 在字符串中找出连续最长的数字串