English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
In this section, we will create a File Upload Web application. This application includes a registration form. In this integration, we use Spring to handle the backend part, and Angular to handle the frontend part.
Once we deploy the application on the server, a registration page will be generated. Users can fill in the required information and upload images. Remember, the image size must not exceed1 MB.
Use any IDE to develop Spring and Hibernate projects. It could be MyEclipse/Eclipse/Netbeans. Here, we are using Eclipse. MySQL for databases. Use any IDE to develop Angular projects. It could be Visual Studio Code/Sublime. Here, we are using Visual Studio Code. Server: Apache Tomcat/JBoss/Glassfish/Weblogic/Websphere.
Here, we use the following technologies:
Spring5 Hibernate5 Angular6 MYSQL
Let's create the database fileuploadexample No need to create tables, as Hibernate will create them automatically.
Let's see the Spring directory structure we need to follow:
To develop a file upload application, please follow these steps: -
Add the dependencies to the pom.xml file.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.w3codebox</<groupId> <artifactId>FileUploadExample</<artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</<version> <name>FileUploadExample Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <springframework.version>5.0.6.RELEASE</springframework.version> <hibernate.version>5.2.16.Final</hibernate.version> <mysql.connector.version>5.1.45</mysql.connector.version> <c3po.version>0.9.5.2</c3po.version> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <!-- Spring --> <dependency> <groupId>org.springframework</groupId>/<groupId> <artifactId>spring</artifactId>-webmvc/<artifactId> <version>${springframework.version}</version>/<version> </<dependency> <dependency> <groupId>org.springframework</groupId>/<groupId> <artifactId>spring</artifactId>-tx/<artifactId> <version>${springframework.version}</version>/<version> </<dependency> <dependency> <groupId>org.springframework</groupId>/<groupId> <artifactId>spring</artifactId>-orm/<artifactId> <version>${springframework.version}</version>/<version> </<dependency> <!-- Add Jackson for JSON converters --> <dependency> <groupId>com.fasterxml.jackson.core</groupId>/<groupId> <artifactId>jackson</artifactId>-databind/<artifactId> <version>2.9.5</<version> </<dependency> <!-- Hibernate --> <dependency> <groupId>org.hibernate</groupId>/<groupId> <artifactId>hibernate</artifactId>-core/<artifactId> <version>${hibernate.version}</version>/<version> </<dependency> <!-- MySQL --> <dependency> <groupId>mysql</groupId>/<groupId> <artifactId>mysql</artifactId>-connector-java/<artifactId> <version>${mysql.connector.version}</version>/<version> </<dependency> <!-- C3PO --> <dependency> <groupId>com.mchange</groupId>/<groupId> <artifactId>c</artifactId>3p0</version>/<artifactId> <version>${c</version>3po.version</version>/<version> </<dependency> <!-- Servlet+JSP+JSTL --> <dependency> <groupId>javax.servlet</groupId>/<groupId> <artifactId>javax.servlet</artifactId>-api/<artifactId> <version>3.1.0</<version> </<dependency> <dependency> <groupId>javax.servlet.jsp</groupId>/<groupId> <artifactId>javax.servlet.jsp</artifactId>-api/<artifactId> <version>2.3.1</<version> </<dependency> <dependency> <groupId>javax.servlet</groupId>/<groupId> <artifactId>jstl</artifactId>/<artifactId> <version>1.2</<version> </<dependency> <!-- to compensate for java 9 not including jaxb --> <dependency> <groupId>javax.xml.bind</groupId>/<groupId> <artifactId>jaxb</artifactId>-api/<artifactId> <version>2.3.0</<version> </<dependency> <!-- JUnit dependency --> <dependency> <groupId>junit</groupId>/<groupId> <artifactId>junit</artifactId>/<artifactId> <version>3.8.1</<version> <scope>test</scope>/scope> </<dependency> <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload --> <dependency> <groupId>commons</groupId>-fileupload</groupId>/<groupId> <artifactId>commons-fileupload</groupId>/<artifactId> <version>1.3</<version> </<dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 --> <dependency> <groupId>org.apache.commons</groupId>/<groupId> <artifactId>commons-dbcp2</<artifactId> <version>2.0</<version> </<dependency> </<dependencies> <build> <finalName>FileUploadExample</finalName> </build> </project>
Create configuration class
We perform configuration based on annotations instead of XML. Therefore, we create two classes and specify the required configuration within them.
DemoAppConfig.java
package com.w;3codebox.FileUploadExample.config; import java.beans.PropertyVetoException; import java.io.IOException; import java.util.Properties; import javax.sql.DataSource; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.orm.hibernate;5.HibernateTransactionManager; import org.springframework.orm.hibernate;5.LocalSessionFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.web.multipart.commons.CommonsMultipartResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import com.mchange.v2.c3p0.ComboPooledDataSource; @Configuration @EnableWebMvc @EnableTransactionManagement @ComponentScan("com.w")3codebox.FileUploadExample" @PropertySource(value = { "classpath:persistence" })-@PropertySource(value = { "classpath:application.properties" }) @PropertySource(value = { "classpath:persistence" })-@PropertySource(value = { "classpath:application.properties" }) @PropertySource(value = { "classpath:application.properties" }) public class DemoAppConfig implements WebMvcConfigurer { @Autowired private Environment env; @Bean public DataSource myDataSource() { // create connection pool ComboPooledDataSource myDataSource = new ComboPooledDataSource(); // set the jdbc driver try { myDataSource.setDriverClass("com.mysql.jdbc.Driver"); } catch (PropertyVetoException exc) { throw new RuntimeException(exc); } // set database connection props myDataSource.setJdbcUrl(env.getProperty("jdbc.url")); myDataSource.setUser(env.getProperty("jdbc.user")); myDataSource.setPassword(env.getProperty("jdbc.password")); // set connection pool props myDataSource.setInitialPoolSize(getIntProperty("connection.pool.initialPoolSize")); myDataSource.setMinPoolSize(getIntProperty("connection.pool.minPoolSize")); myDataSource.setMaxPoolSize(getIntProperty("connection.pool.maxPoolSize")); myDataSource.setMaxIdleTime(getIntProperty("connection.pool.maxIdleTime")); return myDataSource; } private Properties getHibernateProperties() { // set hibernate properties Properties props = new Properties(); props.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); props.setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql")); props.setProperty("hibernate.format_sql", env.getProperty("hibernate.format_sql")); props.setProperty("hibernate.hbm"2ddl.auto, env.getProperty("hibernate.hbm"2ddl")); return props; } // need a helper method // read environment property and convert to int private int getIntProperty(String propName) { String propVal = env.getProperty(propName); // now convert to int int intPropVal = Integer.parseInt(propVal); return intPropVal; } @Bean public LocalSessionFactoryBean sessionFactory(){ // create session factorys LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); // set the properties sessionFactory.setDataSource(myDataSource()); sessionFactory.setPackagesToScan(env.getProperty("hibernate.packagesToScan")); sessionFactory.setHibernateProperties(getHibernateProperties()); return sessionFactory; } @Bean @Autowired public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) { // setup transaction manager based on session factory HibernateTransactionManager txManager = new HibernateTransactionManager(); txManager.setSessionFactory(sessionFactory); return txManager; } @Bean(name="multipartResolver") public CommonsMultipartResolver getResolver() throws IOException{ CommonsMultipartResolver resolver = new CommonsMultipartResolver(); //Set the maximum allowed size (in bytes) for each individual file. // resolver.setMaxUploadSize(5242880);//5MB resolver.setMaxUploadSize(524288);//0.5MB //You may also set other available properties. return resolver; } }
MySpringMvcDispatcherServletInitializer.java
package com.w;3codebox.FileUploadExample.config; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class MySpringMvcDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { // TOdo Auto-generated method stub return null; } @Override protected Class<?>[] getServletConfigClasses() { return new Class[]{DemoAppConfig.class}; } @Override protected String[] getServletMappings() { return new String[]{"/"}; } }
Create entity class
Here, we will create an Entity/POJO (Plain Old Java Object) class.
UserDetail.java
package com.w;3codebox.FileUploadExample.entity; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="user_detail") public class UserDetail { @Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name="user_id") private int userId; @Column(name="email_id") public String emailId; @Column(name="name") public String name; @Column(name="profile_image") public String profileImage; public UserDetail() { } public UserDetail(int userId, String emailId, String name, String profileImage) { super(); this.userId = userId; this.emailId = emailId; this.name = name; this.profileImage = profileImage; } public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getEmailId() { return emailId; } public void setEmailId(String emailId) { this.emailId = emailId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getProfileImage() { return profileImage; } public void setProfileImage(String profileImage) { this.profileImage = profileImage; } @Override public String toString() { return "UserDetail [userId=" + userId + "emailId=" + emailId + "name=" + name + "profileImage=" + profileImage + "]"; } }
Create DAO interface
Here, we are creating a DAO interface to perform database-related operations.
UserDAO.java
package com.w;3codebox.FileUploadExample.DAO.interfaces; import com.w3codebox.FileUploadExample.entity.UserDetail; public interface UserDAO { public int saveUser(UserDetail userDetail); public UserDetail getUserDetail(int userId); public int updateProfileImage(String profileImage, int userID); }
Create DAO interface implementation class
UserDAOImpl.java
package com.w;3codebox.FileUploadExample.DAO.implementation; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.query.Query; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import com.w3codebox.FileUploadExample.DAO.interfaces.UserDAO; import com.w3codebox.FileUploadExample.entity.UserDetail; @Repository("userDAO") public class UserDAOImpl implements UserDAO { @Autowired SessionFactory sessionFactory; public int saveUser(UserDetail userDetail) { Session session = null; try { session = sessionFactory.getCurrentSession(); int status = (Integer) session.save(userDetail); return status; } catch(Exception exception) { System.out.println("Exception in saving data into the database") + exception); return 0; } finally { session.flush(); } } public UserDetail getUserDetail(int userId) { Session session = null; try { session = sessionFactory.getCurrentSession(); UserDetail userDetail = session.get(UserDetail.class, userId); return userDetail; } catch(Exception exception) { System.out.println("Exception in saving data into the database ") + exception); return null; } finally { session.flush(); } } public int updateProfileImage(String profileImage, int userID) { Session session = sessionFactory.getCurrentSession(); int result; try { Query<UserDetail> query = session.createQuery("update UserDetail set profileImage = :profileImage where userId=:userID "); query.setParameter("profileImage", profileImage); query.setParameter("userID", userID); result = query.executeUpdate(); if(result > 0) { return result; } else return -5; } catch(Exception exception) { System.out.println("Error while updating profileImage from DAO :: "); + exception.getMessage()); return -5; } finally { session.flush(); } } }
Create service layer interface
Here, we are creating a service layer interface, acting as a bridge between the DAO and entity class.
UserService.java
package com.w;3codebox.FileUploadExample.service.interfaces; import javax.servlet.http.HttpSession; import org.springframework.web.multipart.MultipartFile; import com.w3codebox.FileUploadExample.entity.UserDetail; public interface UserService { public int saveUser(UserDetail userDetail); public UserDetail getUserDetail(int userId); public int store(MultipartFile file, int userID, HttpSession session); }
Create a service layer implementation class
UserServiceImpl.java
package com.w;3codebox.FileUploadExample.service.implementation; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import javax.servlet.http.HttpSession; import javax.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import com.w3codebox.FileUploadExample.DAO.interfaces.UserDAO; import com.w3codebox.FileUploadExample.entity.UserDetail; import com.w3codebox.FileUploadExample.service.interfaces.UserService; @Service("userService") public class UserServiceImpl implements UserService { @Autowired private UserDAO userDAO; @Transactional public int saveUser(UserDetail userDetail) { return userDAO.saveUser(userDetail); } @Transactional public UserDetail getUserDetail(int userId) { return userDAO.getUserDetail(userId); } @Transactional public int store(MultipartFile file, int userID, HttpSession session) { Path rootLocation = Paths.get(session.getServletContext().getRealPath("/resources/images"); System.out.println("rootLocation == ") + rootLocation); UserDetail userDetail = this.getUserDetail(userID); String nameExtension[] = file.getContentType().split("/"); String profileImage = userID + "." + nameExtension[1]; System.out.println("ProfileImage :: ") + profileImage); if(userDetail.getUserId() > 0) { if(userDetail.getProfileImage() == null || userDetail.getProfileImage() == " " || userDetail.getProfileImage() == "") { try { Files.copy(file.getInputStream(), rootLocation.resolve(profileImage)); int result = userDAO.updateProfileImage(profileImage, userID); if(result > 0) return result; else return -5; } catch(Exception exception) { System.out.println("error while uploading image catch:: ") + exception.getMessage()); return -5; } } else { try { //Files.delete(rootLocation.resolve(profileImage)); Files.delete(rootLocation.resolve(userDetail.getProfileImage())); Files.copy(file.getInputStream(), rootLocation.resolve(profileImage)); int result = userDAO.updateProfileImage(profileImage, userID); if(result > 0) return result; else return -5; } catch(Exception exception) { System.out.println("Error while uploading image when image is already exists :: "); + exception.getMessage()); return -5; } } } else { return 0; } } }
Create a controller class
UserController.java
package com.w;3codebox.FileUploadExample.restController; import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import com.w3codebox.FileUploadExample.entity.UserDetail; import com.w3codebox.FileUploadExample.service.interfaces.UserService; @RestController @RequestMapping("/api @CrossOrigin(origins = "http://localhost:42"00", allowedHeaders = ""*") public class UserController { @Autowired private UserService userService; @PostMapping("/saveUser) public int saveUser(@RequestBody UserDetail userDetail) { return userService.saveUser(userDetail); } @PostMapping("/uploadImage/{userId}" public int handleFileUpload(@PathVariable int userId, @RequestParam("file") MultipartFile file, HttpSession session) { return userService.store(file, userId, session); } }
property file creation
Here, we are creating the src/main/resources Internally create property files.
application.properties
spring.http.multipart.max-file-size=1024KB spring.http.multipart.max-request-size=1024KB
persistence-mysql.properties
## JDBC connection properties # jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/fileuploadexample?useSSL=false jdbc.user=root jdbc.password= ## Connection pool properties # connection.pool.initialPoolSize=5 connection.pool.minPoolSize=5 connection.pool.maxPoolSize=20 connection.pool.maxIdleTime=3000 ## Hibernate properties # <!-- hibernate.dialect=org.hibernate.dialect.MySQLDialect --> hibernate.dialect=org.hibernate.dialect.MySQL5Dialect hibernate.show_sql=true hibernate.format_sql=true hibernate.hbm2ddl=update hibernate.packagesToScan=com.w3codebox.FileUploadExample.entity
Let's take a look at the Angular directory structure we need to follow:
Create an Angular project
Let's use the following command to create an Angular project:
ng new FileUploadExample
Here, FileUploadExample Is the name of the project.
Install the guide program in the project using the following command.
npm install [email protected] --save
Now, include the following code in the style.css file.
@import "~bootstrap/dist/css/bootstrap.css";
Generate component
Open the project in Visual Studio and then use the following command to generate Angular components:
ng g c Register
We also use the following command: -
ng gs services/UserDetail
Edit app.module.ts File Import ReactiveFormsModule -Here, we will import ReactiveFormsModule for reactive forms, and specify it in the imports array. Import HttpModule -Here, we will import for server requests HttpModule , and specify it in the imports array. Register the service class-Here, we mention the service class in the providers array.
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; // import ReactiveFormsModule for reactive form import { ReactiveFormsModule } from '@angular/forms'; import { AppComponent } from './/app.component'; import { RegisterComponent } from './/register/register.component'; import { HttpModule } from '@angular/http'; @NgModule({ declarations: [ AppComponent, RegisterComponent ], imports: [ BrowserModule, ReactiveFormsModule, HttpModule ], providers: [], bootstrap: [AppComponent], }) export class AppModule { }
Edit app.component.html File
<app-register></app-register>
create UserDetail.ts class
Let's use the following command to create a class: -
ng g class/UserDetail
Now, in UserDetail specify required fields in the class.
export class UserDetail { emailId: string; name: string; profileImage: string; }
The purpose of this class is to map specified fields with the fields of Spring entity classes.
Edit user-detail.service.ts File
import { Injectable } from '@angular/core'; import { UserDetail } from '../classes/user-detail'; import { Observable } from 'rxjs'; import { Http, RequestOptions, Headers } from '@angular/http'; @Injectable({ providedIn: 'root' }) export class UserDetailService { // Base URL private baseUrl = "http://localhost:8080/FileUploadExample/api/"; constructor(private http: Http) { } saveData(userDetail: UserDetail): Observable<any> { let url = this.baseUrl + "saveUser"; return this.http.post(url, userDetail); } uploadFile(file: File, id: number): Observable<any> { let url = this.baseUrl + "uploadImage/" + id ; const formdata: FormData = new FormData(); formdata.append('file', file); return this.http.post(url, formdata); } }
Edit register.component.ts File
import { Component, OnInit } from '@angular/core'; import { FormGroup, FormControl, Validators } from '@angular/forms'; import { UserDetail } from '../classes/user-detail'; import { UserDetailService } from '../services/user-detail.service'; import { jsonpFactory } from '@angular/http/src/http_module'; @Component({ selector: 'app-register', templateUrl: '.'/register.component.html, styleUrls: ['./register.component.css] }) export class RegisterComponent implements OnInit { selectedFiles: FileList; currentFileUpload: File; private userDetail = new UserDetail(); constructor(private userDetailService: UserDetailService) { } ngOnInit() { } selectFile(event) { const file = event.target.files.item(0); if (file.type.match('image.*)) { var size = event.target.files[0].size; if(size > 1000000) { alert("size must not exceeds 1 MB); this.form.get('profileImage').setValue(""); } else { this.selectedFiles = event.target.files; } } else { alert('invalid format!'); } } // create the form object. form = new FormGroup({ fullName : new FormControl('', Validators.required), email : new FormControl('', Validators.required), profileImage : new FormControl() ); AdminForm(AdminInformation) { this.userDetail.name = this.FullName.value; this.userDetail.emailId = this.Email.value; console.log(this.userDetail); this.userDetailService.saveData(this.userDetail).subscribe( response => {}} let result = response.json(); console.log(result); if(result > 0 ) { if(this.selectedFiles != null) { this.currentFileUpload = this.selectedFiles.item(0); console.log(this.currentFileUpload); this.userDetailService.uploadFile(this.currentFileUpload, result).subscribe( res => { let re = res.json(); if(re > 0) { alert("file upload successfully "); this.form.get('fullName').setValue(""); this.form.get('email').setValue(""); this.form.get('profileImage').setValue(""); } else{ alert("error while uploading file details"); } }, err => { alert("error while uploading file details"); } ); } } }, error => { console.log("error while saving data in the DB"); } ); } get FullName(){ return this.form.get('fullName'); } get Email(){ return this.form.get('email'); } }
Edit register.component.html File
<h2>Registration form</h2> <form [formGroup]="form" #AdminInformation (ngSubmit)="AdminForm(AdminInformation)"> <div class="row"> <div class=" col-md-offset-1 col-md-4"> <label for="fullName"> Name </label> <input formControlName="fullName" class="form-control" type="text"> </div> </div> <div class="row"> <div class=" col-md-offset-1 col-md-4"> <label for="email"> Email </label> <input formControlName="email" class="form-control" type="text"> </div> </div> <div class="row"> <div class=" col-md-offset-1 col-md-4"> <label for="profileImage">Upload Image</label> <input formControlName="profileImage" class="form-control" type="file" (change)="selectFile($event)"> </div> </div> <div class="row" style="margin-top: 40px;"> <div class="col-md-offset-1 col-md-4"> <button class="btn btn-md btn-primary btn-style" >Save</button> </div> </div> </form>
After completion, provide the URL http: //localhost: 4200/Browser. The following web page appears:
Now, we can fill in the required information and select the file to be uploaded.