From 8617faf9cf7005eb4014e07fc41364547e3716b0 Mon Sep 17 00:00:00 2001 From: lor6 Date: Mon, 27 Feb 2017 17:04:00 +0200 Subject: [PATCH] data rest crud, angular fe (#1199) * data rest crud, angular fe * fix formatting, remove extra imports * fix config * change student entity to employee * expose ids * update boot version, removes ids, check null id --- spring-rest-angular/pom.xml | 11 +- .../web/controller/EmployeeController.java | 14 ++ .../web/dao/EmployeeCRUDRepository.java | 13 ++ .../baeldung/web/dao/StudentRepository.java | 3 +- .../org/baeldung/web/entity/Employee.java | 57 +++++++ .../java/org/baeldung/web/main/MvcConfig.java | 36 +++++ .../baeldung/web/main/PersistenceConfig.java | 4 +- .../src/main/resources/db/sql/employees.sql | 16 ++ .../main/webapp/WEB-INF/pages/employee.html | 55 +++++++ .../src/main/webapp/view/app.js | 144 +++++++++++++++++- ...EmployeeCRUDRepositoryIntegrationTest.java | 47 ++++++ 11 files changed, 395 insertions(+), 5 deletions(-) create mode 100644 spring-rest-angular/src/main/java/org/baeldung/web/controller/EmployeeController.java create mode 100644 spring-rest-angular/src/main/java/org/baeldung/web/dao/EmployeeCRUDRepository.java create mode 100644 spring-rest-angular/src/main/java/org/baeldung/web/entity/Employee.java create mode 100644 spring-rest-angular/src/main/java/org/baeldung/web/main/MvcConfig.java create mode 100644 spring-rest-angular/src/main/resources/db/sql/employees.sql create mode 100644 spring-rest-angular/src/main/webapp/WEB-INF/pages/employee.html create mode 100644 spring-rest-angular/src/test/java/org/baeldung/web/service/EmployeeCRUDRepositoryIntegrationTest.java diff --git a/spring-rest-angular/pom.xml b/spring-rest-angular/pom.xml index 099867d19b..62ab03522d 100644 --- a/spring-rest-angular/pom.xml +++ b/spring-rest-angular/pom.xml @@ -11,7 +11,7 @@ org.springframework.boot spring-boot-starter-parent - 1.4.4.RELEASE + 1.5.1.RELEASE @@ -74,6 +74,15 @@ spring-boot-starter-test test + + org.springframework.boot + spring-boot-starter-data-rest + + + javax.servlet + jstl + 1.2 + diff --git a/spring-rest-angular/src/main/java/org/baeldung/web/controller/EmployeeController.java b/spring-rest-angular/src/main/java/org/baeldung/web/controller/EmployeeController.java new file mode 100644 index 0000000000..a8bfc254c3 --- /dev/null +++ b/spring-rest-angular/src/main/java/org/baeldung/web/controller/EmployeeController.java @@ -0,0 +1,14 @@ +package org.baeldung.web.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +public class EmployeeController { + + @RequestMapping(value = "/employeePage") + public String getEmployeePage() { + return "employee"; + } + +} diff --git a/spring-rest-angular/src/main/java/org/baeldung/web/dao/EmployeeCRUDRepository.java b/spring-rest-angular/src/main/java/org/baeldung/web/dao/EmployeeCRUDRepository.java new file mode 100644 index 0000000000..1e5f81ed45 --- /dev/null +++ b/spring-rest-angular/src/main/java/org/baeldung/web/dao/EmployeeCRUDRepository.java @@ -0,0 +1,13 @@ +package org.baeldung.web.dao; + +import java.util.List; + +import org.baeldung.web.entity.Employee; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.data.rest.core.annotation.RepositoryRestResource; + +@RepositoryRestResource(collectionResourceRel = "employee", path = "employees") +public interface EmployeeCRUDRepository extends CrudRepository { + List findByName(@Param("name") String name); +} diff --git a/spring-rest-angular/src/main/java/org/baeldung/web/dao/StudentRepository.java b/spring-rest-angular/src/main/java/org/baeldung/web/dao/StudentRepository.java index b1aafb583a..566d95da00 100644 --- a/spring-rest-angular/src/main/java/org/baeldung/web/dao/StudentRepository.java +++ b/spring-rest-angular/src/main/java/org/baeldung/web/dao/StudentRepository.java @@ -3,6 +3,7 @@ package org.baeldung.web.dao; import org.baeldung.web.entity.Student; import org.springframework.data.jpa.repository.JpaRepository; -public interface StudentRepository extends JpaRepository { +public interface StudentRepository extends JpaRepository +{ } diff --git a/spring-rest-angular/src/main/java/org/baeldung/web/entity/Employee.java b/spring-rest-angular/src/main/java/org/baeldung/web/entity/Employee.java new file mode 100644 index 0000000000..8d6831726c --- /dev/null +++ b/spring-rest-angular/src/main/java/org/baeldung/web/entity/Employee.java @@ -0,0 +1,57 @@ +package org.baeldung.web.entity; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class Employee implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + private long id; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private Integer age; + + public Employee() { + } + + public Employee(long id, String name, Integer age) { + super(); + this.id = id; + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + +} diff --git a/spring-rest-angular/src/main/java/org/baeldung/web/main/MvcConfig.java b/spring-rest-angular/src/main/java/org/baeldung/web/main/MvcConfig.java new file mode 100644 index 0000000000..b24aad1177 --- /dev/null +++ b/spring-rest-angular/src/main/java/org/baeldung/web/main/MvcConfig.java @@ -0,0 +1,36 @@ +package org.baeldung.web.main; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.view.InternalResourceViewResolver; + +@Configuration +@EnableWebMvc +@ComponentScan("org.baeldung.web.controller") +public class MvcConfig extends WebMvcConfigurerAdapter{ + + public MvcConfig(){ + super(); + } + + @Override + public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { + configurer.enable(); + } + + @Bean + public ViewResolver viewResolver() { + final InternalResourceViewResolver bean = new InternalResourceViewResolver(); + + bean.setPrefix("/WEB-INF/pages/"); + bean.setSuffix(".html"); + + return bean; + } + +} diff --git a/spring-rest-angular/src/main/java/org/baeldung/web/main/PersistenceConfig.java b/spring-rest-angular/src/main/java/org/baeldung/web/main/PersistenceConfig.java index df1240f270..8454ce155a 100644 --- a/spring-rest-angular/src/main/java/org/baeldung/web/main/PersistenceConfig.java +++ b/spring-rest-angular/src/main/java/org/baeldung/web/main/PersistenceConfig.java @@ -2,7 +2,7 @@ package org.baeldung.web.main; import javax.sql.DataSource; -import org.springframework.boot.orm.jpa.EntityScan; +import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -26,7 +26,7 @@ public class PersistenceConfig { @Bean public DataSource dataSource() { EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); - EmbeddedDatabase db = builder.setType(EmbeddedDatabaseType.HSQL).addScript("db/sql/data.sql").build(); + EmbeddedDatabase db = builder.setType(EmbeddedDatabaseType.HSQL).addScript("db/sql/data.sql").addScript("db/sql/employees.sql").build(); return db; } diff --git a/spring-rest-angular/src/main/resources/db/sql/employees.sql b/spring-rest-angular/src/main/resources/db/sql/employees.sql new file mode 100644 index 0000000000..366c0c309a --- /dev/null +++ b/spring-rest-angular/src/main/resources/db/sql/employees.sql @@ -0,0 +1,16 @@ +CREATE TABLE employee ( + id INTEGER PRIMARY KEY, + name VARCHAR(30), + age INTEGER +); + +INSERT INTO employee (id,name,age) +VALUES (1,'Bryan',20); +INSERT INTO employee (id,name,age) +VALUES (2,'Lisa',30); +INSERT INTO employee (id,name,age) +VALUES (3,'Laura',40); +INSERT INTO employee (id,name,age) +VALUES (4,'Alex',35); +INSERT INTO employee (id,name,age) +VALUES (5,'John',47); diff --git a/spring-rest-angular/src/main/webapp/WEB-INF/pages/employee.html b/spring-rest-angular/src/main/webapp/WEB-INF/pages/employee.html new file mode 100644 index 0000000000..510e981f25 --- /dev/null +++ b/spring-rest-angular/src/main/webapp/WEB-INF/pages/employee.html @@ -0,0 +1,55 @@ + + + + +Employee CRUD + + + + + + +
+ + + + + + + + + + + + + +
ID:
Name:
Age:
+

+ Get employee + Update employee + Add employee + Delete employee + +

+

{{message}}

+

{{errorMessage}}

+ +
+
+ Get all Employees

+ Name: + Get employees by name +

+
+ {{emp.name}} {{emp.age}} +
+
+ + \ No newline at end of file diff --git a/spring-rest-angular/src/main/webapp/view/app.js b/spring-rest-angular/src/main/webapp/view/app.js index a41026d2c3..9f78d5adf7 100644 --- a/spring-rest-angular/src/main/webapp/view/app.js +++ b/spring-rest-angular/src/main/webapp/view/app.js @@ -1,5 +1,5 @@ var app = angular.module('app', ['ui.grid','ui.grid.pagination']); - + app.controller('StudentCtrl', ['$scope','StudentService', function ($scope,StudentService) { var paginationOptions = { pageNumber: 1, @@ -53,4 +53,146 @@ app.service('StudentService',['$http', function ($http) { getStudents:getStudents }; +}]); + +app.controller('EmployeeCRUDCtrl', ['$scope','EmployeeCRUDService', function ($scope,EmployeeCRUDService) { + + $scope.updateEmployee = function () { + EmployeeCRUDService.updateEmployee($scope.employee.id,$scope.employee.name,$scope.employee.age) + .then(function success(response){ + $scope.message = 'Employee data updated!'; + $scope.errorMessage = ''; + }, + function error(response){ + $scope.errorMessage = 'Error updating Employee!'; + $scope.message = ''; + }); + } + + $scope.getEmployee = function () { + var id = $scope.employee.id; + EmployeeCRUDService.getEmployee($scope.employee.id) + .then(function success(response){ + $scope.employee = response.data; + $scope.employee.id = id; + $scope.message=''; + $scope.errorMessage = ''; + }, + function error (response ){ + $scope.message = ''; + if (response.status === 404){ + $scope.errorMessage = 'Employee not found!'; + } + else { + $scope.errorMessage = "Error getting Employee!"; + } + }); + } + + $scope.addEmployee = function () { + if ($scope.employee != null && $scope.employee.id) { + EmployeeCRUDService.addEmployee($scope.employee.id, $scope.employee.name, $scope.employee.age) + .then (function success(response){ + $scope.message = 'Employee added!'; + $scope.errorMessage = ''; + }, + function error(response){ + $scope.errorMessage = 'Error adding Employee!'; + $scope.message = ''; + }); + } + else { + $scope.errorMessage = 'Please enter an id!'; + $scope.message = ''; + } + } + + $scope.deleteEmployee = function () { + EmployeeCRUDService.deleteEmployee($scope.employee.id) + .then (function success(response){ + $scope.message = 'Employee deleted!'; + $scope.employee = null; + $scope.errorMessage=''; + }, + function error(response){ + $scope.errorMessage = 'Error deleting Employee!'; + $scope.message=''; + }) + } + + $scope.getAllEmployees = function () { + EmployeeCRUDService.getAllEmployees() + .then(function success(response){ + $scope.employees = response.data._embedded.employee; + $scope.message=''; + $scope.errorMessage = ''; + }, + function error (response ){ + $scope.message=''; + $scope.errorMessage = 'Error getting Employees!'; + }); + } + + $scope.getEmployeesByName = function () { + EmployeeCRUDService.getEmployeesByName($scope.name) + .then(function success(response){ + $scope.employees = response.data._embedded.employee; + $scope.message=''; + $scope.errorMessage = ''; + }, + function error (response ){ + $scope.message=''; + $scope.errorMessage = 'Error getting Employees!'; + }); + } + +}]); + +app.service('EmployeeCRUDService',['$http', function ($http) { + + this.getEmployee = function getEmployee(employeeId){ + return $http({ + method: 'GET', + url:'employees/'+employeeId + }); + } + + this.addEmployee = function addEmployee(id, name, age, gender){ + return $http({ + method: 'POST', + url:'employees', + data: {id:id, name:name, age:age} + }); + } + + this.deleteEmployee = function deleteEmployee(id){ + return $http({ + method: 'DELETE', + url: 'employees/'+id + }) + } + + this.updateEmployee = function updateEmployee(id,name,age){ + return $http({ + method: 'PATCH', + url: 'employees/'+id, + data: {name:name, age:age} + }) + } + + this.getAllEmployees = function getAllEmployees(){ + return $http({ + method: 'GET', + url:'employees' + }); + } + + this.getEmployeesByName = function getEmployeesByName(name){ + return $http({ + method: 'GET', + url:'employees/search/findByName', + params:{name:name} + }); + } + }]); \ No newline at end of file diff --git a/spring-rest-angular/src/test/java/org/baeldung/web/service/EmployeeCRUDRepositoryIntegrationTest.java b/spring-rest-angular/src/test/java/org/baeldung/web/service/EmployeeCRUDRepositoryIntegrationTest.java new file mode 100644 index 0000000000..57fe793596 --- /dev/null +++ b/spring-rest-angular/src/test/java/org/baeldung/web/service/EmployeeCRUDRepositoryIntegrationTest.java @@ -0,0 +1,47 @@ +package org.baeldung.web.service; + +import static org.junit.Assert.*; + +import org.baeldung.web.entity.Employee; +import org.baeldung.web.main.Application; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.DEFINED_PORT) +public class EmployeeCRUDRepositoryIntegrationTest { + + @Autowired + private TestRestTemplate template; + + private static final String EMPLOYEE_ENDPOINT = "http://localhost:8080/employees/"; + private static int EMPLOYEE_ID = 1; + private static int EMPLOYEE_AGE = 25; + + @Test + public void whenEmployeeCRUDOperations_thenCorrect() { + Employee Employee = new Employee(EMPLOYEE_ID, "Bryan", 20); + ResponseEntity postResponse = template.postForEntity(EMPLOYEE_ENDPOINT, Employee, Employee.class, ""); + assertEquals("status is not 201", HttpStatus.CREATED, postResponse.getStatusCode()); + + Employee.setAge(EMPLOYEE_AGE); + Employee patchResponse = template.patchForObject(EMPLOYEE_ENDPOINT + "/" + EMPLOYEE_ID, Employee, Employee.class); + assertEquals("age is not 25", Integer.valueOf(EMPLOYEE_AGE), patchResponse.getAge()); + + ResponseEntity getResponse = template.getForEntity(EMPLOYEE_ENDPOINT + "/" + EMPLOYEE_ID, Employee.class, ""); + assertEquals("status is not 200", HttpStatus.OK, getResponse.getStatusCode()); + + template.delete(EMPLOYEE_ENDPOINT + "/" + EMPLOYEE_ID); + + getResponse = template.getForEntity(EMPLOYEE_ENDPOINT + "/" + EMPLOYEE_ID, Employee.class, ""); + assertEquals("status is not 404", HttpStatus.NOT_FOUND, getResponse.getStatusCode()); + + } +}