SessionLocaleResolver
SessionLocaleResolver保存客户的Locale到HttpSession对象中,并且支持获取和修改。它提供了在cookie中保存Locale状态的一个很好的替代方案。与CookieLocaleResolver一样,如果在会话中没有找到Locale,该类将回退调用HttpServletRequest的getLocale()方法。
这种实现(见代码清单5-37)和CookieLocaleResolver一样容易声明。
代码清单5-37 SessionLocaleResolver bean
使用代码清单5-35中的配置,无论客户通过它的首部传播什么,框架都会强制locale为en。
你可能注意到defaultLocale属性是java.util.Locale类型的,但是我们在上述配置中只指定了字符串en。Spring会用它的LocaleEditor属性编辑器将字符串转换成一个完整的Locale实例。LocaleEditor是Spring默认创建和注册的许多属性编辑器之一。
提示
Spring对JavaBean规范中的PropertyEditors的使用非常广泛。请花些时间学习Spring所提供的编辑器(第6章中的一部分)。
如果你的应用程序需要给每个用户提供他们自己唯一的体验,FixedLocaleResolver很快就会失去作用。使用默认的类AcceptHeaderLocaleResolver(虽然它提供了个性化的体验),应用程序就没有办法改变它的值。有另外的LocaleResolver两种实现允许应用程序为用户改变Locale,CookieLocaleResolver和SessionLocaleResolver,这两种实现都支持跨请求改变和保存Locale。
CookieLocaleResolver
CookieLocaleResolver通过浏览器的cookie设置和取得Locale对象。这种策略在应用程序不支持会话或者状态必须保存在客户端时有用。
请在ApplicationContext中声明这个类并使用它。值得注意的是,可以选择配置cookie的名称,但是该类提供了一个明智的默认值。如果希望清除Localecookie,只需调用setLocale()并传递一个null locale即可。
代码清单5-36包含一个CookieLocaleResolver的bean定义例子。
代码清单5-36 CookieLocaleResolver bean定义
注解
如果没有Localecookie存在,该类将后退调用ServletRequest的getLocale()方法。这个getLocale()方法返回客户首选的Locale,与Accept-LanguageHTTP首部中指定的一样,如果客户没有指定一个Accept-LanguageHTTP首部,该方法返回一个服务器默认的Locale。
SessionLocaleResolver
SessionLocaleResolver保存客户的Locale到HttpSession对象中,并且支持获取和修改。它提供了在cookie中保存Locale状态的一个很好的替代方案。与CookieLocaleResolver一样,如果在会话中没有找到Locale,该类将回退调用HttpServletRequest的getLocale()方法。
这种实现(见代码清单5-37)和CookieLocaleResolver一样容易声明。
代码清单5-37 SessionLocaleResolver bean
小结
那么选择使用何种区域管理策略呢?这完全取决于应用系统的需求是什么,通常,Spring不会强加任何决定给你。事实上,如果上述策略的实现不能满足需求,用LocaleResolver接口来创建一个定制的实现也很简单。
提示
不要被所提供的解决方案和实现所约束。很多时候,还存在着方便定制化的接口或者抽象类。
如果应用程序不允许用户改变它们的Locale,但是你承认浏览器的默认设置,那就坚持默认的AcceptHeaderLocaleResolver。该策略仿效Servlet规范的默认行为,不需要配置。这种选择并不出乎意料,因为它就像大多数人所期望的那样执行。
如果需要强制一个特殊的Locale并且它不能改变,那么FixedLocaleResolver很合适。这个类的设置非常简单,但是很受限制。
当应用程序要求用户从Web应用程序内改变Locale的时候,可以选择CookieLocaleResolver或SessionLocaleResolver。如果应用程序已经使用会话那么SessionLocaleResolver是一个合理的选择。但是,如果需要Locale选择保持时间超过会话的生命周期,那么CookieLocaleResolver是唯一的选择。这里没有明显的赢家,所以你应该选择最适合情形的选项。
6. MultipartResolver
处理文件上传是Web框架的标准特性,Spring MVC的org.springframework.web.multipart.MultipartResolver为该功能提供了策略接口。像许多其他特性一样,当进行文件上传处理时,Spring不会去"重新发明轮子"。Spring提供了两种开箱即用的MultipartResolver实现,一种使用JakartaCommons的FileUpload(http://jakarta.apache.org/commons/fileupload),另一种使用JasonHunter的COS(http://www.servlets.com/cos)。
提示
COS代表com.oreilly.servlet,因为该库最初是为Jason Hunter的Java SerlvetProgramming(O'Reilly, 2001)而写的。
HTTP文件上传,或者叫"HTML中的基于表单文件上传",定义于RFC 1867(http://www.ietf.org/rfc/rfc1867.txt)。通过创建HTML输入字段type="file",并且设置表单的enctype="multipart/form-data",浏览器就能将文本或二进制文件作为HTTP POST请求的一部分发送到服务器。
DispatcherServlet会在ApplicationContext中寻找名为multipartResolver的单独bean。若发现一个,它就会将每个进入的请求传递到解析器,以便用能够暴露上传文件功能的子类来包装HttpServletRequest。若未找到多部分解析器,就无法进行多部分文件处理。要注意的是,DispatcherServlet并不将MultipartResolvers串连起来。
与前述的解析器(如LocaleResolver)不同,客户代码从来不用于与该接口直接作用。DispatcherServlet管理MultipartResolver的工组流,客户代码只要将请求对象转换到org.springframework.web.multipart.MultipartHttpServletRequest包装对象,就可以获取上传文件。
代码清单5-38包含MultipartResolver接口。
代码清单5-38 MultipartResolver接口
DispatcherServlet调用isMultipart()方法,以决定引入请求是否是一个多部分请求。该实现很可能要检查请求的Content-Type以查找是否值为multipart/form-data,但这只是探索的一部分。
如果请求确实包含上传的文件,那么调用resolveMultipart()方法,返回MultipartHttp-ServletRequest(见代码清单5-39)。该包装对象添加方法来取得上传文件。
参考:http://blog.sina.com.cn/s/blog_6b9bfcfa0100n7gj.html