Spring MVC + Velocity實現國際化配置


本示例已升級到Spring Boot 2.x

源碼地址:https://github.com/smltq/spring-boot-demo/tree/master/template-thymeleaf

國際化介紹

web開發中,國際化是需要考慮的一個問題,而且這個問題一般是越早敲定越好(不然等到系統大了,翻譯是個問題).下面是結合實際項目(Spring MVC+Velocity)對實現國際化的一些總結.github地址

Spring國際化

I18N:作為"國際化"的簡稱,其來源是英文單詞internationalization的首末字符i和n,18為中間的字符數.

Spring做國際化的配置主要有3個關鍵點:

  1. ResourceBundleMessageSource:實現國際化資源的定義.
  2. LocaleResolver:實現本地化信息的解析.
  3. LocaleChangeInterceptor:實現本地化信息的監聽(來實現url參數動態指定locale).

LocaleResolver

LocaleResolver是指用什么策略來檢測請求是哪一種locale,Spring MVC提供了一下幾種策略:

AcceptHeaderLocaleResolver

根據瀏覽器Http Header中的accept-language域判定瀏覽器的語言環境,可以通過HttpServletRequest.getLocale獲得域的內容,但是無法調用LocaleResolver接口的setLocale設置locale.基於這個策略,在后面的demo中可以實現基於瀏覽器的國際化案例.

SessionLocaleResolver

根據用戶本次會話過程中的語言設定決定語言種類,session級別的,在此session周期內可以修改語言種類,但是session失效后,語言設定失效.基於這個策略,在后面的demo中可以實現基於session的國際化案例.

CookiedLocaleResolver

根據Cookie判定用於的語言設定(Cookie中保存着用戶前一次的語言設定參數).

FixedLocaleResolver

一直使用固定的Locale,改變locale是不支持的.
如果需要使用哪一種策略,只需要在DispatcherServlet制定的Spring配置文件中配置就行,DispatchServlet將在初始化的時候調用initLocaleResolver(context)方法去配置文件中找名字為localeResolver的bean,如果有就使用配置文件的,沒有就使用默認的AcceptHeaderLocaleResovler
通過上面,了解了Spring實現國際化的相關概念,下面結合demo實例,看看Spring MVC是如何實現國際化的

  • 配置文件
    <!--國際化配置 start-->
    <bean id="messageSource"
          class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="classpath:i18n/messages"/>
        <property name="defaultEncoding" value="UTF-8"/>
    </bean>

    <bean id="localeChangeInterceptor"
          class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
        <property name="paramName" value="lang"/>
    </bean>

    <!--語言選擇-->
    <bean id="localeResolver"
          class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
        <property name="defaultLocale" value="en"/>
    </bean>
    <!--國際化配置 end-->
  • demo里准備兩份語言文件分別是messages_cn.properties和messages_en.properties,內容分別如下:
Hello=Hello
HelloWorld=Hello World
SpringMvcBootstrap=Spring MVC Bootstrap
Greetings=I deeply greet you!
Hello=你好,現在是中文版
HelloWorld=你好,現在是中文版
SpringMvcBootstrap=中文版頭部
Greetings=中文版歡迎你
  • 前端界面通過使用spring針對不同view視圖提供的標記處理國際化信息.velocity標記,比如demo中的hello.vm文件
#define($content)
    #springMessage("Hello")
#end
  • 最后運行結果會根據defaultLocale的配置顯示英語版本或中文版本,顯示效果如下:

  • 以上配置示例是基於Cookie的國際化實現,國際化根據實際需求,實現方式有很多比如:

    • 基於瀏覽器請求的國際化
    • 基於Session的國際化實現
    • 基於ULR請求的國際化實現

Velocity簡單使用

  • pom.xml增加Velocity 依賴
        <!-- Velocity 依賴 -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-tools</artifactId>
            <version>2.0</version>
        </dependency>
  • xml增加模板引擎配置
    <!--模板引擎配置 start-->
    <bean id="velocityConfig"
          class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
        <property name="configLocation">
            <value>/WEB-INF/velocity/velocity.properties</value>
        </property>
    </bean>

    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
        <property name="cache" value="false"/>
        <property name="layoutUrl" value="/layout/main.vm"/>
        <property name="prefix" value="/templates/"/>
        <property name="suffix" value=".vm"/>
        <property name="exposeSpringMacroHelpers" value="true"/>
        <property name="contentType" value="text/html;charset=UTF-8"/>
        <property name="viewClass" value="org.springframework.web.servlet.view.velocity.VelocityLayoutView"/>
    </bean>
    <!--模板引擎配置 end-->
  • controller代碼,hello方法會顯示hello.vm內容,helloWorld方法顯示hello-world.vm內容,入口是main.vm
@Controller
public class HelloWorldController {

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello() {
        return "hello";
    }

    @RequestMapping(value = "/hello-world", method = RequestMethod.GET)
    public String helloWorld() {
        return "hello-world";
    }

    @RequestMapping(value = "/hello-redirect", method = RequestMethod.GET)
    public String helloRedirect() {
        return "redirect:/hello-world";
    }

}
  • 我們看看main.vm代碼
<!doctype html>
<html>
<head>
    <title>$!page_title</title>
    <link href="#springUrl('/resources/css/reset.css')" rel="stylesheet" type="text/css"/>
    <link href="#springUrl('/resources/css/style.css')" rel="stylesheet" type="text/css"/>
</head>
<body>
<article>
    <header>#parse('/layout/header.vm')</header>
    <section>$!content</section>
    <footer>#parse('/layout/footer.vm')</footer>
</article>
</body>
</html>

SpringMVC和REST服務API的基本用法示例

  • pom.xml增加json和xml依賴
        <!-- JSON 轉換器 -->
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.5.3</version>
        </dependency>
        <!-- XML 轉換器 -->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.0</version>
        </dependency>
  • controller代碼
@Controller
public class UserServiceController {

    @RequestMapping(value = "/user/{name}/{surname}.json", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody
    User getUserJson(@PathVariable String name, @PathVariable String surname) {
        User user = new User(name, surname);
        return user;
    }

    @RequestMapping(value = "/user/{name}/{surname}.xml", method = RequestMethod.GET, produces = MediaType.APPLICATION_XML_VALUE)
    public @ResponseBody
    User getUserXml(@PathVariable String name, @PathVariable String surname) {
        User user = new User(name, surname);
        return user;
    }
}

@XmlRootElement(name = "user")
public class User {

    private String name;

    private String surname;

    public User() {

    }

    public User(String name, String surname) {
        super();
        this.name = name;
        this.surname = surname;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }
}
  • json數據結果

瀏覽器輸入http://localhost:9080/testweb/user/tq/lin.json,結果顯示如下:

{
    name: "tq",
    surname: "lin"
}
  • xml數據結果

瀏覽器輸入http://localhost:9080/testweb/user/tq/lin.xml,結果顯示如下:

<user>
    <name>tq</name>
    <surname>lin</surname>
</user>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM