這篇文章主要為大家展示了“Spring國際化文案占位符失效怎么辦”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“Spring國際化文案占位符失效怎么辦”這篇文章吧。

創(chuàng)新互聯(lián)建站于2013年成立,先為武江等服務(wù)建站,武江等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為武江企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。
環(huán)境或版本:Spring 3.2.3
現(xiàn)象:利用Spring自帶的MessageSource來處理國際化文案,us狀態(tài)下的文案有部分占位符未被替換,cn狀態(tài)下的正常。文案如下:
tms.pallet.order.box.qty=The total palletized boxes quantity {0} doesn't match with the received boxes quantity {1},Please double check!
tms.pallet.order.box.qty=打板總箱數(shù)件{0},與訂單收貨總箱數(shù){1}不一致。請(qǐng)檢查!
直覺:是不是英文文案太長了,Spring處理時(shí)對(duì)長度做了限制,仔細(xì)想了想Spring應(yīng)該不會(huì)設(shè)計(jì)的這么坑。
排查:斷點(diǎn)跟蹤Spring源碼(入口:MessageSource的getMessage方法),最后發(fā)現(xiàn)了MessageFormat中這樣的一段處理方法:
// Indices for segments
private static final int SEG_RAW = 0;
private static final int SEG_INDEX = 1;
private static final int SEG_TYPE = 2;
private static final int SEG_MODIFIER = 3; // modifier or subformat
/**
* Sets the pattern used by this message format.
* The method parses the pattern and creates a list of subformats
* for the format elements contained in it.
* Patterns and their interpretation are specified in the
* <a href="#patterns" rel="external nofollow" >class description</a>.
*
* @param pattern the pattern for this message format
* @exception IllegalArgumentException if the pattern is invalid
*/
@SuppressWarnings("fallthrough") // fallthrough in switch is expected, suppress it
public void applyPattern(String pattern) {
StringBuilder[] segments = new StringBuilder[4];
// Allocate only segments[SEG_RAW] here. The rest are
// allocated on demand.
segments[SEG_RAW] = new StringBuilder();
int part = SEG_RAW;
int formatNumber = 0;
boolean inQuote = false;
int braceStack = 0;
maxOffset = -1;
for (int i = 0; i < pattern.length(); ++i) {
char ch = pattern.charAt(i);
if (part == SEG_RAW) {
if (ch == '\'') {
if (i + 1 < pattern.length()
&& pattern.charAt(i+1) == '\'') {
segments[part].append(ch); // handle doubles
++i;
} else {
inQuote = !inQuote;
}
} else if (ch == '{' && !inQuote) {
part = SEG_INDEX;
if (segments[SEG_INDEX] == null) {
segments[SEG_INDEX] = new StringBuilder();
}
} else {
segments[part].append(ch);
}
} else {
if (inQuote) { // just copy quotes in parts
segments[part].append(ch);
if (ch == '\'') {
inQuote = false;
}
} else {
switch (ch) {
case ',':
if (part < SEG_MODIFIER) {
if (segments[++part] == null) {
segments[part] = new StringBuilder();
}
} else {
segments[part].append(ch);
}
break;
case '{':
++braceStack;
segments[part].append(ch);
break;
case '}':
if (braceStack == 0) {
part = SEG_RAW;
makeFormat(i, formatNumber, segments);
formatNumber++;
// throw away other segments
segments[SEG_INDEX] = null;
segments[SEG_TYPE] = null;
segments[SEG_MODIFIER] = null;
} else {
--braceStack;
segments[part].append(ch);
}
break;
case ' ':
// Skip any leading space chars for SEG_TYPE.
if (part != SEG_TYPE || segments[SEG_TYPE].length() > 0) {
segments[part].append(ch);
}
break;
case '\'':
inQuote = true;
// fall through, so we keep quotes in other parts
default:
segments[part].append(ch);
break;
}
}
}
}
if (braceStack == 0 && part != 0) {
maxOffset = -1;
throw new IllegalArgumentException("Unmatched braces in the pattern.");
}
this.pattern = segments[0].toString();
}上面的這段代碼寫的有點(diǎn)讓人費(fèi)解,略微奇特,我們主要看第一個(gè)邏輯分支:對(duì)每一個(gè)待處理的國際化文案模板串中的字符進(jìn)行遍歷,當(dāng)字符為"'"時(shí),判斷后一個(gè)字符是否也為“'”,如果是則將“‘”拼接到已處理的StringBuilder中,不是則將inQuote至為True,如果該字符不會(huì)‘{'且inQuote為false則將part重新置為0,并且segments[SEG_INDEX]=null的話重新創(chuàng)建StringBuilder對(duì)象,否則繼續(xù)拼接。
原因分析:
結(jié)合我們配置的英文文案(其中一共有兩個(gè)占位符,在這這兩占位符之前有一個(gè)單引號(hào)),根據(jù)上面Spring的處理源碼看,實(shí)際處理會(huì)是:對(duì)該字符串進(jìn)行逐個(gè)字符處理,逐個(gè)拼接到已處理的StringBuilder中,當(dāng)處理到‘{'時(shí),此處part將被置為1,同時(shí)segments第1個(gè)存儲(chǔ)位上會(huì)引用StringBuilder類型的對(duì)象,程序繼續(xù)處理下面的待處理的字符,繼續(xù)拼接(請(qǐng)自行看part!= SEG_RAW的邏輯分支),直到處理到‘}'時(shí),part被重新賦值為0,sefgments的其他位被清空,于是繼續(xù)處理下面的字符串繼續(xù)拼接,處理到單引號(hào)時(shí),inQuote被置為True,接下來就一路拼接了,不再對(duì)后面的“{“做占位符處理。
中文文案中兩個(gè)占位符之間并沒有出現(xiàn)單引號(hào),因此解決了問題現(xiàn)象中的第二點(diǎn),中文文案顯示正常。
解決方案:
從源碼看只有一種解決方式,{}之間的單引號(hào)需要成對(duì)出現(xiàn),我們的處理方式是將文案修改為了:
tms.pallet.order.box.qty=The total palletized boxes quantity {0} doesn''t match with the received boxes quantity {1},Please double check!
直接修改文案其實(shí)并不是一種很好的解決方法,最好是能夠重寫Spring調(diào)用applyPattern方法前的某一方法來將單引號(hào)替換為雙引號(hào)。無奈spring 3.2.3版本中對(duì)應(yīng)國際化的處理方法一路private,不給你重寫的機(jī)會(huì)。
查閱相關(guān)資料得知,在Spring4.3.2版本中可以通過重寫ResourceBundleMessageSource類中的getStringOrNull方法來實(shí)現(xiàn)。
長遠(yuǎn)方案:升級(jí)項(xiàng)目中的Spring版本,同時(shí)使用更多的新版特性。
以上是“Spring國際化文案占位符失效怎么辦”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
網(wǎng)頁標(biāo)題:Spring國際化文案占位符失效怎么辦
URL分享:http://chinadenli.net/article36/gsjgpg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、商城網(wǎng)站、電子商務(wù)、品牌網(wǎng)站設(shè)計(jì)、外貿(mào)建站、網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)