js国际化

转载 2017年12月12日 05:52:57

  在Java项目中,尤其是WEB项目中,一般都是通过Struts框架的特性进行国际化的。
  在采用Struts的项目架构中,借用Struts的的国际化标签等特性,可以非常方便的对jsp文件及action类文件进行国际化。但是,在一个面向大众用户的, 开放的WEB应用中,通常有非常多的js文件,如何对js文件进行国际化呢?
在互联网上,通过baidu,google,查找,对js国际化的方法一般是:
  jsp页面中,通过判断客户端的Locale(request.getLocale()),加载不同语言的js文件,对图片的处理方法也是类似。不同语言 的js文件,内容上基本一致,只是把需要显示的文字翻译成不同语言的文字。缺点:不是真正的国际化,如果需要100个国家语言的用户访问,就得需要的 100个js文件。
  对于jsp文件,是通过struts国际化标签,在服务器端根据locale输出特定Locale的消息。因此,设想,js文件,能够也通过后台输出特定locale国际化的消息。

基本理论就是:

  借用ajax,struts技术,js需要国际化的消息,通过ajax技术,通过后台输出,后台处理方式完全和jsp,action类中的处理方式一致.

详细代码实现:

系统采用的框架:struts2.1.6 + spring+hibernate+dwr2.06.
其中dwr是个ajax框架,封装了ajax的调用。

  • js需要请求国际化的消息,必然要和服务器交互,也即通过js调用java类中的方法,这可以通过dwr实现。
    java类:
    JSActionSupport.java
/*
 * Copyright (c) 2002-2006 by OpenSymphony
 * All rights reserved.
 */
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.Serializable;
import java.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;

import javax.servlet.http.HttpServletRequest;


/**
 * 这个类实际上就是struts2中的ActionSupport类的修改,主要修改了getLocale方法,目的是通过ajax调用,获取ajax请求中的locale。同时增加了2个方法 getMsg,getMsgs,用与暴露给js远程调用。
 * JS ActionSupport for get the International message
 * @see ActionSupport class
 */
public class JSActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable {

    protected static Log LOG = LogFactory.getLog(ActionSupport.class);

    private final transient TextProvider textProvider = new TextProviderFactory().createInstance(getClass(), this);
    private final ValidationAwareSupport validationAware = new ValidationAwareSupport();
    /**
     * Get the International Message by the key
     * @param key
     * @return
     */
    public String getMsg(String key) {
        return this.getText(key);
    }
    /**
     * Get the International Message by key collection
     * @param key
     * @return
     */
    public List < String > getMsgs(List < String > key) {
        List < String > result = new ArrayList < String > ();
        for (String temp: key) {
            result.add(this.getMsg(temp));
        }
        return result;
    }

    public void setActionErrors(Collection errorMessages) {
        validationAware.setActionErrors(errorMessages);
    }

    public Collection getActionErrors() {
        return validationAware.getActionErrors();
    }

    public void setActionMessages(Collection messages) {
        validationAware.setActionMessages(messages);
    }

    public Collection getActionMessages() {
        return validationAware.getActionMessages();
    }

    /**
     * @deprecated Use {@link #getActionErrors()}.
     */
    public Collection getErrorMessages() {
        return getActionErrors();
    }

    /**
     * @deprecated Use {@link #getFieldErrors()}.
     */
    public Map getErrors() {
        return getFieldErrors();
    }

    public void setFieldErrors(Map errorMap) {
        validationAware.setFieldErrors(errorMap);
    }

    public Map getFieldErrors() {
        return validationAware.getFieldErrors();
    }

    /**
     * 重写了这个方法,获取ajax请求中的locale,stuts2中的类会调用此方法。
     * Get Locale from dwr request
     */
    public Locale getLocale() {
        //return ActionContext.getContext().getLocale();
        WebContext webCxt = WebContextFactory.get();
        HttpServletRequest request = webCxt.getHttpServletRequest();
        Locale result = request.getLocale();
        return result;
    }

    public String getText(String aTextName) {
        return textProvider.getText(aTextName);
    }

    public String getText(String aTextName, String defaultValue) {
        return textProvider.getText(aTextName, defaultValue);
    }

    public String getText(String aTextName, String defaultValue, String obj) {
        return textProvider.getText(aTextName, defaultValue, obj);
    }

    public String getText(String aTextName, List args) {
        return textProvider.getText(aTextName, args);
    }

    public String getText(String key, String[] args) {
        return textProvider.getText(key, args);
    }

    public String getText(String aTextName, String defaultValue, List args) {
        return textProvider.getText(aTextName, defaultValue, args);
    }

    public String getText(String key, String defaultValue, String[] args) {
        return textProvider.getText(key, defaultValue, args);
    }

    public String getText(String key, String defaultValue, List args, ValueStack stack) {
        return textProvider.getText(key, defaultValue, args, stack);
    }

    public String getText(String key, String defaultValue, String[] args, ValueStack stack) {
        return textProvider.getText(key, defaultValue, args, stack);
    }

    public ResourceBundle getTexts() {
        return textProvider.getTexts();
    }

    public ResourceBundle getTexts(String aBundleName) {
        return textProvider.getTexts(aBundleName);
    }

    public void addActionError(String anErrorMessage) {
        validationAware.addActionError(anErrorMessage);
    }

    public void addActionMessage(String aMessage) {
        validationAware.addActionMessage(aMessage);
    }

    public void addFieldError(String fieldName, String errorMessage) {
        validationAware.addFieldError(fieldName, errorMessage);
    }

    public String input() throws Exception {
        return INPUT;
    }

    public String doDefault() throws Exception {
        return SUCCESS;
    }

    /**
     * A default implementation that does nothing an returns "success".
     * <p/>
     * Subclasses should override this method to provide their business logic.
     * <p/>
     * See also {@link com.opensymphony.xwork2.Action#execute()}.
     *
     * @return returns {@link #SUCCESS}
     * @throws Exception  can be thrown by subclasses.
     */
    public String execute() throws Exception {
        return SUCCESS;
    }

    public boolean hasActionErrors() {
        return validationAware.hasActionErrors();
    }

    public boolean hasActionMessages() {
        return validationAware.hasActionMessages();
    }

    public boolean hasErrors() {
        return validationAware.hasErrors();
    }

    public boolean hasFieldErrors() {
        return validationAware.hasFieldErrors();
    }

    /**
     * Clears all errors and messages. Useful for Continuations and other situations
     * where you might want to clear parts of the state on the same action.
     */
    public void clearErrorsAndMessages() {
        validationAware.clearErrorsAndMessages();
    }

    /**
     * A default implementation that validates nothing.
     * Subclasses should override this method to provide validations.
     */
    public void validate() {}

    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    /**
     * <!-- START SNIPPET: pause-method -->
     * Stops the action invocation immediately (by throwing a PauseException) and causes the action invocation to return
     * the specified result, such as {@link #SUCCESS}, {@link #INPUT}, etc.
     * <p/>
     *
     * The next time this action is invoked (and using the same continuation ID), the method will resume immediately
     * after where this method was called, with the entire call stack in the execute method restored.
     * <p/>
     *
     * Note: this method can <b>only</b> be called within the {@link #execute()} method.
     * <!-- END SNIPPET: pause-method -->
     *
     * @param result the result to return - the same type of return value in the {@link #execute()} method.
     */
    public void pause(String result) {}

}
  • 配置dwr(dwr.xml),达到暴露给js远程调用的目的。
      getMsg(String key)可以实现获取单个key的国际化消息,但是一个js文件中,可能文件中的不同地方都需要国际化的消息,而如果通过getMsg(String key),则导致多次ajax请求,增大服务器压力,因此,可以通过集合方式(getMsgs(List key),一个文件中,一次ajax请求,获取该文件中全部的国际化消息。
<dwr>
   <allow>
      <!--International support for js-->
      <create creator="spring" javascript="jsActionSupport">
         <param name="beanName" value="jsActionSupport"/>
         <include method="getMsg"/>
         <include method="getMsgs"/>
         <!-- JSActionSupport类中,仅这2个方法暴露给远程调用-->
      </create>
      <convert converter="list" match="java.util.List"/>
   </allow>
   <signatures>
      <![CDATA[
         import java.util.List;
         import JSActionSupport;
         JSActionSupport.getMsgs(List<String>key);
         ]]> 
   </signatures>
</dwr>

具体的dwr使用与配置,可以参考dwr文档。
   然后可以通过http://localhost/webcontext/dwr/,进行测试dwr是否部署正确。
   编辑资源文件,方法和struts国际化资源文件一样。为了逻辑清晰,可以把专属于js调用的国际化消息单独放在一个资源文件中 (JSActionSupport.properties,JSActionSupport_en.properties),这个资源文件和 JSActionSupport在同一类包中(package)。

客户端js文件编写与调用

example.js文件内容

dwr.engine.setAsync(false);
var jsResult;
var jsPara;
jsPara = ["key1",
    "key2",
    "key3"
];
jsActionSupport.getMsgs(jsPara, function(data) <!-- js远程调用Java方法 -->
    {
        jsResult = data;
    });

function exampleTest() {
        alert(jsResult[0]; alert(jsResult[1];
    }

总结:
国际化的本质都是通过判断客户端请求头携带的locale信息,根据locale输出国际化消息。

参考资料:
1.http://directwebremoting.org/dwr/index.html (可以下载dwr组件及文档,接受了dwr的使用)
2.http://blog.csdn.net/wen1019/article/details/4785190

关于JS内容的国际化

实现页面内容多语言,前面已经提到了,不明白的可移步:http://blog.csdn.net/sutongxuevip/article/details/52605354,今天我们来说下关于js内容的国...
  • sutongxuevip
  • sutongxuevip
  • 2016年12月01日 17:33
  • 2978

一个极端的前端国际化方法

最近一直在做整个页面的国际化,相信很多小伙伴们都做过,前端主要采用的是Angularjs,后端使用的是Spring来做国际化,那么他们的优点,缺点现在一起来总结一下。其实无论用哪种语言做国际化,感觉都...
  • liaodehong
  • liaodehong
  • 2016年08月29日 15:41
  • 5654

springmvc国际化的实现

1.首先是环境的配置,环境配置步奏很简单,只需要在springmvc的配置文件spring-mvc.xml里面配置国际化的内容:                           i18...
  • lzy295481710
  • lzy295481710
  • 2014年01月03日 17:17
  • 1354

利用Intellij+MAVEN+SpringMVC+URI.js实现页面的中英文切换(国际化)

利用Intellij+MAVEN+SpringMVC实现页面的中英文切换(国际化) 一个页面经常会有中英文切换的功能,今天就使用SpringMVC实现一个通过链接实现页面中英文切换的小DEMO。 ...
  • noaman_wgs
  • noaman_wgs
  • 2017年01月02日 22:55
  • 1686

js 国际化实现

  • 2015年05月28日 09:40
  • 1KB
  • 下载

Js国际化插件

  • 2013年06月06日 21:38
  • 2KB
  • 下载

国际化 js插件

  • 2017年10月25日 16:23
  • 15KB
  • 下载

js jquery 国际化 全兼容

  • 2012年02月29日 15:26
  • 26KB
  • 下载

tornado实现在JS文件的国际化和静态文件的引用

在一个tornado的项目中,需要在JS代码文件中也可以实现国际化和static_url()方法来引用静态文件。 而项目中使用了mako的模板引擎,正常情况下只是模板中可以实现国际化和使用static...
  • cloveses
  • cloveses
  • 2016年04月14日 20:51
  • 1131

angular.js 国际化模块 angular-translate 简单方便快捷翻译中英文等多语言环境

很多web服务面对的不仅仅是当地用户,多语言环境不仅能提升逼格,更重要是一种用户体验. angular.js 作为前后端拆分的解决方案之一,当然离不开前端框架处理国际化的问题,a...
  • daniel7443
  • daniel7443
  • 2016年04月15日 11:41
  • 4554
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:js国际化
举报原因:
原因补充:

(最多只允许输入30个字)