文档章节

php/Java Web国际化的联合解决方案

IamOkay
 IamOkay
发布于 2014/10/26 11:38
字数 1499
阅读 83
收藏 0

1.在php开发项目中,往往没有固定而有效的国际化方案,通常是由数组来实现的,其原理是通过php文件名(如zh-cn.php,zh-tw.php,en-us.php,en.php,zh.php)或者自定义的某些规则进行匹配。

无论在php还是Java中,初始化(默认)语言指定一般通过读取浏览器环境变量或者系统信息来实现的

下面是一张http请求头,注意请求参数appcept-Language

php中

<?php
header("content-type:text/html; charset=utf-8");

echo '<br />'.$_SERVER['HTTP_ACCEPT_LANGUAGE'].'<br />';
//一般使用getallheaders()返回的数组遍历请求同,显然这里的变量经过了处理
if(strrpos(strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE']), 'zh-cn') !== false) {
    echo '<br />你的是中文操作系统<br />';
}
else
{
    echo '<br />非中文操作系统<br />';
}
?>

java中


String lang = request.getHeader("accept-language");
boolean isZh_CN = Pattern.compile("(zh|cn)+",Pattern.CASE_INSENSITIVE).matcher(lang).matches();

我们看到,他们都通过获取accept-language来得到,PHP中的 HTTP_ACCEPT_LANAGUAGE是经过封装后显示的 ,可以使用php内置函数getallheaders来获取所有请求同信息,原理也很简单


if (!function_exists('getallheaders')) 
{ 
    function getallheaders() 
    { 
       foreach ($_SERVER as $name => $value) 
       { 
           if (substr($name, 0, 5) == 'HTTP_')   { 
               $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value; 
           } 
       } 
       return $headers; 
    } 
}



2.上面的数据流程是静态的,在一个项目或框架中这样做无法实现更多语言的设计,因此需要一种灵活的映射来完成这项任务

注意:国际化设置往往需要设置服务器响应数据的编码类型,一般设置为utf-8

php

<?php
header("text/html;charset=utf-8");
?>

java

request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
java web.xml中可以使用filter或者其他框架来设置编码


public class CharacterEncodingFilter implements Filter{

private String encoding = "utf-8"; 
	
public void doFilter(ServletRequest request,ServletResponse response,
	FilterChain chain)throws IOException,ServletException{
	request.setCharacterEncoding(encoding);
	request.setCharacterEncoding(encoding);
	response.setCharacterEncoding(encoding);
	//传递控制到下一个过滤器
	chain.doFilter(request, response);
}

@Override
public void destroy() {
	
}

@Override
public void init(FilterConfig config) throws ServletException 
{
	encoding = config.getInitParameter("encoding")!=null?config.getInitParameter("encoding"):encoding;
}

}

web.xml


<filter>
<filter-name>CharacterEncoding</filter-name>
<filter-class>hello.SetCharacterEncodingFilter</filter-class>
 <init-param>
    	<param-name>encoding</param-name>
    	<param-value>utf-8</param-value>
  </init-param>
</filter>

<filter-mapping>
<filter-name>CharacterEncoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

如果使用了Spring或者Struts框架,需要如下设置方式了


 <listener>
 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>

<filter>
		<filter-name>CharacterFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>


如果采用了SpringMVC控制器,在这里需要注意,SpringMVC默认使用JSON传递数据,因此必须设置编码,下面是springmvc的配置文件


 <mvc:annotation-driven>
		<mvc:message-converters register-defaults="true">
			<bean class="org.springframework.http.converter.StringHttpMessageConverter">
				<property name="supportedMediaTypes">
					<list>
						<value> text/plain;charset=UTF-8</value>
						<value> application/json;charset=UTF-8</value>
						<value> application/xml;charset=UTF-8</value>
					</list>
				</property>
				<constructor-arg name="defaultCharset" value="utf-8"/>
			</bean>
		</mvc:message-converters>
	</mvc:annotation-driven>

如果采用的是struts2控制器需要在struts2配置配置文件中设置

<constant name="struts.i18n.encoding" value="utf-8" />



说道这里,编码问题基本解决了,至于ThinkPHP的编码,默认是utf-8,完全不用设置,如果想尝试一下改变,可以再thinkphp的conf/有具体文件设置,或者在项目配置目录文件中设置 DEFAULT_CHARSET =>'utf-8'即可。

另外提一下python+django,python3.x语言默认使用unicode字符集,Django也是默认的使用utf-8,如果觉得好玩儿的话可在settings.py中进行设置。

3.编码配置完成,下面进行映射

<?php
   //导入语言库(注意,导入的必须是key/value明确的数组)
  $zh = include_once('xxx/zh.php');
  $zh_cn = include_once('xxx/zh_cn.php');
  $zh_tw = include_once('xxx/zh_tw.php');
  $en_us = include_once('xxx/en_us.php');
  $en_uk = include_once('xxx/en_uk.php');
  //简历语言库映射
  $lang = array(
     'zh' => %zh,
     'zh_cn'=>$zh_cn,
     'zh_tw'=>$zh,
.....
  );
//这里使用zh/en来表示说这些语言的地区,范围更广,一般把相同的数据放在这里面


?>


//一下是一个简答的语言库(zh_cn.php)
<?php

 return array('name'=>'姓名',
   'gender'=>'性别'
   ....
 );

?>



当然要想访问上面的数据,那么就需要根据accept-language来判断是什么语言了,判断出来假设

$local = 'zh_cn';

然后调用方式为

$lang[$local]

上面的是普通php要做的,在thinkphp中在项目目录下有一个/lang的文件夹,只需创建zh_cn/common.php,en_us/common.php等语言库,然后就可以在模板中调用了

{$Think.lang.lan_subject}

问题来了,如果要切换语言怎么办,还用问,当然是使用 cookie/session/url里面带的参数来判断了,比如说thinkphp的语言切换参数是 l?输入http://hostname:[port]/xxx/xx.php?l=zh_cn,如果你自己使用的话也可以使用自己的参数,比如local什么的。

问题又来了,某些页面如果没经过controller过滤怎么办?使用javascript的json数据是首选,当然html5支持本例离线缓存等也可以使用,这里不多说。


java web 国际化

java web国际化某些方面和php相同,比如使用json等

在某些时候,推荐使用servlet自带的国际化标签,关于format标签的使用,首先需要在web.xml中进行配置

<!-- Jstl支持国际化,国际化文件的前缀名 -->
	<context-param>
		<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
		<param-value>message</param-value>
	</context-param>



然后建立如下语言包(注意以 web.xml中 param-value值为前缀)


然后在jsp页面中使用,首先引入fmt标签库

<%@ taglib prefix='fmt' uri="http://java.sun.com/jsp/jstl/fmt" %>



然后调用
<fmt:message key="Username" />



在struts.xml中开启国际化(在struts.xml中设置)

<constant name="struts.custom.i18n.resources" value="message" />



在一般项目中,往往通过fmt和struts配合使用

在springmvc中这种配合却成了问题,因为springmvc对url的过滤是全覆盖式的,所以不需要担心没有通过controller过滤

在springmvc中国际化,需要进行如下配置

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename">
            <val >message</val >
        </property>
    </bean>



然后使用spring自带的标签库进行调用

<%@taglib uri="http://www.springframework.org/tags" prefix="spring" %>



<spring:message code="welcome" />



结束了,再说一下python+django,需要国际化时可以采用这种方式





© 著作权归作者所有

IamOkay

IamOkay

粉丝 205
博文 483
码字总数 403228
作品 0
海淀
程序员
私信 提问
天乙社区的网友评论

天乙社区是一套基于JAVA技术的网络虚拟社区,采用了Hibernate+Spring+Struts的轻量级J2EE框架,主要特点有: 1、跨平台:天乙社区完全具有java语言跨平台的特性,可以方便的运行在windows、l...

红薯
2009/12/11
1K
14
Apache开源项目分类列表

分类 项目名 说明 开发语言 服务器 (共20) Apache HTTP Server 全球第一HTTP服务器 C/C++ Tomcat Java的Web服务器 Java James 邮件服务器 Java SpamAssassin 反垃圾邮件 C/C++ Perl Apach...

johnnyhg
2009/05/08
2.3K
0
6.24上午10点Terracotta核心技术介绍以及如何搭建高可用的Web应用

简介 Terracotta 是一种为Java应用而设计的基础软件,它为Java 应用程序提供了高可扩展性和可用性等通用特性。通常来说,公司使用Terracotta从数据库和应用服务器削减工作负载,从而减少了它...

lifefitness
2010/06/24
1K
0
【第1章 Spring概述与结构】1.2 Spring模块与结构

上一节:【第1章 Spring概述与结构】1.1 Spring起源与概述 基于Java Beans的配置管理,采用IOC的原理,特别是对依赖注入技术的使用。这些都用来减少各组件间对实施细则的相互依赖性。 一个核...

陶邦仁
2015/05/21
869
0
企业建站系统MiinCMP1.0.5 标准版发布!

2014-5-6日,Juuluu发布其企业建站系统MiinCMP1.0.5 标准版,1.0.5是一款相对成熟的企业网站解决方案.运行MiinCMP1.0.5,只需2M的mysql,50m的java空间,256的内存,即最低的国内IDC配置,MiinCMP网...

聚龙软件
2014/05/06
633
0

没有更多内容

加载失败,请刷新页面

加载更多

GUAVA--基础工具(Throwables)

1、异常传播 有时候,你会想把捕获到的异常再次抛出。这种情况通常发生在 Error 或 RuntimeException 被捕获的时候,你 没想捕获它们,但是声明捕获 Throwable 和 Exception 的时候,也包括了...

MrYuZixian
23分钟前
6
0
电磁兼容入门篇之辐射发射(辐射骚扰)试验

今天我们一起学习的是四个EMI测试项之一:辐射发射(RE),较前两篇相比的话,今天可能会有一点点深度,不过不用担心,我们先做一个了解,等到测试时或测试后再回过来结合本文,就能掌握的更...

demyar
35分钟前
4
0
Redis 事务:将一组命令放在同一个事务中进行处理

事务 MULTI 、 EXEC 、 DISCARD 和 WATCH 是 Redis 事务相关的命令。事务可以一次执行多个命令, 并且带有以下两个重要的保证: 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺...

须臾之余
37分钟前
6
0
Spring Boot Tomcat配置项

参数配置容器 server.xx开头的是所有servlet容器通用的配置,server.tomcat.xx开头的是tomcat特有的参数,其它类似。 所有参数绑定配置类:org.springframework.boot.autoconfigure.web.Serv...

xiaomin0322
48分钟前
7
0
微课程 | 第二课《Docker 安装方式介绍》

微课程 | 第二课《Docker 安装方式介绍》视频 https://v.youku.com/v_show/id_XNDQ0NDUzNjkxNg==.html?spm=a2hzp.8244740.0.0 上一期我们介绍了 DBLE 的基本概况,下面进入我们的正题,正题基...

爱可生
48分钟前
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部