1. Internationalization
Prepare resource files. The naming format of resource files is as follows:
baseName_language_country.properties
baseName_language.properties
baseName.properties
Among them, baseName is the base name of the resource file. We can customize it, but language and country must be the language and country supported by java. like:
Mainland China: baseName_zh_CN.properties
United States: baseName_en_US.properties
Now add two resource files to the application:
The first one stores Chinese: csdn_zh_CN.properties
The content is: welcome=Welcome to Chuanzhi Podcast The second depository is English (United States): csdn_en_US.properties
The content is: welcome=welcome to csdn
For Chinese property files, after we write them, we should use the native2ascii command provided by jdk to convert the files into unicode-encoded files. The command is used as follows:
native2ascii source file.properties target file.properties
2. Configure global resources and output international information
After preparing the resource file, we can define the resource file as a global resource file through the struts.custom.i18n.resources constant in struts.xml, as follows:
<constant name="struts.custom.i18n.resources" value="csdn" />
csdn is the base name of the resource file.
Later we can access the internationalization information on the page or in the action:
Use the <s:text name=""/> tag in the JSP page to output internationalization information:
<s:text name="user"/>, name is the key in the resource file
In the Action class, you can inherit ActionSupport and use the getText() method to obtain internationalization information. The first parameter of this method is used to specify the key in the resource file.
In the form tag, specify the key in the resource file through the key attribute, such as:
<s:textfield name="realname" key="user"/>
3. Internationalization - Output internationalization information with placeholders
The contents of the resource file are as follows:
welcome= {0}, welcome to Chuanzhi Podcast {1}
Output internationalization information with placeholders in jsp page
<s:text name="welcome">
<s:param><s:property value="realname"/></s:param>
<s:param>Learning</s:param>
</s:text>
To obtain internationalization information with placeholders in the Action class, you can use the getText(String key, String[] args) or getText(String aTextName, List args) method.
4. Internationalization - scope resource files
In a large application, the entire application has a large amount of content that needs to be internationalized. If we place all the internationalized content in the global resource attribute file, it will obviously cause the resource file to become too large, bloated, and inconvenient to maintain. This Sometimes we can use package scope to organize internationalization files for different modules.
Here's how:
Place the package_language_country.properties resource file under the java package. Package is a fixed writing method. Actions under this package and sub-packages can access this resource. When searching for messages with a specified key, the system will first search from the package resource file. When the corresponding key cannot be found, it will search from the resource file specified by the constant struts.custom.i18n.resources.
5. Internationalization-Action scope resource file
We can also specify a resource file separately for an action as follows:
In the path where the Action class is located, place the ActionClassName_language_country.properties resource file. ActionClassName is the simple name of the action class.
When looking for messages with a specified key, the system will first search from the ActionClassName_language_country.properties resource file. If the corresponding key is not found, then it will search up the resource file with the basic name package along the current package until it finds the top-level package. If the corresponding key has not been found, it will finally be searched from the resource file specified by the constant struts.custom.i18n.resources.
6. Internationalization - direct access to a resource file in JSP
Struts2 provides us with the <s:i18n> tag. Using the <s:i18n> tag we can obtain internationalized data directly from a resource file on the classpath without any configuration:
<s:i18n name="csdn">
<s:text name="welcome"/>
</s:i18n>
csdn is the base name of the resource file in the class path.
If the resource file you want to access is under a certain package on the classpath, you can access it like this:
<s:i18n name="cn/csdn/action/package">
<s:text name="welcome">
<s:param>Xiao Zhang</s:param>
</s:text>
</s:i18n>
The above accesses the resource file basically named package under the cn.csdn.action package.
7. OGNL Expression Language
OGNL is the abbreviation of Object Graphic Navigation Language, which is an open source project. The Struts 2 framework uses OGNL as the default expression language.
Compared with EL expressions, it provides some functions we usually need, such as:
Support object method calls, such as xxx.sayHello();
Supports class static method calling and value access. The expression format is @[full class name (including package path)]@[method name | value name], for example: @java.lang.String@format('foo %s' , 'bar') or @cn.csdn.Constant@APP_NAME;
Manipulate collection objects.
Ognl has a concept of context. To put it bluntly, context is a MAP structure, which implements the java.utils.Map interface. In Struts2, the implementation of context is ActionContext. The following is the structural diagram of context.
To access objects in the context, you need to use the # symbol to mark the namespace, such as #application, #session
In addition, OGNL will set a root object (root object). In Struts2, the root object is ValueStack (value stack). If you want to access the properties of the object in the root object (i.e. ValueStack), you can omit the # namespace and directly access the properties of the object.
In struts2, the implementation class of the root object ValueStack is OgnlValueStack. This object does not only store a single value as we imagined, but stores a group of objects. There is a root variable of List type in the OgnlValueStack class, which is used to store a group of objects.
|--request
|--application
context ------|--OgnlValueStack root variable [action, OgnlUtil, ... ]
|--session
|--attr
|--parameters
The first object in the root variable is called the top object on the stack. Usually we can access the properties of the object in the root variable by directly writing the name of the property in the OGNL expression. The search sequence starts from the object on the top of the stack. If the property does not exist on the object on the top of the stack, it will be searched from the second object. , if not found, search from the third object, and access it in sequence until it is found.
Attention: In Struts2, OGNL expressions need to be used with Struts tags. For example: <s:property value="name"/>
Since ValueStack is the root object of OGNL in Struts 2, if the user needs to access the objects in the value stack, the JSP page can directly access the properties of the objects in ValueStack through the following EL expression:
${foo} //Get the foo attribute of an object in the value stack
If you access objects in other Contexts, since they are not root objects, you need to add the # prefix when accessing.
application object: used to access ServletContext, such as #application.userName or #application['userName'], which is equivalent to calling getAttribute("username") of ServletContext.
session object: used to access HttpSession, such as #session.userName or #session['userName'], which is equivalent to calling session.getAttribute("userName").
request object: Map used to access HttpServletRequest attributes, such as #request.userName or #request['userName'], which is equivalent to calling request.getAttribute("userName").
parameters object: used to access HTTP request parameters, such as #parameters.userName or #parameters['userName'], which is equivalent to calling request.getParameter("username").
attr object: used to access its attributes in the order of page->request->session->application.
8. Why can you use EL expressions to access the properties of objects in valueStack?
The reason is that Struts2 further encapsulates HttpServletRequest. The simplified code is as follows:
public class StrutsRequestWrapper extends HttpServletRequestWrapper {
public StrutsRequestWrapper(HttpServletRequest req) {
super(req);
}
public Object getAttribute(String s) {
...
ActionContext ctx = ActionContext.getContext();
Object attribute = super.getAttribute(s);//First get the attribute value from the request scope
if (ctx != null) {
if (attribute == null) {//If the attribute value is not found from the request range, find the attribute value of the object from ValueStack
...
ValueStack stack = ctx.getValueStack();
attribute = stack.findValue(s);
...
}
}
return attribute;
}
}
9. Create List/Map collection objects using OGNL expressions
If you need a collection element (such as a List object or a Map object), you can use the collection-related expressions in OGNL.
Use the following code to directly generate a List object:
<s:set name="list" value="{'zhangming','xiaoi','liming'}" />
<s:iterator value="#list" id="n">
<s:property value="n"/><br>
</s:iterator>
Generate a Map object:
<s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}" />
<s:iterator value="#foobar" >
<s:property value="key"/>=<s:property value="value"/><br>
</s:iterator>
The Set tag is used to place a value into a specified range.
Scope: Specifies the scope in which the variable is placed. This attribute can accept application, session, request, page or action. If this attribute is not set, it will be placed in the OGNL Context by default.
value: The value assigned to the variable. If this attribute is not set, the value at the top of the ValueStack stack is assigned to the variable.