Javaweb implementation File Upload Download function example detailed _java

Source: Internet
Author: User
Tags save file temporary file storage uuid

In the Web application system development, the file uploads and the downloading function is the very commonly used function, today says the Javaweb file uploads and the downloading function realization.

File Upload Overview

1, the role of file upload

such as network hard disk! is used to upload the download file.
Fill out a full resume on the Zhaopin and upload the photos.

2, file upload requirements for the page

Upload file requirements are more, need to remember:

You must use a form, not a hyperlink
The form's method must be post, not a get
The form's enctype must be multipart/form-data
Add a File form field in the form, that is, <input type= "file" name= "xxx"/>

 <form action= "${pagecontext.request.contextpath}/fileuploadservlet" method= "post" enctype= "multipart/ 
 Form-data ">

 username: <input type=" text "name=" username "/><br/> file 1:<input type=" "File" Name= "
 File1 "/><br/>
 files 2:<input type=" file "Name=" File2 "/><br/> <input type="
 submit " Value= "Submit"/>
 </form>

3, compared to the file upload form and ordinary text form of the difference

View the difference between the file upload form and the plain text form by HttpWatch.

File Upload form of the enctype= "Multipart/form-data", representing the multiple parts form data;
Plain text forms can not set the Enctype property:
When method= "POST", the default value of Enctype is application/x-www-form-urlencoded, which means that the URL encoding body is used
When method= "Get", the default value of Enctype is null, there is no body, so there is no need to enctype.
Testing for plain text forms:

<form action= "${pagecontext.request.contextpath}/fileuploadservlet" method= "POST" >
 username: <input type= " Text "name=" username/><br/>
 file 1:<input type= "file" Name= "file1"/><br/>
 file 2:< Input type= "file" Name= "File2"/><br/> <input type= "Submit" value=
 "submitted"/>
</form>

Using the HttpWatch test to view the body of the request data for the form, we found that the request had only a file name and no file content. That is, when the form's enctype is not multipart/form-data, the request does not contain the contents of the file, but only the name of the file, which means that input:file is no different from input:text in the normal text form.

To upload a form to a file test:

 <form action= "${pagecontext.request.contextpath}/fileuploadservlet" method= "post" enctype= "multipart/ 
 Form-data ">

 username: <input type=" text "name=" username "/><br/> file 1:<input type=" "File" Name= "
 File1 "/><br/>
 files 2:<input type=" file "Name=" File2 "/><br/> <input type="
 submit " Value= "Submit"/>
 </form>

Through the HttpWatch test, look at the body part of the request data of the form, and find that the body part is composed of multiple parts, each of which corresponds to a form field, each with its own header information. Header information below is a blank line, and below the blank line is the body part of the field. Multiple parts are separated by randomly generated separator lines.

The header information of a text field contains only one header information, namely Content-disposition, the value of this header information has two parts, the first part is fixed, namely Form-data, the second part is the name of the field. After the empty line is the body part, the body part is in the text box fill in the content.

The header information for the file field contains two header information, content-disposition and Content-type. Content-disposition a filename, which specifies the name of the file to be uploaded. The content-type specifies the type of file to upload. The body part of the file field is the contents of the file.

Please note, because we uploaded files are ordinary text files, that is, TXT file, so in the HttpWatch can be normal display, if the upload is EXE, MP3 and other documents, then in HttpWatch see is garbled

4, file upload to the servlet requirements

A servlet is also required when submitting a form that is submitted as a file when the form is uploaded.
First of all, let's be sure that the data in the file upload form is encapsulated in the request object.

The Request.getparameter (String) method gets the specified form field character content, but the file upload form is no longer a character content, but a byte content, so it fails.

You can then use the getInputStream () method of the request to get the ServletInputStream object, which is a subclass of InputStream, This ServletInputStream object corresponds to the body part of the entire form (starting with the first divider, to the last), which indicates the data in the parse stream we need. Of course parsing it is a very troublesome thing, and Apache has helped us to provide a tool for parsing it: commons-fileupload

You can try to print out the contents of the Request.getinputstream (), and then compare the request data in the HttpWatch

public void DoPost (HttpServletRequest request, httpservletresponse response)
  throws Servletexception, IOException {
 InputStream in = Request.getinputstream ();
 String s = ioutils.tostring (in);
 System.out.println (s);
}
-----------------------------7ddd3370ab2
content-disposition:form-data name= "username"

Hello
----- ------------------------7ddd3370ab2
content-disposition:form-data; name= "File1"; filename= "A.txt
" Content-type:text/plain

aaa
-----------------------------7ddd3370ab2
content-disposition: Form-data; Name= "File2"; Filename= "B.txt"
content-type:text/plain

bbb
-----------------------------7ddd3370ab2--

Commons-fileupload

Why use FileUpload:

Upload file requirements are more, need to remember:

Must be a post form;
The enctype of the form must be multipart/form-data;
Add a File form field to the form, that is,

Servlet's requirements:

Can no longer use Request.getparameter () to get form data
You can use Request.getinputstream () to get all the form data, not the data for a single table item
This means that without using fileupload, we need to parse the contents of Request.getinputstream () ourselves

1, FileUpload overview

FileUpload is an upload component provided by the Apache Commons component. Its main job is to help us resolve request.getinputstream ()

The jar packages required by the FileUpload component are:

Commons-fileupload.jar, Core Package
Commons-io.jar, Dependency pack

2, FileUpload simple application

FileUpload's core categories are: Diskfileitemfactory, Servletfileupload, Fileitem

The steps for using the FileUpload component are as follows:

1. Create factory class Diskfileitemfactory object
diskfileitemfactory factory = new Diskfileitemfactory ();

2. Use the factory to create the parser object
servletfileupload fileupload = new Servletfileupload (factory);

3. Use the parser to parse the request object
list<fileitem> List = fileupload.parserequest (request);


Diskfileitemfactory Disk File Items factory class

Public diskfileitemfactory (int sizethreshold, File repository)
Specify the memory buffer size and temporary file location when constructing the factory

public void Setsizethreshold (int sizethreshold)
set the memory buffer size, default 10K

public void Setrepository (File repository)
set temporary file storage location, default System.getproperty ("Java.io.tmpdir").

Memory buffers: When uploading files, the contents of the uploaded files are first saved in the memory buffer, and when the size of the uploaded file exceeds the buffer size, a temporary file is generated on the server side.

Temporary file storage location: Save over memory buffer size upload file to generate temporary files, resulting in temporary files can be deleted through the Fileitem Delete () method

Fileitem represents each data part of a file upload form

A grand Introduction to the Fileitem class, it is the result we ultimately want. A Fileitem object corresponds to a table item (form field). There are file fields and normal fields in a form, and you can use the Isformfield () method of the Fileitem class to determine whether a form field is normal or not, if it's not a normal field, then it's a file field.

Note: Because the file upload form is encoded multipart/form-data unlike the traditional URL encoding, all getparameter () methods cannot use setcharacterencoding () cannot solve the input garbled problem

Servletfileupload File Upload Core class

3. Simple Upload Example

Write a simple upload example:

The form contains a user name segment and a file field;
The servlet saves uploaded files to the uploads directory, displaying user name, filename, file size, file type.

First step:

To complete the index.jsp, you need only one form. Note that the form must be post, and that the enctype must be mulitpart/form-data

<form action= "${pagecontext.request.contextpath}/fileuploadservlet" method= "post" enctype= "multipart/ 
 Form-data ">

 username: <input type=" text "name=" username "/><br/> file 1:<input type=" "File" Name= "
 File1 "/><br/>
 <input type=" Submit "value=" submitted "/>
</form>

Step Two: Complete Fileuploadservlet

public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, IOException {//

 Because you want to print using response, set its encoding response.setcontenttype ("Text/html;charset=utf-8");
 Create factory diskfileitemfactory dfif = new Diskfileitemfactory ();
 Create a parser object using the factory servletfileupload fileupload = new Servletfileupload (DFIF);
  try {///Use parser object to parse request, get Fileitem list list&lt;fileitem&gt; lists = Fileupload.parserequest (request); Iterate through all table items for (Fileitem fileitem:list) {//If the current form item is a normal table single if (Fileitem.isformfield ()) {//Get the field name of the current form item Strin
   G FieldName = Fileitem.getfieldname (); If the field name of the current form item is username if (fieldname.equals ("username")) {//print the contents of the current form item, that is, what the user entered in the Username form item Response.getwriter
   (). Print ("User name:" + fileitem.getstring () + "&lt;br/&gt;"); } else {//If the current form item is not a normal form item, the description is the file field String name = Fileitem.getname ();//Get the name of the uploaded file//If the file name you uploaded is empty, you do not specify an upload file if (NA me = = NULL | |
   Name.isempty ()) {continue; //Get the real path, corresponding to the ${project directory}/uploads, whenHowever, this directory must exist with String Savepath = This.getservletcontext (). Getrealpath ("/uploads");
   Create the file Object file = New file (Savepath, name) by uploads the directory and file name;
   Save the uploaded file to the specified location fileitem.write (file);
   Print the name of the upload file Response.getwriter (). Print ("Upload filename:" + name + "&lt;br/&gt;");
   Print Upload file size response.getwriter (). Print ("Upload file Size:" + fileitem.getsize () + "&lt;br/&gt;");
  Print upload file type Response.getwriter (). Print ("Upload file type:" + fileitem.getcontenttype () + "&lt;br/&gt;");
 The catch (Exception e) {throw new Servletexception (e);

 } 
 }

Details of File Upload

1, put the uploaded files to the Web-inf directory

If the user uploads the file to the Web-inf directory, then the user can access the uploaded files directly through the browser, which is very dangerous.

If the user uploads a a.jsp file, and then the user accesses the a.jsp file through the browser, the content in a.jsp is executed, if the following statement is in a.jsp: Runtime.getruntime (). EXEC ("shutdown–s– T 1 "), then you will ...

Usually we create a uploads directory in the Web-inf directory to hold the uploaded files, and the ServletContext Getrealpath (String) method is required to locate the directory in the servlet. For example, in my Upload1 project, you have the following statement:

ServletContext ServletContext = This.getservletcontext ();
String Savepath = Servletcontext.getrealpath ("/web-inf/uploads");

Among them Savepath is: F:\tomcat6_1\webapps\upload1\WEB-INF\uploads.

2, file name (full path, file name)

The upload file name may be the full path:

IE6 gets the upload file name is the full path, while the other browsers get the upload file name is only the name of the file. Browser differences we still need to deal with the problem.

String name = File1fileitem.getname ();
Response.getwriter (). print (name);

Using a different browser test, where IE6 will return the full path to upload files, do not know what IE6 is doing, which brings us a lot of trouble, is to deal with this problem.

Dealing with this problem is also very simple, whether or not as a full path, we have to intercept the last "\" After the content is OK

String name = File1fileitem.getname ();
int lastindex = name.lastindexof ("\ \")//Gets the position of the last "\" If
(lastindex!=-1) {//Note that if it is not the full path, there is no "\" presence. Name
 = name.substring (lastindex + 1);//Get file name
}
Response.getwriter (). print (name);

3, Chinese garbled problem

The upload file name contains Chinese:

When you upload a name containing Chinese, you need to set the encoding, the Commons-fileupload component provides us with two ways to set the encoding:

request.setcharacterencoding (String): This is the way we are most familiar with.
fileupload.setheaderencdoing (String): This approach has a higher priority than the previous

The file content of the uploaded file contains Chinese:

Usually we don't need to care about uploading files, because we will save the uploaded files to the hard drive! In other words, what is the original file, to the server side or what it looks like!

But if you have the need to display the uploaded file content on the console, you can use Fileitem.getstring ("Utf-8") to process the encoding

The contents of the text file and ordinary form items use the GetString ("Utf-8") of the Fileitem class to process the encoding.

4, Upload file name problem (file rename)

We usually save the uploaded files to the uploads directory, but what if the user uploads the same file? This can occur as a cover phenomenon. The way to handle this problem is to use the UUID to generate a unique name and then use the "_" Connection file to upload the original name

For example, the user uploads the file is "my inch photo. jpg", after processing, the filename is called: "891b3881395f4175b969256a3f7b6e10_ my inch photo. jpg", this means that the file will not lose the extension, and because of the uniqueness of the UUID, The uploaded file has the same name, but there is no problem with the same name on the server side.

public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, IOException {RE
 Quest.setcharacterencoding ("Utf-8");
 Diskfileitemfactory dfif = new Diskfileitemfactory ();
 Servletfileupload fileupload = new Servletfileupload (DFIF);
  try {list&lt;fileitem&gt; List = fileupload.parserequest (request);
  Gets the second form item because the first table item is username and the second is the File table single Fileitem Fileitem = List.get (1);
  String name = Fileitem.getname ()///Get file name//If the client is using IE6, you need to get the file name int lastindex = Name.lastindexof ("\") from the full path;
  if (lastindex!=-1) {name = name.substring (lastindex + 1);
  //Get the Save directory for uploaded files String savepath = This.getservletcontext (). Getrealpath ("/web-inf/uploads"); string uuid = Commonutils.uuid ()//generate UUID String filename = uuid + "_" + name;//new file name is UUID + underscore + original name//create file object, next

  The upload file will be saved to the path specified by this file, that is, the//savepath directory of the uploaded file//filename, the file name filename = new file (savepath, filename);
 Save files Fileitem.write (file); catch (Exception e) {throw new servletexception (e);

 } 
 }

5, a directory can not store too many files (storage directory scattered)

A directory should not store too many files, a general directory to store 1000 files is the upper limit, if more, then open the directory will be very "card." You can try to print the C:\WINDOWS\system32 directory, and you'll feel it.

In other words, we need to put the uploaded files in a different directory. However, it cannot be a directory for each uploaded file, which can result in too many directories. So we should use some kind of algorithm to "scatter"!

There are many ways to break up, such as using dates to break up and generate a directory every day. You can also use the first letter of the filename to generate the table of contents, and the same first-letter files are placed in the same directory.

Date Breaking algorithm: If the file upload a day too much, then there will be a directory file too much situation;
First-Letter Breaking algorithm: If the file name is in Chinese, because of too much Chinese, it will cause too much of the phenomenon of directory.

Here we use the hash algorithm to break up:

Gets the Hashcode:int Hcode = Name.hashcode of the file name ()
Gets the lower 4-bit of the hcode and converts it to a 16-character
Gets the 5~8 bit of the hcode and converts it to a 16-character
Use these two 16 characters to generate the catalog chain. For example, a low 4-bit character is "5"

The advantage of this algorithm is that in the uploads directory to generate up to 16 directories, and each directory to regenerate up to 16 directories, that is, 256 directories, all uploaded files are placed in these 256 directories. If you have a maximum of 1000 files per directory, you can save 256,000 files

For example, the upload file name is called: Create a new text document. txt, then get the hash code of "new text document. txt", and then get the low 4 bits of the hash code, and the 5~8 bit. If the low 4 bit is: 9,5~8 bit is 1, then the file save path is uploads/9/1/

int hcode = Name.hashcode ()///Get the file name Hashcode
//Get Hcode low 4 bit, and convert to 16 in string
Dir1 = integer.tohexstring ( Hcode & 0xF);
Gets the low 5~8 bit of the hcode and converts it to a 16-in string
Dir2 = integer.tohexstring (Hcode >>> 4 & 0xF);
The file save directory is connected to the full path
Savepath = Savepath + "/" + Dir1 + "/" + Dir2;
Because this path may not exist, create a file object, and then create a directory chain to ensure that the directory already exists new file (Savepath) before saving the file
. mkdirs ();

6, upload the size of a single file limit

Restricting the size of the uploaded file is simple, and the Servletfileupload class of Setfilesizemax (long) is fine. The parameter is the upper-bound byte number of the uploaded file, for example, Servletfileupload.setfilesizemax (1024*10) represents a maximum of 10KB.

Once the uploaded file exceeds the upper limit, a Fileuploadbase.filesizelimitexceededexception exception is thrown. We can get this exception in the servlet and then output the "uploaded file beyond the limit" to the page.

public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, IOException {req
 Uest.setcharacterencoding ("Utf-8");
 Diskfileitemfactory dfif = new Diskfileitemfactory ();
 Servletfileupload fileupload = new Servletfileupload (DFIF);
 Set the upper limit of a single file upload to 10KB fileupload.setfilesizemax (1024 * 10);
 try {list&lt;fileitem&gt; List = fileupload.parserequest (request);
 Gets the second form item because the first table item is username and the second is the File table single Fileitem Fileitem = List.get (1);
 String name = Fileitem.getname ()///Get file name//If the client is using IE6, you need to get the file name int lastindex = Name.lastindexof ("\") from the full path;
 if (lastindex!=-1) {name = name.substring (lastindex + 1);
 //Get the Save directory for uploaded files String savepath = This.getservletcontext (). Getrealpath ("/web-inf/uploads"); string uuid = Commonutils.uuid ()//generate UUID String filename = uuid + "_" + name;//new file name is UUID + underscore + original name int hcode = NA
 Me.hashcode ()///Get the file name Hashcode//Get the Hcode low 4 bit, and convert to 16 string dir1 = Integer.tohexstring (Hcode &amp; 0xF); Get hThe low 5~8 bit of the code and converts it into a 16-string dir2 = Integer.tohexstring (Hcode &gt;&gt;&gt; 4 &amp; 0xF);
 The file save directory is connected to the full path Savepath = Savepath + "/" + Dir1 + "/" + Dir2;

 Because this path may not exist, create a file object, and then create a directory chain to ensure that the directory already exists new file (Savepath) before saving the file. Mkdirs ();

 Create the file object, the following will save the uploaded files to the file specified path//savepath, that is, upload files to save the directory//filename, file name filename = new file (savepath, filename);
 Save files Fileitem.write (file);
 The catch (Exception e) {//Determines whether the type of exception thrown is fileuploadbase.filesizelimitexceededexception///If it is, it indicates that the upload file exceeded the limit. if (e instanceof fileuploadbase.filesizelimitexceededexception) {//Save error message in Request Request.setattribute ("msg", "Upload failed!") The uploaded file is beyond the 10kb!.
 "); Forward to the index.jsp page!
 You need to use ${msg} in the index.jsp page to display the error message Request.getrequestdispatcher ("/index.jsp"). Forward (request, response);
 Return
 } throw new Servletexception (e);

 } 
}

7, the total size of the upload file limit

Uploading files may allow you to upload multiple files in a form, such as:

Sometimes we need to limit the size of a request. That is, the maximum number of bytes for this request (the sum of all the table items)! It is also easy to implement, just call the Setsizemax (long) method of the Servletfileupload class.

For example Fileupload.setsizemax (1024 * 10), displays an upper limit of 10KB for the entire request. The Parserequest () method of the Servletfileupload class throws a Fileuploadbase.sizelimitexceededexception exception when the request size exceeds 10KB.

8, Cache size and temp directory

Think about it, if I upload a Blu-ray movie, first save the movie in memory, and then through memory copy to the server hard disk, then your memory can eat it?
So the FileUpload component is not able to save the file in memory, FileUpload will determine whether the file size exceeds 10KB, if so the file is saved to the hard disk, if not exceeded, then stored in memory.

10KB is the default value of FileUpload, we can set it.

When the file is saved to the hard disk, FileUpload saves the file to the system temp directory, but you can also set the temp directory

public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, IOException {RE
 Quest.setcharacterencoding ("Utf-8");
 Diskfileitemfactory dfif = new Diskfileitemfactory (1024*20, New File ("F:\\temp"));

 Servletfileupload fileupload = new Servletfileupload (DFIF);
  try {list&lt;fileitem&gt; List = fileupload.parserequest (request);
  Fileitem Fileitem = list.get (1);
  String name = Fileitem.getname ();

  String Savepath = This.getservletcontext (). Getrealpath ("/web-inf/uploads");
 Save File Fileitem.write (path (savepath, name));
 catch (Exception e) {throw new Servletexception (e); "Private file path (string savepath, string filename) {//Get file name int lastindex = Filename.lastindexof (" \ ") from full path
 ;
 if (lastindex!=-1) {filename = filename.substring (lastindex + 1);
 ///Generate a level, level two directory int hcode = Filename.hashcode () by file name;
 String Dir1 = integer.tohexstring (Hcode &amp; 0xF); String Dir2 = integer.tohexstring (hcode &gt;&gt;&gt; 4 &amP
 0xF);
 Savepath = Savepath + "/" + Dir1 + "/" + Dir2;

 Create the directory new File (Savepath). Mkdirs ();
 Add UUID prefix to file name String uuid = Commonutils.uuid ();

 filename = uuid + "_" + filename;
 Create file completion path return new file (Savepath, filename);

 }

File download

1, through the servlet download 1

The downloaded resource must be placed in the Web-inf directory (as long as the user cannot access it directly through the browser), and then the download is done through the servlet.

Link to Downloadservlet in the JSP page, and provide the name of the file to download. Downloadservlet then gets the true path of the file and writes the file to the Response.getoutputstream () stream.

download.jsp

 <body> This is my
 JSP page. <br>
 <a href= "<c:url value= '/downloadservlet?path=a.avi '/>" >a.avi</a><br/>
 <a href= "<c:url value= '/downloadservlet?path=a.jpg '/> ' >a.jpg</" a><br/>
 <a href= ' <c:url value= '/downloadservlet?path=a.txt '/> ' >a.txt</a><br/ >
 </body>

Downloadservlet.java

public void doget (HttpServletRequest request, httpservletresponse response)
 throws Servletexception, IOException {
 String filename = request.getparameter ("path");
 String filepath = This.getservletcontext (). Getrealpath ("/web-inf/uploads/" + filename);
 File File = new file (filepath);
 if (!file.exists ()) {
 response.getwriter (). Print ("The file you are downloading does not exist!"). ");
 return;
 }
 Ioutils.copy (new FileInputStream (file), Response.getoutputstream ());
}

The above code has the following questions:

1. Can download A.avi, but the file name in the download box is downloadservlet;
2. A.jpg and A.txt cannot be downloaded, but they are displayed on the page.

2, through the servlet download 2

Let's deal with the problem in the previous example so that the correct file name can be displayed in the Download box, and the a.jpg and a.txt files can be downloaded

Handle the above problem by adding a content-disposition header. When the content-disposition header is set, the browser pops up the download box

You can also specify the name of the download file by using the Content-disposition header!

String filename = request.getparameter ("path");
 String filepath = This.getservletcontext (). Getrealpath ("/web-inf/uploads/" + filename);
 File File = new file (filepath);
 if (!file.exists ()) {
  response.getwriter (). Print ("The file you are downloading does not exist!"). ");
  return;
 }
 Response.AddHeader ("Content-disposition", "attachment;filename=" + filename);
 Ioutils.copy (new FileInputStream (file), Response.getoutputstream ());

Although the above code already can handle txt and jpg file download problem, and also handled in the download box to display the file name problem, but if the download file name is in Chinese, then still not

3, through the servlet download 3

The following is the process of displaying the Chinese in the download box!

In fact, this problem is very simple, only need to use the URL to encode Chinese can!

download.jsp

<a href= "<c:url value="/downloadservlet?path= This killer is not too cold. avi '/> ' > This killer is not too cold .avi</a><br/>
<a href= "<c:url value= '/downloadservlet?path= bai bing. jpg '/> ' > Bai Bing .jpg</a><br/> <a
" <c:url value= '/downloadservlet?path= description document. txt '/> ' > Documentation .txt</a><br/>


Downloadservlet.java

String filename = request.getparameter ("path");
In a GET request, the parameter contains Chinese that needs to be converted by itself.
//Of course if you use the "Global encoding Filter", then there is no need to deal with
filename = new String (filename.getbytes ("iso-8859-1"), "UTF-8");

String filepath = This.getservletcontext (). Getrealpath ("/web-inf/uploads/" + filename);
File File = new file (filepath);
if (!file.exists ()) {
 response.getwriter (). Print ("The file you are downloading does not exist!"). ");
 return;
}
All browsers will use the local encoding, that is, the Chinese operating system using
the GBK//browser to receive this file name, will use Iso-8859-1 to decode
filename = new String (Filename.getbytes (" GBK ")," iso-8859-1 ");
Response.AddHeader ("Content-disposition", "attachment;filename=" + filename);
Ioutils.copy (new FileInputStream (file), Response.getoutputstream ());

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

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.