Uploading files

Learn how to send files to server with Hi-Framework

ng-upload directive

The ng-upload directive is part of Hi-Framework (not AngularJS), and it is responsible for binding file input boxes to scope objects with references of files ready to be uploaded. That files, are then sent to the server-side via frontier method invocations (passing the objects as params, the same way we send any other kind of data).

Using ng-upload, your markup will look like this:

<input type="file" ng-upload="profilePhoto" />

And you can access the object anytime at $scope.profilePhoto.

Sending the file to server

As we said before, sending files to server does not look different from any other frontier invocations with params:

 MyFrontier.method1($scope.profilePhoto,someOtherParam).try(function(result){    
		// Do anything
    }).catch(function(){
        // Do anything
	}).finally(function(){
        // Do anything
    });

Handling the file on server-side

Configuring web.xml

In order to send files to server-side, you must set some Multipart configurations in your web.xml file.

See example below:

  <servlet>
        <servlet-name>Hi-Framework-Dispatcher-Servlet</servlet-name>
        <servlet-class>org.emerjoin.hi.web.DispatcherServlet</servlet-class>
        <multipart-config>
            <location>tmp/</location> <!-- set a temporary folder -->
            <max-file-size>80848820</max-file-size> <!-- 77 MB -->
            <max-request-size>918018841</max-request-size> <!-- 875 MB -->
            <file-size-threshold>1048576</file-size-threshold> <!-- 1 MB -->
        </multipart-config>
    </servlet>

    <servlet-mapping>
        <servlet-name>Hi-Framework-Dispatcher-Servlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

Learn more about multipart configurations here.

Getting the file on Frontier

In your frontier, just make sure the type of the variable expecting your file is org.emerjoin.hi.web.frontier.FileUpload.

@Frontier
public class MyFrontier{
    public void method1(FileUpload  file, String otherParam){

         //write file here

    }
}

Writing the file

Writing the file requires you to know where you wish to place it. The syntax for writing files is as simple as follows:

@Frontier
public class MyFrontier{
    public void method1(FileUpload  file, int otherParam){
             
        try {

            file.saveToFolder("/path/to/your/uploads/directory/");

        }catch (Exception ex){

            //handle error here

        }    

    }
}

About paths
Relative paths will not work. please make sure you indicate the absolute path according to your OS. Learn more at https://docs.oracle.com/javase/tutorial/essential/io/path.html

Client-side operations

There some interesting things we allow you to do on the client-side.

Clearing selected files

To achieve this, just delete the $scope variable referencing the file.

delete $scope.profilePhoto;

Getting a callback after a file was selected

To achieve this, just handle the onFiles event.

Make sure to pass a parameter named upload if you wish to get information about the file.

HTML

<input type="file" ng-upload="profilePhoto" onFiles="someFunction(upload)" />

JS


 Hi.view(function($scope){
 
    $scope.someFunction = function(upload){
    
        //do whatever you want.
        
    }
 
 });

Multiple files upload

Getting multiple files uploaded instead of one is as simple as getting only one.

Client-side

See this example below:

<form>
   
    <input type="file" ng-upload="somePhotos" onFiles="someFunction(upload)" multiple="true" />

</form>

NOTICE
In case of multiple files upload, make sure the param you pass to onFiles is still upload

Server-side

On the server-side the only thing that changes is that you expect a set of FileUpload objects.

@Frontier
public class MyFrontier{

     public void someMethod(FileUpload[] myFiles, int otherParam){
          for(FileUpload file: myFiles){
             
              //write file here
			 
          } 
     }

}
Github Repository