1. Обзор
В этом руководстве мы собираемся создать пример простого приложения CRUD, используя AngularJS для внешнего интерфейса и Spring Data REST для внутреннего интерфейса.
2. Создание службы данных REST
Чтобы создать поддержку сохраняемости, мы будем использовать спецификацию Spring Data REST, которая позволит нам выполнять операции CRUD с моделью данных.
Вы можете найти всю необходимую информацию о том, как настроить конечные точки REST во введении к Spring Data REST . В этой статье мы будем повторно использовать существующий проект, который мы настроили для вводного руководства.
Для сохранения мы будем использовать базу данных H2
в памяти.
В качестве модели данных в предыдущей статье определяется класс WebsiteUser со свойствами
id
, name
и email
, а также интерфейс репозитория с именем UserRepository
.
Определение этого интерфейса указывает Spring создать поддержку для предоставления ресурсов коллекции REST и ресурсов элементов. Давайте подробнее рассмотрим конечные точки, доступные нам сейчас, которые мы позже будем вызывать из AngularJS
.
2.1. Ресурсы коллекции
Список всех пользователей будет доступен нам в конечной точке /users
. Этот URL-адрес можно вызвать с помощью метода GET, и он вернет объекты JSON в форме:
{
"_embedded" : {
"users" : [ {
"name" : "Bryan",
"age" : 20,
"_links" : {
"self" : {
"href" : "http://localhost:8080/users/1"
},
"User" : {
"href" : "http://localhost:8080/users/1"
}
}
},
...
]
}
}
2.2. Ресурсы предметов
Одним объектом WebsiteUser
можно управлять, обращаясь к URL-адресам формы /users/{userID}
с помощью различных методов HTTP и полезных данных запроса.
Для получения объекта WebsiteUser
мы можем получить доступ к /users/{userID}
с помощью метода GET. Это возвращает объект JSON формы:
{
"name" : "Bryan",
"email" : "bryan@yahoo.com",
"_links" : {
"self" : {
"href" : "http://localhost:8080/users/1"
},
"User" : {
"href" : "http://localhost:8080/users/1"
}
}
}
Чтобы добавить нового WebsiteUser
, нам нужно будет вызвать /users
методом POST. Атрибуты новой записи WebsiteUser
будут добавлены в тело запроса в виде объекта JSON:
{name: "Bryan", email: "bryan@yahoo.com"}
Если ошибок нет, этот URL возвращает код состояния 201 CREATED.
Если мы хотим обновить атрибуты записи WebsiteUser
, нам нужно вызвать URL-адрес /users/{UserID}
с методом PATCH и телом запроса, содержащим новые значения:
{name: "Bryan", email: "bryan@gmail.com"}
Чтобы удалить запись WebsiteUser
, мы можем вызвать URL-адрес /users/{UserID}
с помощью метода DELETE. Если ошибок нет, возвращается код состояния 204 NO CONTENT.
2.3. Конфигурация MVC
Мы также добавим базовую конфигурацию MVC для отображения html-файлов в нашем приложении:
@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
public MvcConfig(){
super();
}
@Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Bean
WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> enableDefaultServlet() {
return (factory) -> factory.setRegisterDefaultServlet(true);
}
}
2.4. Разрешение запросов между источниками
Если мы хотим развернуть внешнее приложение AngularJS
отдельно от REST API, нам нужно включить запросы между источниками.
В Spring Data REST добавлена поддержка этого, начиная с версии 1.5.0.RELEASE. Чтобы разрешить запросы из другого домена, все, что вам нужно сделать, это добавить аннотацию @CrossOrigin
в репозиторий:
@CrossOrigin
@RepositoryRestResource(collectionResourceRel = "users", path = "users")
public interface UserRepository extends CrudRepository<WebsiteUser, Long> {}
В результате к каждому ответу от конечных точек REST будет добавлен заголовок Access-Control-Allow-Origin
.
3. Создание клиента AngularJS
Для создания интерфейса нашего CRUD-приложения мы будем использовать AngularJS
— хорошо известную среду JavaScript, упрощающую создание интерфейсных приложений.
Чтобы использовать AngularJS
, нам сначала нужно включить файл angular.min.js
в нашу html-страницу, которая будет называться users.html
:
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js">
</script>
Далее нам нужно создать модуль, контроллер и службу Angular, которые будут вызывать конечные точки REST и отображать возвращенные данные.
Они будут помещены в файл JavaScript с именем app.js
, который также необходимо включить на страницу users.html
:
<script src="view/app.js"></script>
3.1. Угловой сервис
Во-первых, давайте создадим службу Angular с именем UserCRUDService
, которая будет использовать внедренную службу AngularJS
$http
для выполнения вызовов на сервер. Каждый вызов будет помещен в отдельный метод.
Давайте взглянем на определение метода получения пользователя по идентификатору с помощью конечной точки /users/{userID}
:
app.service('UserCRUDService', [ '$http', function($http) {
this.getUser = function getUser(userId) {
return $http({
method : 'GET',
url : 'users/' + userId
});
}
} ]);
Далее давайте определим метод addUser
, который делает POST-запрос к URL-адресу /users
и отправляет пользовательские значения в атрибуте данных :
this.addUser = function addUser(name, email) {
return $http({
method : 'POST',
url : 'users',
data : {
name : name,
email: email
}
});
}
Метод updateUser
аналогичен приведенному выше, за исключением того, что он будет иметь параметр id
и выполнять запрос PATCH:
this.updateUser = function updateUser(id, name, email) {
return $http({
method : 'PATCH',
url : 'users/' + id,
data : {
name : name,
email: email
}
});
}
Метод удаления записи WebsiteUser
сделает запрос DELETE:
this.deleteUser = function deleteUser(id) {
return $http({
method : 'DELETE',
url : 'users/' + id
})
}
И, наконец, давайте взглянем на методы получения всего списка пользователей:
this.getAllUsers = function getAllUsers() {
return $http({
method : 'GET',
url : 'users'
});
}
Все эти сервисные методы будут вызываться контроллером AngularJS .
3.2. Угловой контроллер
Мы создадим контроллер UserCRUDCtrl
AngularJS
, в который будет внедрен UserCRUDService
и который будет использовать методы службы для получения ответа от сервера, обработки случаев успеха
и ошибок и установки переменных
$scope
, содержащих данные ответа, для их отображения на странице HTML. .
Давайте взглянем на функцию getUser()
, которая вызывает сервисную функцию getUser(userId)
и определяет два метода обратного вызова в случае успеха и ошибки. Если запрос сервера выполнен успешно, то ответ сохраняется в пользовательской
переменной; в противном случае обрабатываются сообщения об ошибках:
app.controller('UserCRUDCtrl', ['$scope','UserCRUDService',
function ($scope,UserCRUDService) {
$scope.getUser = function () {
var id = $scope.user.id;
UserCRUDService.getUser($scope.user.id)
.then(function success(response) {
$scope.user = response.data;
$scope.user.id = id;
$scope.message='';
$scope.errorMessage = '';
},
function error (response) {
$scope.message = '';
if (response.status === 404){
$scope.errorMessage = 'User not found!';
}
else {
$scope.errorMessage = "Error getting user!";
}
});
};
}]);
Функция addUser()
вызовет соответствующую сервисную функцию и обработает ответ:
$scope.addUser = function () {
if ($scope.user != null && $scope.user.name) {
UserCRUDService.addUser($scope.user.name, $scope.user.email)
.then (function success(response){
$scope.message = 'User added!';
$scope.errorMessage = '';
},
function error(response){
$scope.errorMessage = 'Error adding user!';
$scope.message = '';
});
}
else {
$scope.errorMessage = 'Please enter a name!';
$scope.message = '';
}
}
Функции updateUser()
и deleteUser()
аналогичны приведенным выше:
$scope.updateUser = function () {
UserCRUDService.updateUser($scope.user.id,
$scope.user.name, $scope.user.email)
.then(function success(response) {
$scope.message = 'User data updated!';
$scope.errorMessage = '';
},
function error(response) {
$scope.errorMessage = 'Error updating user!';
$scope.message = '';
});
}
$scope.deleteUser = function () {
UserCRUDService.deleteUser($scope.user.id)
.then (function success(response) {
$scope.message = 'User deleted!';
$scope.User = null;
$scope.errorMessage='';
},
function error(response) {
$scope.errorMessage = 'Error deleting user!';
$scope.message='';
});
}
И, наконец, давайте определим функцию, которая извлекает список пользователей и сохраняет его в переменной users :
$scope.getAllUsers = function () {
UserCRUDService.getAllUsers()
.then(function success(response) {
$scope.users = response.data._embedded.users;
$scope.message='';
$scope.errorMessage = '';
},
function error (response) {
$scope.message='';
$scope.errorMessage = 'Error getting users!';
});
}
3.3. HTML-страница
На странице users.html
будут использоваться функции контроллера, определенные в предыдущем разделе, и сохраненные переменные.
Во-первых, чтобы использовать модуль Angular, нам нужно установить свойство ng-app :
<html ng-app="app">
Затем, чтобы не вводить UserCRUDCtrl.getUser()
каждый раз, когда мы используем функцию контроллера, мы можем обернуть наши HTML-элементы в div
с установленным свойством ng-controller :
<div ng-controller="UserCRUDCtrl">
Давайте создадим `форму, которая будет вводить и отображать значения для объекта
WebiteUser , которым мы хотим манипулировать. У каждого из них будет установлен атрибут
ng-model` , который привязывает его к значению атрибута:
<table>
<tr>
<td width="100">ID:</td>
<td><input type="text" id="id" ng-model="user.id" /></td>
</tr>
<tr>
<td width="100">Name:</td>
<td><input type="text" id="name" ng-model="user.name" /></td>
</tr>
<tr>
<td width="100">Age:</td>
<td><input type="text" id="age" ng-model="user.email" /></td>
</tr>
</table>
Привязка ввода id к переменной
user.id
, например, означает, что всякий раз, когда значение ввода изменяется, это значение устанавливается в переменной user.id
и наоборот.
Затем давайте используем атрибут ng-click
, чтобы определить ссылки, которые будут запускать вызов каждой определенной функции контроллера CRUD:
<a ng-click="getUser(user.id)">Get User</a>
<a ng-click="updateUser(user.id,user.name,user.email)">Update User</a>
<a ng-click="addUser(user.name,user.email)">Add User</a>
<a ng-click="deleteUser(user.id)">Delete User</a>
Наконец, выведем список пользователей целиком и по именам:
<a ng-click="getAllUsers()">Get all Users</a><br/><br/>
<div ng-repeat="usr in users">
{{usr.name}} {{usr.email}}
4. Вывод
В этом руководстве мы показали, как вы можете создать приложение CRUD, используя AngularJS
и спецификацию Spring Data REST .
Полный код приведенного выше примера можно найти в проекте GitHub .
Чтобы запустить приложение, вы можете использовать команду mvn spring-boot:run
и получить доступ к URL-адресу /users.html
.