File Upload with AngularJs And Spring Boot Rest

File Upload with AngularJs And Spring Boot Rest thumbnail
50K
By Dhiraj 02 October, 2017

In this post we will be discussing about using form data to upload file to a spring boot based REST server with angular js as client.We will have a sample project having a form to upload a file and once the file is uploaded, we will be displaying the same in a table with a download button and whenever this button is clicked the image will be downloaded in the browser. We will be using spring boot to ease our development. So let us get started with file upload with angular js and spring boot.

This article is based on AngularJs. You can visit my another article for latest version of Angular here - Angular Multiple File Upload

You can follow this article for Angular 8 integration with Spring Boot.

Project Structure

Following is the project structure which we will be creating.

spring-boot-angular-file-upload-strct

Following is the final output of what we will be implementing here.

spring-boot-angular-file-upload

Maven Dependencies

spring-boot-starter-parent: It provides useful Maven defaults. It also provides a dependency-management section so that you can omit version tags for existing dependencies.

spring-boot-starter-web: It includes all the dependencies required to create a web app. This will avoid lining up different spring common project versions.

spring-boot-starter-tomcat: It enable an embedded Apache Tomcat 7 instance, by default.This can be also marked as provided if you wish to deploy the war to any other standalone tomcat.

spring-boot-starter-data-jpa: It provides key dependencies for Hibernate, Spring Data JPA and Spring ORM.

pom.xml
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
</parent>
	
    <dependencies>
	    <dependency>
                   <groupId>org.springframework.boot</groupId>
                   <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
	    <dependency>
                   <groupId>org.springframework.boot</groupId>
                   <artifactId>spring-boot-starter-tomcat</artifactId>
             </dependency>
	     <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-data-jpa</artifactId>
	      </dependency>
	      <dependency>
                     <groupId>com.h2database</groupId>
                     <artifactId>h2</artifactId>
		</dependency>
		
    </dependencies>
	

Controller Class Implementation

This class has rest endpoints exposed for file upload.It has also some endpoints exposed to download the document.

DocumentController.java
@Controller
@RequestMapping(value = "/doc")
public class DocumentController {

    private static final Logger LOG = Logger.getLogger(DocumentController.class);
    
    @Autowired
    DocumentService documentService;

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public @ResponseBody ResponseMetadata handleFileUpload(@RequestParam(value="file") MultipartFile file) throws IOException {
        return documentService.save(file);
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public HttpEntity getDocument(@PathVariable Long id) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.IMAGE_JPEG);
        return new ResponseEntity(documentService.getDocumentFile(id), httpHeaders, HttpStatus.OK);
    }

    @RequestMapping(method = RequestMethod.GET)
    public @ResponseBody List getDocument() {
        return documentService.findAll();
    }

}

Defining Document Model Class

Document.java
@Entity
public class Document {

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Long id;

    @Column
    private String docName;

    @Column
    @Lob
    private byte[] file;
	
	//getters and setters goes here
 Other Interesting Posts
Spring Boot Angular Deployment
Spring Boot MVC Apache Tiles
Spring Boot Actuator Rest Endpoints Example
Spring MVC Pdf Excel View Resolver Example
Spring Boot Thymeleaf Example
Spring Boot Security Hibernate Example with complete JavaConfig
Securing REST API with Spring Boot Security Basic Authentication
Spring Boot Security Password Encoding using Bcrypt Encoder
Spring Security with Spring MVC Example Using Spring Boot
Websocket spring Boot Integration Without STOMP with complete JavaConfig

Service Implementation

DocumentServiceImpl.java
@Service
public class DocumentServiceImpl implements DocumentService {
    
    @Autowired
    private DocumentDao documentDao;

    @Override
    public ResponseMetadata save(MultipartFile file) throws IOException {

        Document doc = new Document();
        doc.setDocName(file.getOriginalFilename());
        doc.setFile(file.getBytes());
        documentDao.save(doc);
        ResponseMetadata metadata = new ResponseMetadata();
        metadata.setMessage("success");
        metadata.setStatus(200);
        return metadata;
    }

    @Override
    public byte[] getDocumentFile(Long id) {
      return documentDao.findOne(id).getFile();
    }

    @Override
    public List findAll() {
        return (List) documentDao.findAll();
    }

}

Rest of the server implementation are common codes which can be found in the source code below. Now let us move to client side.

Client Side Implementation

We have a simple .html file having a input type as file and a bootstrap table to display the uploaded file. It can be found in the source code. Let us take a look into our angular controller implementation.

The controller implementation is a very simple. We have one directive defined as fileModel that is responsible to set the uploaded file in a $scope variable. Rest of the implementation is very common. It has methods defined that is responsible for calling angular service methods which makes REST call to upload the document and read the document.

app.js
App.controller('docController',
    ['$scope', '$rootScope','docService','$http', function($scope, $rootScope, docService, $http) {

        $scope.file = '';

        $scope.upload = function(){
            var file = $scope.file;
            docService.saveDoc(file)
                .then(
                    function (response) {
                        alert("file uploaded successfully.");
                        $http.get("http://localhost:8080/doc/").success(
                            function(response) {
                                $rootScope.docList = response;
                            });
                    },
                    function (errResponse) {

                    }
                );
        }
    }
    ]);

App.constant('urls', {
    DOC_URL: 'http://localhost:8080/doc/'
});

App.directive('fileModel', [ '$parse', function($parse) {
    return {
        restrict : 'A',
        link : function(scope, element, attrs) {
            var model = $parse(attrs.fileModel);
            var modelSetter = model.assign;

            element.bind('change', function() {
                scope.$apply(function() {
                    modelSetter(scope, element[0].files[0]);
                });
            });
        }
    };
} ]);

App.run(function($rootScope, $http) {
    $http.get("http://localhost:8080/doc/").success(
        function(response) {
            $rootScope.docList = response;
        });
});

Defining Angular Service

DocumentService.js
'use strict';
var App = angular.module('uploadApp',[]);

App.factory('docService', ['$http', '$q', 'urls', function ($http, $q, urls) {

            var factory = {
                saveDoc: saveDoc,
                findDoc: findDoc
            };

            return factory;

            function saveDoc(file) {
                var deferred = $q.defer();
                var formData = new FormData();
                formData.append('file', file);

                $http.post(urls.DOC_URL+'upload', formData,{
                    transformRequest : angular.identity,
                    headers : {
                        'Content-Type' : undefined
                    }})
                    .then(
                        function (response) {
                            deferred.resolve(response.data);
                        },
                        function (errResponse) {
                            alert(errResponse.data.errorMessage);
                            deferred.reject(errResponse);
                        }
                    );
                return deferred.promise;
            };

            function findDoc(docId) {
                var deferred = $q.defer();
                $http.get(urls.DOC_URL + '/'+docId)
                    .then(
                        function (response) {
                            deferred.resolve(response.data);
                        },
                        function (errResponse) {
                            alert(errResponse.data.errorMessage);
                            deferred.reject(errResponse);
                        }
                    );
                return deferred.promise;
            }
        }
    ]);

And finally, following is our html page where we have used the file-model directive.

<html ng-app="uploadApp">
<head>
<meta charset="utf8" />
<title>Document Upload</title>
<link rel="stylesheet" href="styles/bootstrap.min.css">
</head>
<body ng-controller="docController">
	<div class="container">
		<div class="col-md-6">
		<div class="row">
            <h2>Upload Document</h2>
            <table class="table table-bordered">
                <tr>
                    <td><input type="file" class="custom-file-input" file-model="file"></td>

                </tr>
                <tr>
                    <td><button ng-click="upload()">Upload</button></td>
                </tr>
            </table>
        </div>
            <div class="row">
		        <table class="table table-bordered">
			<thead>
    			<tr>
    				<th>File Name</th>
    				<th>Action</th>
    			</tr>
			</thead>
			<tbody>
				<tr ng-repeat="doc in docList">
					<td><a href="/doc/{{doc.id}}">{{doc.docName}}</a></td>
					<td><a href="/doc/{{doc.id}}" target="_blank">Download</a></td>
				</tr>
			</tbody>		
		</table>
		</div>
	</div>
    </div>
    <script src="lib/plugin/jquery-2.2.1.min.js"></script>
	<script src="lib/plugin/bootstrap.min.js"></script>
	<script src="lib/plugin/angular.min.js"></script>
	<script src="documentService.js"></script>
	<script src="app.js"></script>
</body>
</html>

Conclusion

I hope this article served you that you were looking for. If you have anything that you want to add or share then please share it below in the comment section.

Download source

Share

If You Appreciate This, You Can Consider:

We are thankful for your never ending support.

About The Author

author-image
A technology savvy professional with an exceptional capacity to analyze, solve problems and multi-task. Technical expertise in highly scalable distributed systems, self-healing systems, and service-oriented architecture. Technical Skills: Java/J2EE, Spring, Hibernate, Reactive Programming, Microservices, Hystrix, Rest APIs, Java 8, Kafka, Kibana, Elasticsearch, etc.

Further Reading on Spring Boot