91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring國際化文案占位符失效怎么辦

發布時間:2021-07-12 14:45:17 來源:億速云 閱讀:155 作者:小新 欄目:編程語言

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

環境或版本:Spring 3.2.3

現象:利用Spring自帶的MessageSource來處理國際化文案,us狀態下的文案有部分占位符未被替換,cn狀態下的正常。文案如下:

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=打板總箱數件{0},與訂單收貨總箱數{1}不一致。請檢查!

直覺:是不是英文文案太長了,Spring處理時對長度做了限制,仔細想了想Spring應該不會設計的這么坑。

排查:斷點跟蹤Spring源碼(入口:MessageSource的getMessage方法),最后發現了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();
  }

上面的這段代碼寫的有點讓人費解,略微奇特,我們主要看第一個邏輯分支:對每一個待處理的國際化文案模板串中的字符進行遍歷,當字符為"'"時,判斷后一個字符是否也為“'”,如果是則將“‘”拼接到已處理的StringBuilder中,不是則將inQuote至為True,如果該字符不會‘{'且inQuote為false則將part重新置為0,并且segments[SEG_INDEX]=null的話重新創建StringBuilder對象,否則繼續拼接。

原因分析:

  1. 結合我們配置的英文文案(其中一共有兩個占位符,在這這兩占位符之前有一個單引號),根據上面Spring的處理源碼看,實際處理會是:對該字符串進行逐個字符處理,逐個拼接到已處理的StringBuilder中,當處理到‘{'時,此處part將被置為1,同時segments第1個存儲位上會引用StringBuilder類型的對象,程序繼續處理下面的待處理的字符,繼續拼接(請自行看part!= SEG_RAW的邏輯分支),直到處理到‘}'時,part被重新賦值為0,sefgments的其他位被清空,于是繼續處理下面的字符串繼續拼接,處理到單引號時,inQuote被置為True,接下來就一路拼接了,不再對后面的“{“做占位符處理。

  2. 中文文案中兩個占位符之間并沒有出現單引號,因此解決了問題現象中的第二點,中文文案顯示正常。

解決方案:

從源碼看只有一種解決方式,{}之間的單引號需要成對出現,我們的處理方式是將文案修改為了:

tms.pallet.order.box.qty=The total palletized boxes quantity {0} doesn''t match with the received boxes quantity {1},Please double check!

直接修改文案其實并不是一種很好的解決方法,最好是能夠重寫Spring調用applyPattern方法前的某一方法來將單引號替換為雙引號。無奈spring 3.2.3版本中對應國際化的處理方法一路private,不給你重寫的機會。

查閱相關資料得知,在Spring4.3.2版本中可以通過重寫ResourceBundleMessageSource類中的getStringOrNull方法來實現。

長遠方案:升級項目中的Spring版本,同時使用更多的新版特性。

以上是“Spring國際化文案占位符失效怎么辦”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

大竹县| 常州市| 易门县| 开原市| 大兴区| 湖口县| 海淀区| 资阳市| 富锦市| 南溪县| 吴桥县| 祁东县| 禄劝| 璧山县| 观塘区| 江源县| 巫山县| 怀安县| 绥化市| 汾西县| 盱眙县| 从化市| 沂水县| 徐汇区| 遵化市| 安平县| 马尔康县| 溆浦县| 青岛市| 永定县| 乐安县| 扬州市| 临夏县| 高安市| 昌宁县| 长丰县| 兴文县| 阿瓦提县| 拉萨市| 右玉县| 璧山县|