一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - 解決Spring國(guó)際化文案占位符失效問(wèn)題的方法

解決Spring國(guó)際化文案占位符失效問(wèn)題的方法

2021-04-21 14:43打破突破 Java教程

本篇文章主要介紹了解決Spring國(guó)際化文案占位符失效問(wèn)題的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

寫(xiě)在前面:接下來(lái)很長(zhǎng)一段時(shí)間的文章主要會(huì)記錄一些項(xiàng)目中實(shí)際遇到的問(wèn)題及對(duì)應(yīng)的解決方案,在相應(yīng)代碼分析時(shí)會(huì)直指問(wèn)題所在,不會(huì)將無(wú)關(guān)的流程代碼貼出,感興趣的讀者可以自行跟蹤。同時(shí)希望大家能夠?qū)⑿牡皿w會(huì)在評(píng)論區(qū)分享出來(lái),讓大家共同進(jìn)步!

環(huán)境或版本:spring 3.2.3

現(xiàn)象:利用spring自帶的messagesource來(lái)處理國(guó)際化文案,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)檢查!

直覺(jué):是不是英文文案太長(zhǎng)了,spring處理時(shí)對(duì)長(zhǎng)度做了限制,仔細(xì)想了想spring應(yīng)該不會(huì)設(shè)計(jì)的這么坑。

排查:斷點(diǎn)跟蹤spring源碼(入口:messagesource的getmessage方法),最后發(fā)現(xiàn)了messageformat中這樣的一段處理方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// 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();
  }

上面的這段代碼寫(xiě)的有點(diǎn)讓人費(fèi)解,略微奇特,我們主要看第一個(gè)邏輯分支:對(duì)每一個(gè)待處理的國(guó)際化文案模板串中的字符進(jìn)行遍歷,當(dāng)字符為"'"時(shí),判斷后一個(gè)字符是否也為“'”,如果是則將“‘”拼接到已處理的stringbuilder中,不是則將inquote至為true,如果該字符不會(huì)‘{'且inquote為false則將part重新置為0,并且segments[seg_index]=null的話重新創(chuàng)建stringbuilder對(duì)象,否則繼續(xù)拼接。

原因分析:

  1. 結(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,接下來(lái)就一路拼接了,不再對(duì)后面的“{“做占位符處理。
  2. 中文文案中兩個(gè)占位符之間并沒(méi)有出現(xiàn)單引號(hào),因此解決了問(wèn)題現(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í)并不是一種很好的解決方法,最好是能夠重寫(xiě)spring調(diào)用applypattern方法前的某一方法來(lái)將單引號(hào)替換為雙引號(hào)。無(wú)奈spring 3.2.3版本中對(duì)應(yīng)國(guó)際化的處理方法一路private,不給你重寫(xiě)的機(jī)會(huì)。

查閱相關(guān)資料得知,在spring4.3.2版本中可以通過(guò)重寫(xiě)resourcebundlemessagesource類中的getstringornull方法來(lái)實(shí)現(xiàn)。

長(zhǎng)遠(yuǎn)方案:升級(jí)項(xiàng)目中的spring版本,同時(shí)使用更多的新版特性。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://my.oschina.net/u/3345762/blog/1790216

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产日产韩产麻豆1区 | 日韩久久影院 | 高清不卡免费一区二区三区 | 激情小视频网站 | 国产图片综合区 | 男人的天堂视频在线 | 美女被扒开屁股进去网 | 欧美最猛性xxxxx69交 | 日本人泡妞18xxⅹ | 国产最新进精品视频 | 日韩免费视频播放 | 国产精品日本亚洲777 | 成年无限观看onlyfans | 国内精品久久久久影院网站 | 精品一久久香蕉国产线看播放 | 337p大尺度啪啪人体午夜2020 | 99久久精品免费观看区一 | 91欧洲在线视精品在亚洲 | 国内交换一区二区三区 | 四虎地址8848aa4hc44四虎 四虎成人永久地址 | 亚洲高清视频网站 | 日韩精品一区二区三区视频 | 日本另类z0zx高清 | 啊好大好粗 | 日老逼| 国产成人91高清精品免费 | 成人做视频免费 | 亚洲v日韩v欧美在线观看 | 日本一区二区三区在线 观看网站 | 精品视频久久久久 | 色综合久久天天综合 | 逼里逼里香 | 久久精麻豆亚洲AV国产品 | 精品一区二区三区视频日产 | 欧美综合精品一区二区三区 | 二区三区在线观看 | 高h孕交 | 国产成人在线视频 | 国产一级特黄aa大片免费 | 天天爽天天 | 9191精品国产观看 |