Spring (11) ------ support for spring Internationalization
1. Introduction to spring Internationalization
In java programming, there are two methods to process information:
(1) store the information in the database and retrieve it from the database when it is used. (The conventional data dictionary is)
(2) store the information in the java constant class and call the property value through the java class.
These two methods can be implemented for websites that do not need to be internationalized. However, if you need to internationalize,
These two methods are very difficult to achieve internationalization.
Spring provides good support for international implementation, and the Application inherits
The org. springframework. context. MessageResource interface obtains information resources through the getMessage () method,
To achieve the goal of internationalization.
2. getMessage ()
(1) getMessage (java. lang. String arg0, java. lang. Object [] arg1, java. lang. String arg2, java. util. Locale arg3 );
This is the basic method for obtaining information. If the specified information cannot be found, that is, the information is not found after passing in java. lang. Object [] arg1,
Java. lang. String arg2 is used as the default information.
(2) getMessage (java. lang. String arg0, java. lang. Object [] arg1, java. util. Locale arg2) throws org. springframework. context. NoSuchMessageException;
The same method does not specify the default value. If the specified information cannot be found based on the input parameter, NoSuchMessageException is thrown.
(3) getMessage (org. springframework. context. MessageSourceResolvable arg0, java. util. Locale arg1) throws org. springframework. context. NoSuchMessageException;
You can use MessageSourceResolvable to obtain the signal of the input information. The input parameters are of different types than the preceding two methods, which are generally not commonly used.
Iii. Implementation ideas of spring on Internationalization
When ApplicationContext is loaded, the bean with the id of messageSource is automatically searched from the spring configuration file XML.
Spring defines messageSource as the bean supported by internationalization, and uses org. springframework. context. support. ResourceBundleMessageSource.
Bind the resource file of international information to obtain international information.
4. Let's analyze the idea of internationalization based on the instance.
Use output Chinese for testing
My project structure:
Messages_en_CN.properties file content:
HelloWorld = greeting: {0}, greeting time: {1} Note: Put this file under src
HelloWorld class:
Package com. lanhuigu. spring. action; public class HelloWorld {private String msg; // private RefTest refTest; // The constructors with parameters/* public HelloWorld (RefTest refTest) {this. refTest = refTest;} * // inject the attribute value public void setMsg (String msg) {this. msg = msg;} public String getMsg () {return msg;}/* public RefTest getRefTest () {return refTest;} public void setRefTest (RefTest refTest) {this. refTest = refTest ;}*/}
Spring configuration file:
Messages_en_CN
Test
Test procedure:
Package com. lanhuigu. spring. test; import java. util. calendar; import java. util. locale; import org. junit. test; import org. springframework. context. applicationContext; import org. springframework. context. support. classPathXmlApplicationContext; import com. lanhuigu. spring. action. helloWorld; public class TestHelloWorld {@ Testpublic void testMyHelloWorld () {// 1 read the configuration file ApplicationContext acxt = new ClassPathXmlApplicationContext ("/applicationContext. xml "); // 2 get the ISayHello implementation Class Object HelloWorld helloAC = (HelloWorld) acxt Based on bean. getBean ("sayHello"); // 3 call the interface method System. out. println (helloAC. getMsg (); // 4 obtain the dependent class RefTest first, and obtain the dependent class attributes from the dependent class // System. out. println (helloAC. getRefTest (). getMyRef (); // 5. international TESTING //. corresponding to messages. two Parameters in properties: {0}, {1} Object [] objs = new Object [] {"HelloWorld", Calendar. getInstance (). getTime ()}; // B. according to messages. properties to get the configuration, input the objs data parameter, and add the country to get the current time String mytest = acxt. getMessage ("HelloWorld", objs, Locale. CHINA); System. out. println (mytest );}}
Running result:
The output result is garbled. No matter what the Garbled text is, analyze the internationalization principle based on the code.
(1) In the spring configuration file, the id of the internationalized bean is messageSource (this is agreed by spring, which means you can use it if you have nothing to do with it ),
The source of bean is org. springframework. context. support. ResourceBundleMessageSource.
The attribute basename or basenames is different. You can see the annotations in the spring configuration file. The value of the value under property is src.
The name of the configuration file. For example, in spring Messages_en_CN That is, the configuration file of src international information is
Messages_en_CN.propertiest or messages_en_CN.class.
(2) The configuration in the messages_en_CN.properties resource file is HelloWorld = greeting: {0}, greeting time: {1}
= (Equal sign) before HelloWorld is acxt. getMessage ("HelloWorld", objs, Locale. CHINA) is equivalent to the key value,
According to the value in the HelloWorld information resource configuration file, 'greetings: {0}, greeting time: {1} ', and then objs will pass in the corresponding parameter,
Returns the corresponding string: é ????? : HelloWorld, é ???????? ?? : 16-4-9 pm (solve the problem below garbled code)
From the above, we can see that the ResourceBundleMessageSource interface is used to obtain the resource file for internationalization,
Input the corresponding parameters and assemble them into corresponding strings, that is, convert the information obtained from the database or java constant class.
To get information from the resource library, if we put different resource configuration files, we get information in different languages,
To achieve internationalization, the configuration files of the language are stored every time.
5. Solve Chinese garbled characters
In the above example, we can see that the basic internationalization is achieved, obviously in Chinese, and a bunch of garbled characters are output. The solution to this problem is as follows:
(1) transcoding is a thankless solution.
(2) added the ResourceBundleMessageSource interface to solve the garbled problem.
In the above util code, create the ResourceBundleMessageSourceExtend class, inherit from ResourceBundleMessageSource,
Handle garbled characters:
Package com. lanhuigu. spring. util; import java. io. unsupportedEncodingException; import java. text. messageFormat; import java. util. locale; import java. util. map; import java. util. concurrent. concurrentHashMap; import org. springframework. context. support. resourceBundleMessageSource; public class ResourceBundleMessageSourceExtend extends ResourceBundleMessageSource {// The property file is encoded using a UTF-8 (your property file messages. properties uses what ENCODING, ENCODING is set to the corresponding format) private static final String ENCODING = "UTF-8"; private static final String NULL = "null "; /** cache the encoding key value **/Map
EncodingCache = new ConcurrentHashMap
(20);/*** resolve no argus */protected String resolveCodeWithoutArguments (String code, Locale locale) {String message = super. resolveCodeWithoutArguments (code, locale); return decodeString (message, ENCODING);}/*** resolve args * @ see resolveCode (String code, Locale locale) */protected MessageFormat createMessageFormat (String msg, Locale locale) {if (logger. isDebugEnabled () {logger. debug ("Creating MessageFormat for pattern [" + msg + "] and locale '" + locale + "'");} msg = decodeString (msg, ENCODING ); return new MessageFormat (msg! = Null? Msg: ""), locale);}/*** transcoding * @ param msg * @ param encode * @ return */private String decodeString (String message, String encode) {String encodMessage = encodingCache. get (message); if (encodMessage = null) {try {encodMessage = new String (message. getBytes ("ISO8859-1"), encode); if (message! = Null) {encodingCache. put (message, encodMessage);} else {encodingCache. put (message, NULL); // log the code is not exist in properties} catch (UnsupportedEncodingException e) {e. printStackTrace () ;}} return encodMessage ;}}
Modify the spring configuration file as follows:
Messages_en_CN
Test
The running result is as follows:
The code is garbled. note what is the encoding format of messages_en_CN.properties,
In the Extended Interface, right-click the propertiest configuration file and choose properties to see what the encoding is. Then
Set private static final String ENCODING = "UTF-8"; to the corresponding ENCODING format to avoid garbled characters.
I'm in the form of a UTF-8, so ENCODING is set to a UTF-8, which can support UTF-8 ENCODING.