Freemarker syntax knowledge

Source: Internet
Author: User
Tags arithmetic operators
Freemarker syntax knowledge

The freemarker template file is not much more complex than the HTML page. The freemarker template file consists of the following four parts:
1. Text: directly output
2. Note: <# --... --> the format is not output.
3. interpolation: that is, the section in the format of $ {...} Or # {...} will be replaced by the Section in the data model.
4. FTL command: specified by freemarker. Similar to the HTML Tag, add # Before the name to differentiate and no output will be made.

The following is an example of a freemarker template, which contains the four parts mentioned above.
<HTML> <br>
<Head> <br>
<Title> welcome! </Title> <br>
</Head> <br>
<Body> <br>
<# -- Comment --> <br>
<# -- Use interpolation below -->
<H1> welcome $ {user }! </H1> <br>
<P> we have these animals: <br>
<U1> <br>
<# -- Use the FTL command -->
<# List animals as being> <br>
<Li >$ {being. name} for $ {being. Price} euros <br>
<# List> <br>
<U1> <br>
</Body> <br>
</Html>

1. FTL command rules

In freemarker, FTL tags are used to use commands. freemarker has three FTL tags, which are similar to HTML tags.
1. Start Tag: <# directivename parameter>
2. end tag: </# directivename>
3. Empty Tag: <# directivename parameter/>

In fact, the symbol # In front of the label may also be changed to @. If the command is a USER command rather than a built-in command, you should change the symbol # To the @ symbol.
When using FTL labels, correct nesting should be provided instead of cross-use, which is exactly the same as the usage of XML labels. if no instruction exists, freemarker generates an error message instead of template output. freemarker ignores the blank characters in the FTL tag. it is worth noting that no blank characters are allowed between <,/> and the command.

2. interpolation rules

Freemarker has two types of interpolation: 1. Common interpolation $ {expr}; 2. Digital formatting interpolation: # {expr} Or # {expr; format}

2.1 General Interpolation

General interpolation can be divided into the following four situations:
1. the interpolation result is a string value: the expression result is output directly.
2. the interpolation result is a numeric value: Convert the expression result into text output according to the default format (set by the # setting command). You can use the built-in string function to format a single interpolation, as shown in the following example:
<# Settion number_format = "currency"/>
<# Assign answer = 42/>
$ {Answer}
$ {Answer? String} <# -- the same as $ {answer} -->
$ {Answer? String. Number}
$ {Answer? String. Currency}
$ {Answer? String. percent}
$ {Answer}
The output result is:
$42.00
$42.00
42
$42.00
4,200%
3. the interpolation result is a date value: Convert the expression result into text output according to the default format (set by the # setting command). You can use the built-in string function to format a single interpolation, as shown in the following example:
$ {Lastupdated? String ("yyyy-mm-dd hh: mm: ss zzzz ")}
$ {Lastupdated? String ("Eee, mmm D, ''yy ")}
$ {Lastupdated? String ("eeee, Mmmm DD, yyyy, HH: mm: SS A' ('zzz ')'")}
The output result is:
08:08:08 Pacific Daylight Time
Tue, Apr 8, '03
Tuesday, 1200l 08,200 3, 08:08:08 (PDT)
4. the interpolation result is a Boolean value: Convert the expression result into text output according to the default format (set by the # setting command). You can use the built-in string function to format a single interpolation, as shown in the following example:
<# Assign Foo = true/>
$ {Foo? String ("yes", "no ")}
The output result is:
Yes

2.2 digital formatting and Interpolation

The format and interpolation of numbers can be # {expr; format}. The format can be:
MX: Minimum X-digit decimal part
MX: the maximum number of digits in the decimal part
Example:
<# Assign x= 2.582/>
<# Assign y = 4/>
# {X; M2 }<#-- output 2.58 -->
# {Y; M2} <# -- output 4 -->
# {X; M2 }<#-- output 2.6 -->
# {Y; M2 }< # -- output 4.0 -->
# {X; m1m2 }< # -- output 2.58 -->
# {X; m1m2 }< # -- output 4.0 -->

3. Expression

An expression is the core function of the freemarker template. When an expression is placed in the interpolation syntax $ {}, it indicates the value of the expression to be output. The expression syntax can also be combined with the freemarker tag to control the output. in fact, freemarker's expression function is very powerful. It not only supports specifying values directly, but also output variable values. It also supports functions such as string formatting output and set access.

3.1 directly specify a value

Use the directly specified value syntax to allow freemarker to directly output values in interpolation, rather than output variable values. Directly Specifying values can be strings, values, Boolean values, sets, and map objects.

1, string
Directly specify the string value to be limited by single or double quotation marks. If the string value contains special characters that need to be escaped, see the following example:
$ {"My files are saved on the c: \ disk "}
$ {'My name is \ "annlee \"'}
The output result is:
My files are saved on the c: \ disk.
My name is "annlee"

Freemarker supports the following escape characters:
\ "; Double quotation marks (u0022)
\ '; Single quotes (u0027)
\\; Backslash (u005c)
\ N; line feed (u000a)
\ R; press enter (u000d)
\ T; tab (u0009)
\ B; Return key (u0008)
\ F; form feed (u000c)
\ L; <
\ G;>
\ ;&
\{;{
\ Xcode; specify the Unicode code by using a 4-digit hexadecimal number and output the characters corresponding to the Unicode code.

If a text segment contains a large number of special characters, freemarker provides another special format: You can add the r mark before the quotation marks of the specified string content, files marked with R will be output directly. see the following code:
$ {R "$ {Foo }"}
$ {R "C: \ Foo \ bar "}
The output result is:
$ {Foo}
C: \ Foo \ bar

2, numeric value
The value in the expression is output directly without quotation marks. decimal point ". "separated, cannot use group", "symbol. freemarker currently does not support scientific notation, so "1e3" is incorrect. note the following when using values in the freemarker expression:
1. The value cannot be omitted from 0 before the decimal point, so ". 5" is incorrect.
2. Values 8, + 8, and 8.00 are the same.

3, Boolean Value
Use true or false without quotation marks.

4. Set
The set is enclosed in square brackets. Each set element is separated by a comma (,). See the following example:
<# List ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] As x>
$ {X}
</# List>
The output result is:
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday

In addition, the set element can also be an expression, for example:
[2 + 2, [1, 2, 3, 4], "whatnot"]

You can also use a number range to define a number set, such as 2 .. 5 is equivalent to [2, 3, 4, 5], but more efficient. note that square brackets are not required when you use a number range to define a set. The number range also supports a counter-incrementing number range, such as 5 .. 2

5. map object
The map object is enclosed in curly brackets. Key-value pairs in the map are separated by a colon (:). Multiple key-value pairs are separated by commas. the following is an example:
{"Language": 78, "Mathematics": 80}
Both the key and value of the map object are expressions, but the key must be a string.

3.2 output variable value

When freemarker expressions output variables, these variables can be top-level variables, variables in the map object, variables in the Set, and points (.) to access the attributes of a Java object. these situations are discussed below.

1. Top-level variables
The so-called top-level variables are directly placed in the value of the data model. For example, there are the following data models:
Map root = new hashmap (); // create a data model
Root. Put ("name", "annlee"); // name is a top-level variable.

For top-level variables, $ {variablename} is directly used to output the variable value. The variable name can only be a combination of letters, numbers, underscores, $, @, and #, and cannot start with a number. to output the above name value, you can use the following syntax:
$ {Name}

2. Output set Elements
If you want to output a set element, You can output the set element based on the index of the Set element. The index of the Set element is specified in square brackets. Suppose there is an index:
["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]. the index name is week. If week needs to be output, you can use the following syntax:
$ {Week [2]} // outputs the third set Element

Freemarker also supports returning the child set of the set. To return the child set of the set, you can use the following syntax:
Week [3 .. 5] // returns the child set of the week set. The element in the child set is the 4-6 element in the week set.

3. Output map elements
Here, the map object can be an example of direct hashmap, or even a JavaBean instance. For a JavaBean instance, we can regard it as a map instance whose attribute is key and its attribute value is value. to output the value of the map element, you can use the DOT or square brackets syntax. assume that the following data model is available:
Map root = new hashmap ();
Book = New Book ();
Author author = new author ();
Author. setname ("annlee ");
Author. setaddress ("GZ ");
Book. setname ("struts2 ");
Book. setauthor (author );
Root. Put ("info", "struts ");
Root. Put ("book", book );

To access the name of the author of a book named struts2 in the data model, you can use the following syntax:
Book. Author. Name // use point syntax for all
Book ["author"]. Name
Book. Author ["name"] // use the dot syntax and square brackets syntax in combination.
Book ["author"] ["name"] // all use square brackets syntax

When the dot syntax is used, the variable name has the same limit as the top-level variable, but the square brackets syntax does not have this limit, because the name can be the result of any expression.

3.3, string operation

Freemarker expressions are very flexible for string operations. They can be used to connect string constants and variables, or return string substrings.

There are two syntaxes for string connection:
1. Use $ {...} Or # {...} to insert the expression value in the String constant to complete string connection.
2. Connect strings directly using the join operator +

For example, the following data model is available:
Map root = new hashmap (); root. Put ("user", "annlee ");
The following link the user variable with the constant:
$ {"Hello, $ {user }! "} // Use the first syntax to connect
$ {"Hello," + User + "! "} // Use + to connect
The output strings above are all hello, annlee !, The two syntaxes have the same effect.

It is worth noting that $ {...} can only be used in the text section and cannot be used in expressions. The following code is incorrect:
<# If $ {isbig}> wow! </# If>
<# If "$ {isbig}"> wow! </# If>
It should be written as: <# If isbig> wow! </# If>

The substring can be intercepted Based on the string index. If only one index value is specified when the substring is intercepted, it is used to obtain the character corresponding to the specified index in the string; if two index values are specified, the string substring in the middle of the two indexes is returned. assume that the following data model is available:
Map root = new hashmap (); root. Put ("book", "struts2, freemarker ");
You can use the following syntax to intercept substrings:
$ {Book [0] }$ {book [4]} // The result is Su.
$ {Book [1 .. 4]} // The result is Tru.

3.4 set join Operators

The set operator is to concatenate two sets into a new set, and the operator connecting the set is +. See the following example:
<# List ["Monday", "Tuesday", "Wednesday"] + ["Thursday", "Friday", "Saturday"] As x>
$ {X}
</# List>
The output is: Monday Tuesday Thursday Friday Saturday

3.5 map join Operator

The map object connection operator connects two map objects into a new map object. The map object connection operator is +. If the two map objects have the same key, the value on the right replaces the value on the left. see the following example:
<# Assign scores = {"": 86, "": 78 }+ {"": 87, "Java": 93}>
The language score is $ {scores. Language}
The math score is $ {scores. Math}
Java score: $ {scores. Java}
The output result is:
The Chinese score is 86.
The math score is 87.
Java score 93

3.6 Arithmetic Operators

Freemarker expressions fully support arithmetic operations. freemarker supports the following Arithmetic Operators: +,-, *,/, and %:
<# Assign x = 5>
$ {X * X-100}
$ {X/2}
$ {12% 10}
The output result is:
-75, 2.5, 2

When using Arithmetic Operators in expressions, pay attention to the following points:
1. The operation numbers on both sides of the operator must be numbers
2. When the + operator is used, if one side is a number and the other is a string, the number is automatically converted to a string and then connected, for example: ${3 + "5 "}, result: 35

Use the built-in int function to integer the value, for example:
<# Assign x = 5>
${(X/2 )? Int}
$ {1.1? Int}
$ {1.999? Int}
$ {-1.1? Int}
$ {-1.999? Int}
Result: 2 1-1-1

3.7 comparison Operators

The following comparison operators are supported in expressions:
1, = OR =: determines whether two values are equal.
2 ,! =: Determines whether two values are unequal.
3,> or GT: Determine whether the left value is greater than the right value
4,> = or GTE: Determine whether the left value is greater than or equal to the right value
5, <or LT: Determine whether the left value is smaller than the right value
6, <= or LTE: Determine whether the left value is less than or equal to the right value

Note: = and! = Can be used as a string. The value and date are equal, but = and! = The two sides must be values of the same type; otherwise, an error is generated, and freemarker is for exact comparison. "X", "X", "x" are not equal. other operators can act on numbers and dates, but cannot act on strings. Most of the time, they can be replaced by letter operators such as GT>, because freemarker interprets ">" as the ending character of the FTL tag, you can also use parentheses to avoid this situation, such as: <# If (x> Y)>

3.8 logical operators

Logical operators include the following:
Logic and :&&
Logic or: |
Non-logical :!
Logical operators can only act on boolean values; otherwise, errors may occur.

3.9 built-in functions

Freemarker also provides some built-in functions to convert the output, which can be followed by any variable ?,? Follow the built-in functions to rotate the output variables. Below are common built-in string functions:
HTML: HTML encoding of strings
Cap_first: capital the first letter of the string
Lower_case: converts a string to lowercase.
Upper_case: converts a string to uppercase.
Trim: removes the spaces before and after the string.

The following are common built-in functions of the set.
Size: obtains the number of elements in a sequence.

Below are common built-in functions for numeric values
INT: obtains the integer part of A number. The result is signed.

For example:
<# Assign test = "Tom & Jerry">
$ {Test? HTML}
$ {Test? Upper_case? HTML}
Result: Tom & amp; Jerry

3.10 null value Processing Operator

Freemarker has strict processing on null values. freemarker variables must have values. If a variable is not assigned a value, an exception is thrown, because the Force Error of variables not assigned by freemarker can prevent many potential errors, such as missing potential variable names or other variable errors. the null value mentioned here actually includes non-existent variables. For a Java null value, we think this variable exists, but its value is null, but for the freemarker template, it cannot understand the null value. The null value is the same as the nonexistent variable.

To process missing variables, freemarker provides two operators:
! : Specify the default value of the missing variable
?? : Determines whether a variable exists

Here ,! The following two operators are used:
Variable! Or variable! Defaultvalue. In the first usage, the default value is not specified for the missing variable, indicating that the default value is a Null String, a set with a length of 0, or a map object with a length of 0.

Use! When the default value is specified, the default value type is not required to be the same as the variable type. Use ?? The operator is very simple. It always returns a Boolean value. Usage: Variable ??, If this variable exists, true is returned; otherwise, false is returned.

3.11 operator priority

The operator priority in freemarker is as follows (sorted from high to low ):
1, unary operator :!
2. built-in functions :?
3, multiplication and division: *,/, %
4. addition and subtraction:-, +
5, comparison:>, <, >=, <= (LT, LTE, GT, GTE)
6, equal: =, = ,! =
7. Logic and :&&
8, logic or: |
9, number range :..

In fact, we should use parentheses to strictly differentiate during the development process. This is easy to read and has fewer errors.

4. Frequently Used freemarker commands

Freemarker's FTL commands are also an important part of the template. These commands can facilitate iteration and branch control of data contained in the data model. in addition, some important functions are also implemented through the FTL command.

4.1 If command

This is a typical Branch Control Command. Its function is similar to if in Java. The syntax format of the IF command is as follows:
<# If condition>...
<# Elseif condition>...
<# Elseif condition>...
<# Else>...
</# If>

Example:
<# Assign age = 23>
<# If (age> 60)> elderly
<# Elseif (age> 40)> middle-aged
<# Elseif (age> 20)> young people
<# Else> young man
</# If>
Output: young people
The logic expression in the above Code is enclosed in parentheses mainly because there is a> symbol in it. Because freemarker regards> as the end character of the tag, it may cause program errors. To avoid this situation, we should use brackets wherever these symbols appear.

4.2 switch, Case, default, break command

These commands are obviously branch commands, which act similar to the switch statement of Java. The syntax structure of the switch command is as follows:
<# Switch value>
<# Case refvalue>... <# Break>
<# Case refvalue>... <# Break>
<# Default>...
</# Switch>

4.3 list, break command

The list command is an iterative output Command Used To iterate the set of output data models. The syntax format of the list command is as follows:
<# List sequence as item>
...
</# List>
In the preceding syntax format, sequence is a collection object or expression. However, this expression returns a collection object, and item is an arbitrary name, is the set element output by iteration. in addition, when the set object is iterated, there are two special cycle variables:
Item_index: index value of the current variable
Item_has_next: whether the next object exists
You can also use the <# Break> command to exit iteration.

Example:
<# List ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] As x>
$ {X_index + 1}. $ {x} <# If x_has_next>, </If>
<# If x = "Thursday"> <# Break> </# If>
</# List>

4.4 include command

The include command is similar to the JSP containing command. The syntax format for containing the specified page. include command is as follows:
<# Include filename [Options]>
In the preceding syntax format, the two parameters are described as follows:
Filename: Specifies the template file to be included.
Options: this parameter can be omitted. It specifies the included options, including encoding and parse options. Encoding specifies the decoding set used when the page is contained, parse specifies whether the included file is parsed as an FTL file. If the parse option value is omitted, the default value of this option is true.

4.5 import command

This command is used to import all variables in the freemarker template and place the variables in the specified map object. The syntax format of the import command is as follows:
<# Import "/lib/common. FTL" As COM>
The code above will import all the variables in the/lib/common. FTL template file and place these variables in a map object named COM.

4.6 noparse command

The noparse command specifies that freemarker does not process the content contained in the specified command. The syntax format of this command is as follows:
<# Noparse>... </# noparse>

See the following example:
<# Noparse>
<# List books as book>
<Tr> <TD >$ {book. name} <TD> author: $ {book. Author}
</# List>
</# Noparse>
The output is as follows:
<# List books as book>
<Tr> <TD >$ {book. name} <TD> author: $ {book. Author}
</# List>

4.7 escape and noescape commands

The escape command automatically adds the escape expression to the interpolation in the body area, but does not affect the interpolation in the string. It only affects the interpolation in the body. The syntax format of the escape command is as follows:
<# Escape identifier as expression>...
<# Noescape>... </# noescape>
</# Escape>

See the following code:
<# Escape X as X? HTML>
First name: $ {firstname}
Last name: $ {lastname}
Maiden name: $ {maidenname}
</# Escape>
The above code is equivalent:
First name: $ {firstname? HTML}
Last name: $ {lastname? HTML}
Maiden name: $ {maidenname? HTML}

The escape command works when parsing the template rather than when running. In addition, the escape command is also nested and used. The child escape inherits the rules of the parent escape, as shown in the following example:
<# Escape X as X? HTML>
Customer name: $ {customername}
Items to ship;
<# Escape X as itemcodetonamemap [x]>
$ {Itemcode1}
$ {Itemcode2}
$ {Itemcode3}
$ {Itemcode4}
</# Escape>
</# Escape>
The above code is similar:
Customer name: $ {customername? HTML}
Items to ship;
$ {Itemcodetonamemap [itemcode1]? HTML}
$ {Itemcodetonamemap [itemcode2]? HTML}
$ {Itemcodetonamemap [itemcode3]? HTML}
$ {Itemcodetonamemap [itemcode4]? HTML}

For all interpolation in the escape command, this interpolation will be automatically added with an escape expression. If you need to specify some interpolation in the escape command, you should use the noescape command, the interpolation in the noescape command does not add an escape expression.

4.8 assign command

The assign command has been used multiple times before. It is used to create or replace a top-level variable for the template page. The assign command is used in many ways, including creating or replacing a top-level variable, you can also create or replace multiple variables. Its simplest syntax is as follows: <# assign name = value [IN namespacehash]>, which is used to specify a variable named name, the value of this variable is value. In addition, freemarker allows you to add an in clause to the assign command. The in clause is used to place the created name variable in the namespacehash namespace.

The assign command also has the following usage: <# assign name1 = value1 name2 = value2... namen = valuen [IN namespacehash]>. This syntax can create or replace multiple top-level variables at the same time. In addition, it has a complicated usage, if the variable value to be created or replaced is a complex expression, you can use the following syntax format: <# assign name [IN namespacehash]> capture this </# assign>, in this syntax, the content of the assign command is assigned to the name variable. example:
<# Assign x>
<# List ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] as n>
$ {N}
</# List>
</# Assign>
$ {X}
The above code will generate the following output: Monday Tuesday Thursday Friday Saturday

Although assign specifies the usage of this complex variable value, we should not abuse this usage, as shown in the following example: <# assign x> Hello $ {user }! </# Assign>. The above code is better written as follows: <# assign x = "Hello $ {user }! ">

4.9 setting command

This command is used to set the runtime environment of freemarker. The syntax format of this command is as follows: <# setting name = value>. in this format, the value range of name includes the following:
Locale: Specifies the country/language option used by the template.
Number_format: Format of the output number.
Boolean_format: Specifies the syntax format of two boolean values. The default value is true and false.
Date_format, time_format, datetime_format: Format of the output date.
Time_zone: specifies the time zone used to format the output date.

4.10 macro, nested, return command

Macro can be used to implement custom commands. By using custom commands, you can define a template segment as a user instruction. The syntax format of macro commands is as follows:
<# Macro name param1 param2... paramn>
...
<# Nested loopvar1, loopvar2,..., loopvarn>
...
<# Return>
...
</# Macro>
The preceding format snippet contains the following parts:
The name: Name attribute specifies the name of the custom command. Multiple parameters can be input when using the custom command.
Paramx: This attribute is used to specify parameters when using custom commands. When using this custom command, you must input values for these parameters.
Nested command: The intermediate part of the nested label output when using custom commands
Loop variable in the nested command: this loop variable will be specified by the macro definition part and passed to the template using the tag
Return command: This command can be used to end the custom command at any time.

See the following example:
<# Macro book> // define a custom instruction
J2EE
</# Macro>
<@ Book/> // use the command just defined
The output result of the above Code is: J2EE

In the above Code, it may be difficult to see the use of custom tags, because the content of the book commands we define is very simple. In fact, custom tags can contain a lot of content, this allows for better code reuse. in addition, you can specify parameters for custom commands when defining custom commands. See the following code:
<# Macro Book Booklist> // define a custom instruction. Booklist is a parameter.
<# List booklist as book>
$ {Book}
</# List>
</# Macro>
<@ Book Booklist = ["Spring", "J2EE"]/> // use the command just defined
The above code passes in a parameter value for the book command. The output result of the above Code is: Spring J2EE

In addition, you can use the nested command to output the intermediate part of the custom command when using the custom command. See the following example:
<# Macro page title>
<HTML>
<Head>
<Title> freemarker Example page-$ {Title? HTML} </title>
</Head>
<Body>
<H1 >$ {Title? HTML} <# Nested> // The label body used to introduce custom commands.
</Body>
</Html>
</# Macro>
The code above defines an HTML page template as a page instruction, so the page instruction can be performed on other pages:
<# Import "/common. FTL" As COM> // assume that the preceding template page is named common. FTL. The import page
<@ Com. page title = "book list">
<U1>
<Li> spring </LI>
<Li> J2EE </LI>
</Ul>
</@ Com. Page>

From the above example, we can see that using macro and nested commands can easily achieve the page decoration effect. In addition, you can also specify one or more cycle variables when using the nested command, see the following code:
<# Macro book>
<# Nested 1> // a loop variable value is specified when the book command is used.
<# Nested 2>
</# Macro>
<@ Book; X >$ {x}. Books </@ book>
When using the nested command to pass in the variable value, when using the custom command, you need to use a placeholder (such as the; X after the book command). The above code output text is as follows:
1. Books 2. Books

When using cyclic variables in the nested command, you can use multiple cyclic variables. See the following code:
<# Macro repeat count>
<# List 1 .. count as x> // Three Cyclic variables are specified when the nested command is used.
<# Nested X, X/2, x = count>
</# List>
</# Macro>
<@ Repeat count = 4; C halfc last>
$ {C}. $ {halfc} <# If last> last! </# If>
</@ Repeat>
The above output result is:
1. 0.5 2. 1 3. 1.5 4. 2 last;

The return command ends the macro command. Once the return command is executed in the macro command, freemarker does not continue to process the content in the macro command. See the following code:
<# Macro book>
Spring
<# Return>
J2EE
</# Macro>
<@ Book/>

Freemarker syntax knowledge

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.