然后 算了, 今天一天好像心情都太平静了, 似乎是没有什么起伏啊, 呵呵呵 倒也正常???, 写下关于 i18n 吧???
老项目, servlet + jsp, 需求是国际化处理
这里着重介绍一下前1, 2, 3 个步骤, 当然 仅供参考
script1. 遍历项目下面的所有需要处理的文件[jsp + js], 二级根据行遍历[当然可以使用相关的xml包来处理, 我这里为了简单就直接一行为单位], 搜索中文字符串script1 核心代码如下 :
@Override
public void consume(String line) {
int len = line.length();
for (int i = 0; i < len; i++) {
// 过滤注释行
if (line.startsWith("//", i)) {
return;
}
if (isChinese(line.charAt(i))) {
int j = i;
for (; j < len; j++) {
if ((!isChinese(line.charAt(j))) && (!isBlank(line.charAt(j)))) {
break;
// int idxOfSpecialTag = idxOfSpecialTag(line, j);
// if(idxOfSpecialTag < 0) {
// break;
// }
//
// j = idxOfSpecialTag;
// continue ;
}
}
// j 到达len, 或者 line[j] 不是中文
String chineseStr = line.substring(i, j);
if (result.add(chineseStr)) {
chineseCounter.incrementAndGet();
}
cnt.incrementAndGet();
if (showChineseInFile) {
info(" 搜索到中文字符串 : [" + chineseStr + "]");
}
i = j;
}
}
}
/**
* 判断给定的字符是否是中文
*
* @param ch ch
* @return boolean
* @author Jerry.X.He
* @date 2018/1/10 12:35
*/
private boolean isChinese(char ch) {
return ch >= '\u4e00' && ch <= '\u9FA5';
}
private boolean isBlank(char ch) {
boolean rangeReturn = (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
|| (ch >= '\uFF00' && ch <= '\uFFEF') || (ch >= '\u3000' && ch <= '\u303F')
|| (ch >= '\uFE10' && ch <= '\uFE1F') || (ch >= '\uFE30' && ch <= '\uFE4F');
if (rangeReturn) {
return rangeReturn;
}
// String specialStr = " \t\b\f\r\n.。,《》%〔〕";
String specialStr = " \t\b\f\r\n.。,《》%〔〕&;-_=@";
return specialStr.contains(String.valueOf(ch));
}
/**
* 添加 fmt:bundle, 需要的标签信息
*
* @param file file
* @return void
* @author Jerry.X.He
* @date 2018/1/11 15:09
*/
private void appendFmtBundle(File file) throws Exception {
StringBuilder sb = new StringBuilder();
String fileContent = Tools.getContent(file);
sb.append("<!-- i18n 相关 -->\n" +
"<%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\"%>\n" +
"<%@ taglib prefix=\"fn\" uri=\"http://java.sun.com/jsp/jstl/functions\"%>\n" +
"<%@ taglib prefix=\"fmt\" uri=\"http://java.sun.com/jsp/jstl/fmt\"%>\n" +
"\n" +
"<fmt:setLocale value=\"${param.locale}\" />\n" +
"<fmt:bundle basename=\"pageDict\">\n\n\n");
sb.append(fileContent);
sb.append("\n\n<!-- i18n 相关 -->\n" +
"</fmt:bundle>");
// info(sb.toString());
Tools.save(sb.toString(), file, Tools.UTF_8);
}
/**
* 中文 -> 替换为中文对应的 占位符
* 注意 : chinese2Key 需要根据value的长度排序, 长 -> 短
*
* @param file file
* @return void
* @author Jerry.X.He
* @date 2018/1/11 16:14
*/
private void chinese2FmtKey(File file) throws Exception {
final StringBuilder sb = new StringBuilder();
FileUtils.consumeContentList(file, new StringConsumer<Object>() {
@Override
public void consume(String s) {
for (Map.Entry<String, String> entry : chinese2Key.entrySet()) {
String chinese = entry.getKey();
if (s.contains(chinese)) {
s = s.replaceAll(chinese, "<fmt:message key=\"" + entry.getValue() + "\" />");
continue ;
}
}
Tools.appendCRLF(sb, s);
}
@Override
public Object get() {
return null;
}
});
// info(sb.toString());
Tools.save(sb.toString(), file, Tools.UTF_8);
}