banner



How To Upload A File Using Http Post In Java

Uploading and downloading files are very mutual tasks for which developers need to write code in their applications.

In this article, Yous'll learn how to upload and download files in a RESTful bound boot web service.

We'll first build the REST APIs for uploading and downloading files, and then test those APIs using Postman. We'll too write front-end lawmaking in javascript to upload files.

Following is the concluding version of our application -

Spring Boot File Upload and Download AJAX Rest API Web Service All right! Permit'southward go started.

Creating the Application

Permit's generate our application using Spring Kicking CLI. Fire up your terminal, and blazon the following control to generate the app -

            $ spring init --name=file-demo --dependencies=spider web file-demo Using              service              at https://start.bound.io Project extracted to              '/Users/rajeevkumarsingh/spring-kicking/file-demo'                      

You may likewise generate the awarding through Leap Initializr web tool by post-obit the instructions below -

  1. Open http://get-go.spring.io
  2. Enter file-demo in the "Artifact" field.
  3. Enter com.example.filedemo in the "Package" field.
  4. Add Spider web in the "Dependencies" section.
  5. Click Generate to generate and download the projection.

That's it! You may now unzip the downloaded awarding annal and import it into your favorite IDE.

Configuring Server and File Storage Backdrop

Showtime thing First! Let'southward configure our Spring Boot awarding to enable Multipart file uploads, and define the maximum file size that tin be uploaded. We'll as well configure the directory into which all the uploaded files will be stored.

Open up src/main/resources/application.backdrop file, and add the following properties to information technology -

                          ## MULTIPART (MultipartProperties)              # Enable multipart uploads              jump.servlet.multipart.enabled              =              true              # Threshold after which files are written to disk.              spring.servlet.multipart.file-size-threshold              =              2KB              # Max file size.              spring.servlet.multipart.max-file-size              =              200MB              # Max Request Size              jump.servlet.multipart.max-request-size              =              215MB              ## File Storage Properties              # All files uploaded through the Balance API will be stored in this directory              file.upload-dir              =              /Users/callicoder/uploads                      

Note: Delight change the file.upload-dir property to the path where yous desire the uploaded files to be stored.

Automatically binding properties to a POJO class

Jump Boot has an awesome characteristic called @ConfigurationProperties using which you tin automatically bind the properties defined in the awarding.properties file to a POJO class.

Let's define a POJO class called FileStorageProperties inside com.example.filedemo.holding package to bind all the file storage properties -

                          package              com.instance.filedemo.holding              ;              import              org.springframework.boot.context.properties.                            ConfigurationProperties              ;              @ConfigurationProperties              (prefix              =              "file"              )              public              class              FileStorageProperties              {              individual              String              uploadDir;              public              String              getUploadDir              (              )              {              render              uploadDir;              }              public              void              setUploadDir              (              String              uploadDir)              {              this              .uploadDir              =              uploadDir;              }              }                      

The @ConfigurationProperties(prefix = "file") annotation does its job on application startup and binds all the properties with prefix file to the corresponding fields of the POJO class.

If yous define additional file backdrop in future, you lot may simply add a corresponding field in the above class, and spring kicking will automatically bind the field with the belongings value.

Enable Configuration Properties

Now, To enable the ConfigurationProperties feature, you need to add @EnableConfigurationProperties note to any configuration grade.

Open the primary grade src/main/coffee/com/example/filedemo/FileDemoApplication.java, and add the @EnableConfigurationProperties annotation to it like so -

                          package              com.example.filedemo              ;              import              com.example.filedemo.property.                            FileStorageProperties              ;              import              org.springframework.boot.                            SpringApplication              ;              import              org.springframework.boot.autoconfigure.                            SpringBootApplication              ;              import              org.springframework.boot.context.properties.                            EnableConfigurationProperties              ;              @SpringBootApplication              @EnableConfigurationProperties              (              {              FileStorageProperties              .              class              }              )              public              form              FileDemoApplication              {              public              static              void              primary              (              String              [              ]              args)              {              SpringApplication              .              run              (              FileDemoApplication              .              class              ,              args)              ;              }              }                      

Writing APIs for File Upload and Download

Permit's at present write the Residue APIs for uploading and downloading files. Create a new controller form called FileController within com.example.filedemo.controller package.

Here is the complete lawmaking for FileController -

                          bundle              com.instance.filedemo.controller              ;              import              com.case.filedemo.payload.                            UploadFileResponse              ;              import              com.instance.filedemo.service.                            FileStorageService              ;              import              org.slf4j.                            Logger              ;              import              org.slf4j.                            LoggerFactory              ;              import              org.springframework.beans.mill.note.                            Autowired              ;              import              org.springframework.cadre.io.                            Resource              ;              import              org.springframework.http.                            HttpHeaders              ;              import              org.springframework.http.                            MediaType              ;              import              org.springframework.http.                            ResponseEntity              ;              import              org.springframework.spider web.bind.annotation.                            *              ;              import              org.springframework.web.multipart.                            MultipartFile              ;              import              org.springframework.spider web.servlet.support.                            ServletUriComponentsBuilder              ;              import              javax.servlet.http.                            HttpServletRequest              ;              import              coffee.io.                            IOException              ;              import              java.util.                            Arrays              ;              import              coffee.util.                            Listing              ;              import              java.util.stream.                            Collectors              ;              @RestController              public              grade              FileController              {              private              static              final              Logger              logger              =              LoggerFactory              .              getLogger              (              FileController              .              class              )              ;              @Autowired              private              FileStorageService              fileStorageService;              @PostMapping              (              "/uploadFile"              )              public              UploadFileResponse              uploadFile              (              @RequestParam              (              "file"              )              MultipartFile              file)              {              String              fileName              =              fileStorageService.              storeFile              (file)              ;              String              fileDownloadUri              =              ServletUriComponentsBuilder              .              fromCurrentContextPath              (              )              .              path              (              "/downloadFile/"              )              .              path              (fileName)              .              toUriString              (              )              ;              return              new              UploadFileResponse              (fileName,              fileDownloadUri,              file.              getContentType              (              )              ,              file.              getSize              (              )              )              ;              }              @PostMapping              (              "/uploadMultipleFiles"              )              public              List                              <                UploadFileResponse                >                            uploadMultipleFiles              (              @RequestParam              (              "files"              )              MultipartFile              [              ]              files)              {              return              Arrays              .              asList              (files)              .              stream              (              )              .              map              (file              ->              uploadFile              (file)              )              .              collect              (              Collectors              .              toList              (              )              )              ;              }              @GetMapping              (              "/downloadFile/{fileName:.+}"              )              public              ResponseEntity                              <                Resources                >                            downloadFile              (              @PathVariable              Cord              fileName,              HttpServletRequest              request)              {              // Load file every bit Resources              Resources              resource              =              fileStorageService.              loadFileAsResource              (fileName)              ;              // Try to decide file's content type              Cord              contentType              =              cypher              ;              endeavor              {              contentType              =              asking.              getServletContext              (              )              .              getMimeType              (resources.              getFile              (              )              .              getAbsolutePath              (              )              )              ;              }              catch              (              IOException              ex)              {              logger.              info              (              "Could non determine file type."              )              ;              }              // Fallback to the default content blazon if type could non be determined              if              (contentType              ==              null              )              {              contentType              =              "application/octet-stream"              ;              }              render              ResponseEntity              .              ok              (              )              .              contentType              (              MediaType              .              parseMediaType              (contentType)              )              .              header              (              HttpHeaders              .CONTENT_DISPOSITION,              "attachment; filename=\""              +              resource.              getFilename              (              )              +              "\""              )              .              trunk              (resource)              ;              }              }                      

The FileController grade uses FileStorageService for storing files in the file system and retrieving them. It returns a payload of type UploadFileResponse after the upload is completed. Allow's define these classes one by one.

UploadFileResponse

Equally the name suggests, this class is used to return the response from the /uploadFile and /uploadMultipleFiles APIs.

Create UploadFileResponse class inside com.example.filedemo.payload package with the following contents -

                          package              com.example.filedemo.payload              ;              public              class              UploadFileResponse              {              individual              Cord              fileName;              private              Cord              fileDownloadUri;              private              String              fileType;              individual              long              size;              public              UploadFileResponse              (              String              fileName,              String              fileDownloadUri,              String              fileType,              long              size)              {              this              .fileName              =              fileName;              this              .fileDownloadUri              =              fileDownloadUri;              this              .fileType              =              fileType;              this              .size              =              size;              }              // Getters and Setters (Omitted for brevity)              }                      

Service for Storing Files in the FileSystem and retrieving them

Let's now write the service for storing files in the file system and retrieving them. Create a new class called FileStorageService.coffee inside com.case.filedemo.service bundle with the following contents -

                          package              com.case.filedemo.service              ;              import              com.instance.filedemo.exception.                            FileStorageException              ;              import              com.example.filedemo.exception.                            MyFileNotFoundException              ;              import              com.example.filedemo.property.                            FileStorageProperties              ;              import              org.springframework.beans.factory.annotation.                            Autowired              ;              import              org.springframework.cadre.io.                            Resource              ;              import              org.springframework.core.io.                            UrlResource              ;              import              org.springframework.stereotype.                            Service              ;              import              org.springframework.util.                            StringUtils              ;              import              org.springframework.web.multipart.                            MultipartFile              ;              import              java.io.                            IOException              ;              import              java.cyberspace.                            MalformedURLException              ;              import              java.nio.file.                            Files              ;              import              java.nio.file.                            Path              ;              import              coffee.nio.file.                            Paths              ;              import              java.nio.file.                            StandardCopyOption              ;              @Service              public              grade              FileStorageService              {              private              terminal              Path              fileStorageLocation;              @Autowired              public              FileStorageService              (              FileStorageProperties              fileStorageProperties)              {              this              .fileStorageLocation              =              Paths              .              go              (fileStorageProperties.              getUploadDir              (              )              )              .              toAbsolutePath              (              )              .              normalize              (              )              ;              try              {              Files              .              createDirectories              (              this              .fileStorageLocation)              ;              }              catch              (              Exception              ex)              {              throw              new              FileStorageException              (              "Could non create the directory where the uploaded files will be stored."              ,              ex)              ;              }              }              public              String              storeFile              (              MultipartFile              file)              {              // Normalize file proper noun              String              fileName              =              StringUtils              .              cleanPath              (file.              getOriginalFilename              (              )              )              ;              try              {              // Check if the file's name contains invalid characters              if              (fileName.              contains              (              ".."              )              )              {              throw              new              FileStorageException              (              "Lamentable! Filename contains invalid path sequence "              +              fileName)              ;              }              // Re-create file to the target location (Replacing existing file with the same name)              Path              targetLocation              =              this              .fileStorageLocation.              resolve              (fileName)              ;              Files              .              re-create              (file.              getInputStream              (              )              ,              targetLocation,              StandardCopyOption              .REPLACE_EXISTING)              ;              return              fileName;              }              catch              (              IOException              ex)              {              throw              new              FileStorageException              (              "Could non store file "              +              fileName              +              ". Please endeavour again!"              ,              ex)              ;              }              }              public              Resource              loadFileAsResource              (              String              fileName)              {              try              {              Path              filePath              =              this              .fileStorageLocation.              resolve              (fileName)              .              normalize              (              )              ;              Resource              resources              =              new              UrlResource              (filePath.              toUri              (              )              )              ;              if              (resource.              exists              (              )              )              {              return              resource;              }              else              {              throw              new              MyFileNotFoundException              (              "File not found "              +              fileName)              ;              }              }              take hold of              (              MalformedURLException              ex)              {              throw              new              MyFileNotFoundException              (              "File not establish "              +              fileName,              ex)              ;              }              }              }                      

Exception Classes

The FileStorageService form throws some exceptions in case of unexpected situations. Following are the definitions of those exception classes (All the exception classes go inside the parcel com.example.filedemo.exception).

1. FileStorageException

It's thrown when an unexpected situation occurs while storing a file in the file organization -

                          bundle              com.example.filedemo.exception              ;              public              form              FileStorageException              extends              RuntimeException              {              public              FileStorageException              (              String              message)              {              super              (bulletin)              ;              }              public              FileStorageException              (              String              message,              Throwable              crusade)              {              super              (bulletin,              cause)              ;              }              }                      

ii. MyFileNotFoundException

It's thrown when a file that the user is trying to download is not found.

                          packet              com.case.filedemo.exception              ;              import              org.springframework.http.                            HttpStatus              ;              import              org.springframework.web.bind.annotation.                            ResponseStatus              ;              @ResponseStatus              (              HttpStatus              .NOT_FOUND)              public              grade              MyFileNotFoundException              extends              RuntimeException              {              public              MyFileNotFoundException              (              Cord              message)              {              super              (message)              ;              }              public              MyFileNotFoundException              (              String              bulletin,              Throwable              cause)              {              super              (message,              cause)              ;              }              }                      

Note that, nosotros've annotated the to a higher place exception form with @ResponseStatus(HttpStatus.NOT_FOUND). This ensures that Leap boot responds with a 404 Not Found status when this exception is thrown.

Running the Application and Testing the APIs via Postman

We're washed developing our backend APIs. Let'south run the application and test the APIs via Postman. Type the following control from the root directory of the projection to run the application -

Once started, the application tin can be accessed at http://localhost:8080.

ane. Upload File

Spring Boot File Upload Rest API Example

2. Upload Multiple Files

Spring Boot Upload Multiple Files Rest API Example

iii. Download File

Spring Boot Download File Rest API Example

Developing the Front End

Our backend APIs are working fine. Let's now write the front end code to allow users upload and download files from our web app.

All the front end files volition get within src/principal/resources/static folder. Following is the directory structure of our front-end lawmaking -

            static   └── css        └── main.css   └── js        └── main.js   └── index.html                      

A bit of HTML

                                          <!                DOCTYPE                html                >                                                              <html                >                                                              <caput                >                                                              <meta                proper noun                                  =                  "viewport"                                content                                  =                  "width=device-width, initial-calibration=i.0, minimum-scale=1.0"                                >                                                              <title                >              Jump Boot File Upload / Download Rest API Example                                  </title                >                                                              <link                rel                                  =                  "stylesheet"                                href                                  =                  "/css/principal.css"                                />                                                              </head                >                                                              <torso                >                                                              <noscript                >                                                              <h2                >              Sorry! Your browser doesn't support Javascript                                  </h2                >                                                              </noscript                >                                                              <div                class                                  =                  "upload-container"                                >                                                              <div                class                                  =                  "upload-header"                                >                                                              <h2                >              Spring Kick File Upload / Download Residue API Example                                  </h2                >                                                              </div                >                                                              <div                course                                  =                  "upload-content"                                >                                                              <div                class                                  =                  "unmarried-upload"                                >                                                              <h3                >              Upload Single File                                  </h3                >                                                              <course                id                                  =                  "singleUploadForm"                                proper noun                                  =                  "singleUploadForm"                                >                                                              <input                id                                  =                  "singleFileUploadInput"                                type                                  =                  "file"                                name                                  =                  "file"                                class                                  =                  "file-input"                                required                />                                                              <push button                type                                  =                  "submit"                                course                                  =                  "chief submit-btn"                                >              Submit                                  </button                >                                                              </class                >                                                              <div                class                                  =                  "upload-response"                                >                                                              <div                id                                  =                  "singleFileUploadError"                                >                                                              </div                >                                                              <div                id                                  =                  "singleFileUploadSuccess"                                >                                                              </div                >                                                              </div                >                                                              </div                >                                                              <div                class                                  =                  "multiple-upload"                                >                                                              <h3                >              Upload Multiple Files                                  </h3                >                                                              <class                id                                  =                  "multipleUploadForm"                                name                                  =                  "multipleUploadForm"                                >                                                              <input                id                                  =                  "multipleFileUploadInput"                                type                                  =                  "file"                                proper noun                                  =                  "files"                                form                                  =                  "file-input"                                multiple                required                />                                                              <button                type                                  =                  "submit"                                class                                  =                  "primary submit-btn"                                >              Submit                                  </button                >                                                              </form                >                                                              <div                class                                  =                  "upload-response"                                >                                                              <div                id                                  =                  "multipleFileUploadError"                                >                                                              </div                >                                                              <div                id                                  =                  "multipleFileUploadSuccess"                                >                                                              </div                >                                                              </div                >                                                              </div                >                                                              </div                >                                                              </div                >                                                              <script                src                                  =                  "/js/main.js"                                >                                                                            </script                >                                                              </trunk                >                                                              </html                >                                    

Some Javascript

                          'use strict'              ;              var              singleUploadForm              =              document.              querySelector              (              '#singleUploadForm'              )              ;              var              singleFileUploadInput              =              document.              querySelector              (              '#singleFileUploadInput'              )              ;              var              singleFileUploadError              =              document.              querySelector              (              '#singleFileUploadError'              )              ;              var              singleFileUploadSuccess              =              document.              querySelector              (              '#singleFileUploadSuccess'              )              ;              var              multipleUploadForm              =              document.              querySelector              (              '#multipleUploadForm'              )              ;              var              multipleFileUploadInput              =              document.              querySelector              (              '#multipleFileUploadInput'              )              ;              var              multipleFileUploadError              =              document.              querySelector              (              '#multipleFileUploadError'              )              ;              var              multipleFileUploadSuccess              =              document.              querySelector              (              '#multipleFileUploadSuccess'              )              ;              role              uploadSingleFile              (              file              )              {              var              formData              =              new              FormData              (              )              ;              formData.              append              (              "file"              ,              file)              ;              var              xhr              =              new              XMLHttpRequest              (              )              ;              xhr.              open              (              "Postal service"              ,              "/uploadFile"              )              ;              xhr.              onload              =              function              (              )              {              panel.              log              (xhr.responseText)              ;              var              response              =              JSON              .              parse              (xhr.responseText)              ;              if              (xhr.condition              ==              200              )              {              singleFileUploadError.way.display              =              "none"              ;              singleFileUploadSuccess.innerHTML              =              "<p>File Uploaded Successfully.</p><p>DownloadUrl : <a href='"              +              response.fileDownloadUri              +              "' target='_blank'>"              +              response.fileDownloadUri              +              "</a></p>"              ;              singleFileUploadSuccess.way.brandish              =              "block"              ;              }              else              {              singleFileUploadSuccess.style.display              =              "none"              ;              singleFileUploadError.innerHTML              =              (response              &&              response.message)              ||              "Some Fault Occurred"              ;              }              }              xhr.              send              (formData)              ;              }              role              uploadMultipleFiles              (              files              )              {              var              formData              =              new              FormData              (              )              ;              for              (              var              index              =              0              ;              index              <              files.length;              alphabetize++              )              {              formData.              suspend              (              "files"              ,              files[index]              )              ;              }              var              xhr              =              new              XMLHttpRequest              (              )              ;              xhr.              open              (              "Mail service"              ,              "/uploadMultipleFiles"              )              ;              xhr.              onload              =              function              (              )              {              panel.              log              (xhr.responseText)              ;              var              response              =              JSON              .              parse              (xhr.responseText)              ;              if              (xhr.status              ==              200              )              {              multipleFileUploadError.style.display              =              "none"              ;              var              content              =              "<p>All Files Uploaded Successfully</p>"              ;              for              (              var              i              =              0              ;              i              <              response.length;              i++              )              {              content              +=              "<p>DownloadUrl : <a href='"              +              response[i]              .fileDownloadUri              +              "' target='_blank'>"              +              response[i]              .fileDownloadUri              +              "</a></p>"              ;              }              multipleFileUploadSuccess.innerHTML              =              content;              multipleFileUploadSuccess.fashion.display              =              "cake"              ;              }              else              {              multipleFileUploadSuccess.style.display              =              "none"              ;              multipleFileUploadError.innerHTML              =              (response              &&              response.message)              ||              "Some Error Occurred"              ;              }              }              xhr.              send              (formData)              ;              }              singleUploadForm.              addEventListener              (              'submit'              ,              function              (              event              )              {              var              files              =              singleFileUploadInput.files;              if              (files.length              ===              0              )              {              singleFileUploadError.innerHTML              =              "Please select a file"              ;              singleFileUploadError.style.display              =              "block"              ;              }              uploadSingleFile              (files[              0              ]              )              ;              issue.              preventDefault              (              )              ;              }              ,              true              )              ;              multipleUploadForm.              addEventListener              (              'submit'              ,              function              (              outcome              )              {              var              files              =              multipleFileUploadInput.files;              if              (files.length              ===              0              )              {              multipleFileUploadError.innerHTML              =              "Please select at to the lowest degree one file"              ;              multipleFileUploadError.style.display              =              "block"              ;              }              uploadMultipleFiles              (files)              ;              result.              preventDefault              (              )              ;              }              ,              true              )              ;                      

The above code is self explanatory. I'chiliad using XMLHttpRequest along with FormData object to upload file(due south) as multipart/course-data.

And some CSS

                          *              {              -webkit-box-sizing              :              border-box;              -moz-box-sizing              :              border-box;              box-sizing              :              border-box;              }              body              {              margin              :              0;              padding              :              0;              font-weight              :              400;              font-family              :              "Helvetica Neue"              ,              Helvetica,              Arial,              sans-serif;              font-size              :              1rem;              line-height              :              1.58;              color              :              #333;              background-color              :              #f4f4f4;              }              body:earlier              {              summit              :              50%;              width              :              100%;              position              :              accented;              acme              :              0;              left              :              0;              background              :              #128ff2;              content              :              ""              ;              z-alphabetize              :              0;              }              .clearfix:after              {              display              :              block;              content              :              ""              ;              clear              :              both;              }              h1, h2, h3, h4, h5, h6              {              margin-elevation              :              20px;              margin-bottom              :              20px;              }              h1              {              font-size              :              1.7em;              }              a              {              colour              :              #128ff2;              }              button              {              box-shadow              :              none;              border              :              1px solid transparent;              font-size              :              14px;              outline              :              none;              line-height              :              100%;              white-space              :              nowrap;              vertical-marshal              :              middle;              padding              :              0.6rem 1rem;              border-radius              :              2px;              transition              :              all 0.2s ease-in-out;              cursor              :              pointer;              min-height              :              38px;              }              button.primary              {              background-color              :              #128ff2;              box-shadow              :              0 2px 2px 0              rgba              (0,              0,              0,              0.12)              ;              color              :              #fff;              }              input              {              font-size              :              1rem;              }              input[type="file"]              {              border              :              1px solid #128ff2;              padding              :              6px;              max-width              :              100%;              }              .file-input              {              width              :              100%;              }              .submit-btn              {              display              :              block;              margin-top              :              15px;              min-width              :              100px;              }                              @media                screen                and                (                min-width                :                500px)                            {              .file-input              {              width              :              calc              (100% - 115px)              ;              }              .submit-btn              {              display              :              inline-block;              margin-height              :              0;              margin-left              :              10px;              }              }              .upload-container              {              max-width              :              700px;              margin-left              :              motorcar;              margin-correct              :              auto;              background-colour              :              #fff;              box-shadow              :              0 1px 11px              rgba              (0,              0,              0,              0.27)              ;              margin-top              :              60px;              min-height              :              400px;              position              :              relative;              padding              :              20px;              }              .upload-header              {              border-bottom              :              1px solid #ececec;              }              .upload-header h2              {              font-weight              :              500;              }              .single-upload              {              padding-bottom              :              20px;              margin-lesser              :              20px;              border-bottom              :              1px solid #e8e8e8;              }              .upload-response              {              overflow-10              :              hidden;              word-pause              :              pause-all;              }                      

If you utilise JQuery

If you prefer using jQuery instead of vanilla javascript, then you tin can upload files using jQuery.ajax() method similar so -

                          $              (              '#singleUploadForm'              )              .              submit              (              function              (              event              )              {              var              formElement              =              this              ;              // You can straight create form information from the form element              // (Or you could get the files from input element and append them to FormData every bit nosotros did in vanilla javascript)              var              formData              =              new              FormData              (formElement)              ;              $.              ajax              (              {              type:              "Post"              ,              enctype:              'multipart/form-data'              ,              url:              "/uploadFile"              ,              data:              formData,              processData:              false              ,              contentType:              false              ,              success              :              function              (              response              )              {              console.              log              (response)              ;              // process response              }              ,              fault              :              function              (              error              )              {              console.              log              (error)              ;              // procedure error              }              }              )              ;              result.              preventDefault              (              )              ;              }              )              ;                      

Conclusion

All right folks! In this commodity, we learned how to upload single besides equally multiple files via Residuum APIs written in Leap Boot. We also learned how to download files in Spring Kick. Finally, nosotros wrote code to upload files by calling the APIs through javascript.

I hope the mail service was helpful to you. You tin download the entire code for the projection that nosotros built in this commodity from the github repository.

If y'all want to store files in MySQL database instead of the local file system, then check out the following article -

Jump Boot File Upload / Download with JPA, Hibernate, and MySQL database

Thank you for reading! Run across you in the side by side mail!

Source: https://www.callicoder.com/spring-boot-file-upload-download-rest-api-example/

Posted by: renoofuld1952.blogspot.com

0 Response to "How To Upload A File Using Http Post In Java"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel