Written in the previous article: For a long time, the article will mainly record the actual problems encountered in some projects and the corresponding solutions. When analyzing the corresponding code, it will directly point out the problem and will not post irrelevant process codes. Interested readers can track them themselves. At the same time, I hope everyone can share their experiences in the comment area so that everyone can make progress together!
Environment or version: Spring 3.2.3
Phenomenon: Spring's own MessageSource is used to process international copywriting. Some placeholders in the copywriting in the Us state have not been replaced, which is normal in the CN state. The copywriting is as follows:
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=Total number of boxes for boarding {0}, which is inconsistent with the total number of boxes for order receipt {1}. Check, please!
Intuition: Is the English copywriting too long? Spring has restricted the length when processing it. After thinking about it carefully, Spring should not be so pitiful.
Troubleshooting: Breakpoints track Spring source code (entry: MessageSource getMessage method), and finally discovered a processing method like this in 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(); }The above code is a bit confusing and slightly strange. We mainly look at the first logical branch: traverse the characters in each pending international copy template string. When the character is "'", determine whether the next character is also "'". If so, splice "'" into the processed StringBuilder. If not, inQuote is True. If the character does not '{' and inQuote is false, then reset the part to 0, and if segments[SEG_INDEX]=null, recreate the StringBuilder object, otherwise continue splicing.
Cause analysis:
Solution:
From the source code, there is only one solution. Single quotes between {} need to appear in pairs. Our way of handling is to modify the copy to:
tms.pallet.order.box.qty=The total palletized boxes quantity {0} doesn''t match with the received boxes quantity {1},Please double check!
Modifying the copywriting directly is not a good solution. It is best to be able to rewrite a method before Spring calls the applyPattern method to replace single quotes with double quotes. Unfortunately, the corresponding international processing methods in spring 3.2.3 are private all the way, and they do not give you the chance to rewrite.
After consulting relevant information, you can find that in Spring 4.3.2 version, you can rewrite the getStringOrNull method in the ResourceBundleMessageSource class to achieve it.
Long-term solution: Upgrade the Spring version in the project, and use more new features.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.