java中的Propertise用来做键值对应是很方便的。但是不足也是明显的,那就是它对中文的支持不好。从jdk的src中可以看到这个类它使用了8859作为输入编码。呵呵 硬编码哦,厉害!!
其实解决的方法很简单的。就是写一个类来继承自Propertise。下面这个类是ejbca项目中的一个类。
/*************************************************************************
* *
* EJBCA: The OpenSource Certificate Authority *
* *
* This software is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or any later version. *
* *
* See terms of license at gnu.org. *
* *
*************************************************************************/
package se.anatom.ejbca.webdist.webconfiguration;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class LanguageProperties extends java.util.Properties {
private static final String keyValueSeparators = "=: /t/r/n/f";
private static final String strictKeyValueSeparators = "=:";
private static final String specialSaveChars = "=: /t/r/n/f#!";
private static final String whiteSpaceChars = " /t/r/n/f";
public synchronized void load(InputStream inStream) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(inStream));//就是这里了。sun的是8859的硬编码的。
while (true) {
String line = in.readLine();
if (line == null) {
return;
}
if (line.length() > 0) {
// Continue lines that end in slashes if they are not comments
char firstChar = line.charAt(0);
if ( (firstChar != '#') && (firstChar != '!')) {
while (continueLine(line)) {
String nextLine = in.readLine();
if (nextLine == null) {
nextLine = "";
}
String loppedLine = line.substring(0, line.length() - 1);
// Advance beyond whitespace on new line
int startIndex = 0;
for (startIndex = 0; startIndex < nextLine.length(); startIndex++) {
if (whiteSpaceChars.indexOf(nextLine.charAt(startIndex)) == -1) {
break;
}
}
nextLine = nextLine.substring(startIndex, nextLine.length());
line = new String(loppedLine + nextLine);
}
// Find start of key
int len = line.length();
int keyStart;
for (keyStart = 0; keyStart < len; keyStart++) {
if (whiteSpaceChars.indexOf(line.charAt(keyStart)) == -1) {
break;
} }
// Blank lines are ignored
if (keyStart == len) {
continue;
}
// Find separation between key and value
int separatorIndex;
for (separatorIndex = keyStart; separatorIndex < len; separatorIndex++) {
char currentChar = line.charAt(separatorIndex);
if (currentChar == '//') {
separatorIndex++;
}
else if (keyValueSeparators.indexOf(currentChar) != -1) {
break;
}
}
// Skip over whitespace after key if any
int valueIndex;
for (valueIndex = separatorIndex; valueIndex < len; valueIndex++) {
if (whiteSpaceChars.indexOf(line.charAt(valueIndex)) == -1) {
break;
}
}
// Skip over one non whitespace key value separators if any
if (valueIndex < len) {
if (strictKeyValueSeparators.indexOf(line.charAt(valueIndex)) != -1) {
valueIndex++;
// Skip over white space after other separators if any
}
}
while (valueIndex < len) {
if (whiteSpaceChars.indexOf(line.charAt(valueIndex)) == -1) {
break;
}
valueIndex++;
}
String key = line.substring(keyStart, separatorIndex);
String value = (separatorIndex < len) ?
line.substring(valueIndex, len) : "";
// Convert then store key and value
key = loadConvert(key);
value = loadConvert(value);
put(key, value);
}
}
}
}
/*
* Returns true if the given line is a line that must
* be appended to the next line
*/
private boolean continueLine (String line) {
int slashCount = 0;
int index = line.length() - 1;
while((index >= 0) && (line.charAt(index--) == '//'))
slashCount++;
return (slashCount % 2 == 1);
}
/*
* Converts encoded //uxxxx to unicode chars
* and changes special saved chars to their original forms
*/
private String loadConvert (String theString) {
char aChar;
int len = theString.length();
StringBuffer outBuffer = new StringBuffer(len);
for(int x=0; x<len; ) {
aChar = theString.charAt(x++);
if (aChar == '//') {
aChar = theString.charAt(x++);
if(aChar == 'u') {
// Read the xxxx
int value=0;
for (int i=0; i<4; i++) { aChar
= theString.charAt(x++);
switch (aChar) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
value =
(value << 4) + aChar - '0';
break;
case 'a': case 'b': case 'c':
case 'd': case 'e': case 'f':
value = (value << 4) + 10 + aChar - 'a';
break;
case 'A': case 'B': case 'C':
case 'D': case 'E': case 'F':
value = (value << 4) + 10 + aChar - 'A';
break; default:
throw new IllegalArgumentException("Malformed //uxxxx encoding.");
}
}
outBuffer.append((char)value); } else {
if (aChar == 't') aChar = '/t';
else if (aChar == 'r') aChar = '/r';
else if (aChar == 'n') aChar = '/n';
else if (aChar == 'f') aChar = '/f';
outBuffer.append(aChar);
}
} else
outBuffer.append(aChar);
}
return outBuffer.toString();
}
}
在你的Properties中有中文的时候可以导入这个类了。
下面是个具体例子:
1。 下面这个类调用了一个属性文件,取APPSERVMUSTBERUNNING所对应的键值(当然了是中文)。
Install.java
package aranjuez.test;
import java.util.*;
import java.io.*;
import aranjuez.util.MyPropertises;
public class Install{
private MyProperties text;//MyPropertise就是上面那个类了,我只是改改名字
public Install(String language)throws Exception {
text = new MyProperties();
text.load(this.getClass().getResourceAsStream("/" + "install." + language.toLowerCase() + ".properties"));
//text.load(new FileInputStream("install."+ language+".properties"));
}
public static void main(String[] args) throws Exception {
Install install = new Install("zh");
install.run();
}
private void run(){
System.out.print(text.getProperty("APPSERVMUSTBERUNNING"));
}
}
2.下面的文件就是那个Properties文件install.zh.properties
APPSERVMUSTBERUNNING=请确认已经启动了application server(JBoss)
3.aranjuez.util.MyPropertises文件就是上面的类了,改改包名就行了
运行Install则能看到:
请确认已经启动了application server(JBoss)
修改Install,使语言类型为参数就可以做出一个多语言的安装包了