AngularJS CRUD应用程序与Spring Data REST

2023/05/18

1. 概述

在本教程中,我们创建一个简单的CRUD应用程序示例,使用AngularJS作为前端,使用Spring Data REST作为后端。

2. 创建REST数据服务

为了创建对持久性的支持,我们将使用Spring Data REST规范,使我们能够对数据模型执行CRUD操作。

你可以在Spring Data REST简介中找到有关如何设置REST端点的所有必要信息。在本文中,我们重用在前文中构建的项目。对于持久层,我们使用内存数据库H2。

作为数据模型,上一篇文章定义了一个WebsiteUser类,具有id、name和email属性以及一个名为UserRepository的Repository接口。

定义此接口指示Spring创建对公开REST集合资源和元素资源的支持。现在让我们仔细看看我们可用的端点,稍后我们将从AngularJS调用这些端点。

2.1 集合资源

我们可以通过端点/users获得所有用户的集合,可以使用GET方法调用此URL,并将返回以下形式的JSON对象:

{
    "_embedded": {
        "users": [
            {
                "name": "Bryan",
                "age": 20,
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/users/1"
                    },
                    "User": {
                        "href": "http://localhost:8080/users/1"
                    }
                }
            },
            ...
        ]
    }
}

2.2 元素资源

可以通过使用不同的HTTP方法和请求负载访问/users/{userID}形式的URL来操纵单个WebsiteUser对象。

为了检索WebsiteUser对象,我们可以使用GET方法访问/users/{userID},这将返回以下形式的JSON对象:

{
    "name": "Bryan",
    "email": "bryan@yahoo.com",
    "_links": {
        "self": {
            "href": "http://localhost:8080/users/1"
        },
        "User": {
            "href": "http://localhost:8080/users/1"
        }
    }
}

要添加新的WebsiteUser,我们需要使用POST方法调用/users。新WebsiteUser记录的属性将作为JSON对象添加到请求正文中:

{name: "Bryan", email: "bryan@yahoo.com"}

如果没有出现错误,此URL将返回状态码“201 CREATED”。

如果我们想要更新WebsiteUser记录的属性,我们需要使用PATCH方法和包含新值的请求主体调用URL “/users/{UserID}”:

{name: "Bryan", email: "bryan@gmail.com"}

要删除WebsiteUser记录,我们可以使用DELETE方法调用URL “/users/{UserID}”。如果没有错误,则返回状态码“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注解添加到Repository:

@CrossOrigin
@RepositoryRestResource(collectionResourceRel = "users", path = "users")
public interface UserRepository extends CrudRepository<WebsiteUser, Long> {
}

因此,在来自REST端点的每个响应中,都会添加一个Access-Control-Allow-Origin标头。

3. 创建AngularJS客户端

为了创建我们的CRUD应用程序的前端,我们将使用AngularJS,它可以简化前端应用程序的创建。为了使用AngularJS,我们首先需要在我们的html页面中包含angular.min.js文件:

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js">
</script>

接下来,我们需要创建一个Angular模块、控制器和服务,它将调用REST端点并显示返回的数据。

这些将被放置在一个名为app.js的 JavaScript 文件中,该文件也需要包含在users.html页面中:

<script src="view/app.js"></script>

3.1 Angular服务

首先,我们创建一个名为UserCRUDService的Angular服务,它将使用注入的AngularJS $http服务来调用服务器,每个调用都放置在一个单独的方法中。

下面是使用/users/{userID}端点定义通过id检索用户的方法:

app.service('UserCRUDService', ['$http', function ($http) {

    this.getUser = function getUser(userId) {
        return $http({
            method: 'GET',
            url: 'users/' + userId
        });
    }
}])

接下来,我们定义addUser方法,它向/users URL发出POST请求并在data属性中发送用户值:

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'
    });
}

所有这些Service方法都将由AngularJS控制器调用。

3.2 Angular控制器

我们将创建一个UserCRUDCtrl AngularJS控制器,它注入一个UserCRUDService并使用Service方法从服务器获取响应,处理成功和错误情况,并设置包含响应数据的$scope变量以在HTML页面中显示它.

让我们来看看getUser()函数,它调用getUser(userId) Service函数,并在成功和错误时定义两个回调方法。如果服务器请求成功,则将响应保存在user变量中;否则,将处理错误消息:

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()函数将调用相应的Service函数并处理响应:

$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元素包装在一个带有ng-controller属性集的div中:

<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">
 

4. 总结

在本教程中,我们演示了如何使用AngularJS和Spring Data REST规范创建CRUD应用程序。要运行该应用程序,你可以使用命令mvn spring-boot:run并访问URL /users.html。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章