Spring Boot&Angular 5&Spring Data&Rest示例(CRUD)

本教程提供了Spring Boot,Angular 5和spring数据的完整实现,以示例为例构建端到端的单页Java Web应用程序。我们将使用Spring Boot 1.5公开REST API和angular5并通过路由来构建我们的客户端不仅要消耗服务器公开的API,还要将MySql数据库与后端代码集成以进行CRUD操作,我们将使用angular CLI生成angular项目,并使用spring boot初始化程序生成spring boot项目。在本文中,您将能够使用CRUD操作构建用户管理应用程序,该应用程序可以部署到独立的tomcat或将客户端和服务器部署到具有跨源请求的其他服务器。

在下一篇文章中,我们将研究通过maven将spring boot和angular 5应用程序打包到一个war文件中并部署到独立tomcat的不同方法。 另外,您可能对将这个应用程序与带有Spring Boot Security的Angular5 JWT身份验证集成感兴趣

Angular 5功能

1. Angular 5更快,更轻便且易于使用。

2.材料设计功能和带有构建优化器的改进的编译器

3.引入了新的HttpClientModule,它是对现有HttpModule的完整重写。

4. TypeScript 2.4支持。

5.响应式表单支持

环境设定

我们将要构建的应用程序有两个不同的部分,即客户端和服务器,因此,环境设置也针对每个部分。

Angular5环境设置

Angular 5提供了一个漂亮的工具-Angular CLI,以开始使用Angular。 在这里,我们将使用相同的工具来生成示例的angular应用程序,然后对其进行修改以符合我们的要求。要开始使用Angular CLI,需要安装节点才能使用NPM工具。 您可以通过单击节点-v来检查节点上是否已安装节点。 在我的机器上,我得到以下结果。

如果尚未安装, 请先访问NodeJs官方网站进行安装。完成后,遍历您的工作区位置并执行以下命令来安装angular cli并生成示例angular项目。

npm install -g @angular/cli
ng new portal-app

完成此操作后,您可以遍历该位置,并看到一个文件夹portal-app已创建,其中包含由angular cli命令生成的所有文件和文件夹,以开始使用angular5。现在,您可以打开自己喜欢的编辑器以导入项目我将这个项目导入IntellijIdea中,并得到如下结构:

这里要检查的一件事是,如果您已经使用sudo命令安装了NodeJ,那么在安装angular cli时可能会遇到以下权限问题。为避免这种情况,建议始终在安装任何新命令时使用brew命令软件。

如果您遇到此问题,请提供对文件夹-/ usr / local / lib / node_modules的读/写访问权限,或按照此处的说明进行操作-Mac 支持

对于Windows用户,可以使用git命令行或cygwin进行安装。

Spring Boot环境设置

通过提供默认的初始化程序,Spring Boot团队确实简化了Spring Boot环境的设置。打开URL https://start.spring.io/并按如下所示生成项目。

现在解压缩user-portal.zip并导入到Java IDE中。 以下是最终结构。

CLI命令生成的默认文件

现在让我们尝试了解生成的不同文件。

模块–模块将应用程序分解为逻辑代码。 每段代码或模块都旨在执行一项任务,所有模块均由main.ts加载。

组件–组件用于将模块组合在一起。

tsconfig.json –目录中tsconfig.json文件的存在表示该目录是Typescript项目的根。此文件指定了编译Typescript所需的根文件和TypeScript编译器动作。

package.json –它包含为角度项目定义的所有依赖项。一旦我们进行nom install,这些依赖项将自动下载。

karma.conf.json – karma单元测试的配置文件。

文件.angular-cli.json将具有所有应用程序配置,例如有关根目录和out目录的信息.welcome或main html文件以及main ts文件。 所有其他与环境相关的信息将在此处显示。

现在是时候运行dfault生成的应用程序并在浏览器中查看它了。 如果使用的是IntellijIdea,则可以从其中的终端运行ng serve命令,如果未在终端中单击以下命令。

cd portal-app
 ng serve

此后,打开浏览器并输入url – http:// localhost:4200 /,角度应用程序启动。 现在,我们可以开始修改应用程序以创建用户管理门户。

Spring Boot Rest API

现在,让我们首先创建我们的API。我们拥有UerController,其中公开了所有用于CRUD操作的API。@ CrossOrigin用于允许跨源资源共享(CORS),以便我们在不同服务器上运行的角度应用程序可以使用这些资源来自浏览器的API。我们还可以使用proxy.config.json在角度端配置代理,这在后续主题中已进行了讨论。

UserController.java

package com.devglan.userportal;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@CrossOrigin(origins = "http://localhost:4200", maxAge = 3600)
@RestController
@RequestMapping({"/api"})
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping
    public User create(@RequestBody User user){
        return userService.create(user);
    }

    @GetMapping(path = {"/{id}"})
    public User findOne(@PathVariable("id") int id){
        return userService.findById(id);
    }

    @PutMapping
    public User update(@RequestBody User user){
        return userService.update(user);
    }

    @DeleteMapping(path ={"/{id}"})
    public User delete(@PathVariable("id") int id) {
        return userService.delete(id);
    }

    @GetMapping
    public List findAll(){
        return userService.findAll();
    }
}

Spring Boot服务实现

服务类在这里没有多余的逻辑,这是一个非常简单的实现。

UserServiceImpl.java

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository repository;

    @Override
    public User create(User user) {
        return repository.save(user);
    }

    @Override
    public User delete(int id) {
        User user = findById(id);
        if(user != null){
            repository.delete(user);
        }
        return user;
    }

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

    @Override
    public User findById(int id) {
        return repository.findOne(id);
    }

    @Override
    public User update(User user) {
        return null;
    }
}

Spring数据实施

我们将使用针对ORM相关解决方案的Spring数据JPA实现。要了解Spring数据的内部实现,您可以访问我的另一篇文章-Spring Boot JPASpring Boot Hibernate实现。

UserRepository.java

package com.devglan.userportal;

import org.springframework.data.repository.Repository;

import java.util.List;

public interface UserRepository extends Repository {

    void delete(User user);

    List findAll();

    User findOne(int id);

    User save(User user);
}

Spring Boot数据源配置

application.properties

server.contextPath=/user-portal
spring.datasource.url=jdbc:mysql://localhost:3306/testdb
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.show-sql=true
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl
spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy

默认脚本

CREATE TABLE user(id INT NOT NULL AUTO_INCREMENT,email VARCHAR(255),first_name  VARCHAR(255),last_name VARCHAR(255),PRIMARY KEY (id))ENGINE=InnoDB;

创建角度组件

Angular CLI带有generate命令来创建组件,点击ng generate component user命令,它将在app文件夹内创建一个用户文件夹,该用户文件夹将包含用户模块所需的所有文件。

首先,我们将修改app.component.html以包含2个列表用户链接并添加用户。我们所有的视图都将被加载到router-outlet中。

app.component.html

<div class="container-fluid">
<div class="col-md-offset-1">
  <h1>
    Welcome to {{title}}!
  </h1>
</div>

<a routerLink="/users"> List Users</a>
<a style="margin-left:10px" routerLink="/add">Add User</a>
<br/>
<router-outlet></router-outlet>
</div>

由于我们在上面定义了两条路由,因此我们需要两个不同的视图(user.component.html,add-user.component.html)和组件(user.component.ts,add-user.component.ts)在每个视图上进行渲染click.Now,现在让我们实现user.component.ts的代码。在此,加载该组件时将调用ngOnInit()方法,它将获取所有用户记录,并填充html页面。

用户组件

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

import { User } from '../models/user.model';
import { UserService } from './user.service';

@Component({
  selector: 'app-user',
  templateUrl: './user.component.html',
  styles: []
})
export class UserComponent implements OnInit {

  users: User[];

  constructor(private router: Router, private userService: UserService) {

  }

  ngOnInit() {
    this.userService.getUsers()
      .subscribe( data => {
        this.users = data;
      });
  };

  deleteUser(user: User): void {
    this.userService.deleteUser(user)
      .subscribe( data => {
        this.users = this.users.filter(u => u !== user);
      })
  };

}

同样,我们有add-user.component.ts

import { Component } from '@angular/core';
import { Router } from '@angular/router';

import { User } from '../models/user.model';
import { UserService } from './user.service';

@Component({
  templateUrl: './add-user.component.html'
})
export class AddUserComponent {

  user: User = new User();

  constructor(private router: Router, private userService: UserService) {

  }

  createUser(): void {
    this.userService.createUser(this.user)
        .subscribe( data => {
          alert("User created successfully.");
        });

  };

}

user.model.ts

export class User {

  id: string;
  firstName: string;
  lastName: string;
  email: string;
}

user.service.ts

import {Injectable} from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

import { User } from '../models/user.model';


const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};

@Injectable()
export class UserService {

  constructor(private http:HttpClient) {}

  private userUrl = 'http://localhost:8080/user-portal/api';

  public getUsers() {
    return this.http.get(this.userUrl);
  }

  public deleteUser(user) {
    return this.http.delete(this.userUrl + "/"+ user.id);
  }

  public createUser(user) {
    return this.http.post(this.userUrl, user);
  }

}

创建角度视图

如上所述,我们有两个视图– user.component.html和add-user.component.html

user.component.html

<div class="col-md-6">
<h2> User Details</h2>

<table class="table table-striped">
  <thead>
  <tr>
    <th class="hidden">Id</th>
    <th>FirstName</th>
    <th>LastName</th>
    <th>Email</th>
    <th>Action</th>
  </tr>
  </theadv
  <tbody>
  <tr *ngFor="let user of users">
    <td class="hidden">{{user.id}}</td>
    <td>{{user.firstName}}</td>
    <td>{{user.lastName}}</td>
    <td>{{user.email}}</td>
    <td><button class="btn btn-danger" (click)="deleteUser(user)"> Delete User</button></td>
  </tr>
  </tbody>
</table>
</div>

add-user.component.html

<div class="col-md-6">
  <h2 class="text-center">Add User</h2>
<form>
  <div class="form-group">
    <label for="email">Email address:</label>
    <input type="email" [(ngModel)]="user.email" placeholder="Email" name="email" class="form-control" id="email">
  </div>

  <div class="form-group">
    <label for="firstName">First Name:</label>
    <input [(ngModel)]="user.firstName" placeholder="First Name" name="firstName" class="form-control" id="firstName">
  </div>

  <div class="form-group">
    <label for="lastName">Last Name:</label>
   <input [(ngModel)]="user.lastName" placeholder="Last name" name="lastName" class="form-control" id="lastName">
  </div>

  <button class="btn btn-success" (click)="createUser()">Create</button>
</form>
</div>

角路由

现在是时候以角度配置路由了,在此配置中,我们将配置要加载的路径和相应的组件,这将依次加载相应的视图。以下是我们的路由配置。

app.routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { UserComponent } from './user/user.component';
import {AddUserComponent} from './user/add-user.component';

const routes: Routes = [
  { path: 'users', component: UserComponent },
  { path: 'add', component: AddUserComponent }
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes)
  ],
  exports: [
    RouterModule
  ],
  declarations: []
})
export class AppRoutingModule { }

角度模块

现在我们的应用程序差不多完成了,我们只需要在主模块中包含以上所有实现即可。

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { UserComponent } from './user/user.component';
import { AppRoutingModule } from './app.routing.module';
import {UserService} from './user/user.service';
import {HttpClientModule} from "@angular/common/http";
import {AddUserComponent} from './user/add-user.component';

@NgModule({
  declarations: [
    AppComponent,
    UserComponent,
    AddUserComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    FormsModule
  ],
  providers: [UserService],
  bootstrap: [AppComponent]
})
export class AppModule { }

Angular CLI代理配置

要在angular CLI中配置代理,我们需要在angular项目的根目录中创建proxy.config.json文件,并在package.json中编辑启动脚本。

proxy.config.json

{
  "/api/*": {
    "target": "http://localhost:8080/user-portal",
    "secure": false
  }
}

target的值是应用程序的上下文根,而api是用户API的端点。

package.json

"start": "ng serve --proxy-config proxy.config.json",

现在,请确保将user.service.ts文件中的userUrl值更改为“ / api”,并在UserController.java中注释@CrossOrigin。完成后,请使用ng serve –proxy-config proxy.config.json或npm开始启动角度应用

最终申请结构

运行Spring Boot应用程序

我们将使用spring boot嵌入式tomcat功能来部署应用程序。有关此功能的更多信息, 请检查this

UserPortalApplication.java

package com.devglan.userportal;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class UserPortalApplication {

	public static void main(String[] args) {
		SpringApplication.run(UserPortalApplication.class, args);
	}
}

运行Angular应用

现在服务器已启动,可以用来部署角度应用程序并测试该应用程序。

点击URL – http:// localhost:4200 / ,您将看到以下结果。

现在,单击“添加用户”链接,将出现以下表单以添加用户。

现在,添加多个用户后,单击列表用户。

结论

这几乎是关于spring boot和angular 5集成教程的。在下一篇文章中,我们将研究使用maven和tomcat在单个war文件中部署此应用程序 。 您可以从此处下载源代码。如果时间允许,我们将尝试将Spring Security与之集成。请在下面让我知道您的评论。

翻译自: https://www.javacodegeeks.com/2018/03/spring-boot-angular-5-spring-data-rest-example-crud.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值