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-appng 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 {@Autowiredprivate UserService userService;@PostMappingpublic User create(@RequestBody User user){return userService.create(user);}@GetMapping(path = {"/{id}"})public User findOne(@PathVariable("id") int id){return userService.findById(id);}@PutMappingpublic User update(@RequestBody User user){return userService.update(user);}@DeleteMapping(path ={"/{id}"})public User delete(@PathVariable("id") int id) {return userService.delete(id);}@GetMappingpublic List findAll(){return userService.findAll();}
}

Spring Boot服务实现

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

UserServiceImpl.java

@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserRepository repository;@Overridepublic User create(User user) {return repository.save(user);}@Overridepublic User delete(int id) {User user = findById(id);if(user != null){repository.delete(user);}return user;}@Overridepublic List findAll() {return repository.findAll();}@Overridepublic User findById(int id) {return repository.findOne(id);}@Overridepublic User update(User user) {return null;}
}

Spring数据实施

我们将使用针对ORM相关解决方案的Spring数据JPA实现。要了解Spring数据的内部实现,您可以访问我的另一篇文章-Spring Boot JPA和Spring 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/348561.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

信号与系统 chapter12 卷积及其性质

卷积的概念 卷积算得上是信号与系统里面一个比较抽象的概念&#xff0c;它广泛应用在统计学、工程学&#xff0c;好多人明白了怎么做题&#xff0c;却仍然说不清楚卷积的概念&#xff0c;我们把它当作一种运算&#xff0c;它的运算形式如下&#xff1a; 有f1(t)f2(t)f_1(t)f_2…

第二章导数与微分思维导图_线性代数第二章 矩阵 思维导图

这章内容复习集中在两方面&#xff1a;矩阵乘法&#xff1b;可逆矩阵及相关内容&#xff08;矩阵方程和伴随矩阵&#xff09;。可逆矩阵是全课程的一个关键性概念&#xff0c;与各章内容都有联系&#xff0c;应着重注意这些联系。

图像的常用压缩技术以及视频码率的计算

图像压缩方法&#xff1a; 冗余度压缩方法&#xff1a;也称无损压缩&#xff0c;压缩比较低信息量压缩方法&#xff1a;有损压缩&#xff0c;多用在数字电视技术与静止图像通信&#xff0c;压缩编码中丢弃了一些没有作用的信息 压缩种类压缩方法无损压缩哈夫曼编码&#xff0…

框架优点_铝型材框架相比其他框架的优点

很多自动化技术机械厂都是应用到工业铝型材框架做为设备的支撑点件&#xff0c;还会继续有一些顾客会有疑问&#xff0c;用铁或是是其他的原材料来做框架能不能&#xff1f;当然是能够 的&#xff0c;但是为什么有生产厂家把原来其他原材料换为工业铝型材框架来应用呢&#xff…

使用Maven进行Selenium测试自动化

今天&#xff0c;我想帮助您更好地管理自动GUI测试&#xff08;Selenium&#xff09;。 在过去&#xff0c;我已经看到人们处理此问题的许多不同方式。 有些人只是用Selenium-IDE编写普通HTML TestCases&#xff0c;将其存储在HDD上的某个位置&#xff0c;并在需要时手动运行。…

2018年工业机器人销量排位_长安-2018年11月汽车销量 细分销量

根据盖世汽车社区-销量数据库查询&#xff0c;为广大汽车行业人士整理了长安-2018年11月细分销量(按变速箱)数据如下:变速箱类型九月十月十一月累计4AT[TS-40/Ss-II]4,6554,0545,34814,0575AMT[AF512]11711202295DCT[DF515]56955139915195MT[MF510]2,34298475040765MT[MF515/TM…

Spring中@ Component,@ Service,@ Controller和@Repository之间的区别

在了解Spring框架中Repository Component &#xff0c; Service Controller &#xff0c; Repository Controller和Repository批注之间的区别之前&#xff0c;了解Component批注在Spring中的作用很重要。 在Spring的初始发行期间&#xff0c;所有bean都用于在XML文件中声明。 对…

信号与系统 chapter13 阶跃响应的定义与求法

定义 阶跃响应是阶跃函数ξ(t)\xi(t)ξ(t)所引起的***零状态响应&#xff0c;***记为g(t)g(t)g(t) 这玩意的求法与咱们前面画信号与系统框图那一部分有异曲同工之妙信号与系统chapter8 有两种方法 经典法 利用单位阶跃函数与单位冲激响应之间的关系 看一道例题&#xff1a…

语音识别插件_2D动画唇动合成,根据语音自动生成动画人物口型

蕾师师 发自 凹非寺量子位 报道 | 公众号 QbitAI只需要输入一段语音&#xff0c;代码会自动生成与之相对的动画唇形。还是毫无违和感的那种。这是一个在GitHub上拥有501星的开源项目&#xff0c;叫做Rhubarb Lip Sync。它既可以是Windows和OS X命令行工具&#xff0c;也可以作为…

安装指定版本pytorch_Ubuntu16.04安装pytorch(七)

Ubuntu16.04自带python 2.7.12 和python 3.5.2&#xff0c;不需要自己装python第一步&#xff1a;安装pip3sudo apt-get install python3-pip顺便安装numpypip3 install numpy第二步&#xff1a;配置pip使用的镜像源---------------------------------------------------------…

后怎么恢复_爬山后小腿肌肉酸痛怎么办 ?这样来恢复!|新生活公社

爬山后小腿肌肉酸痛怎么办 &#xff1f;这样来恢复&#xff01;在爬山之后腿疼的话可以用热敷、按摩、泡脚、拉伸等等方法来帮助自己恢复&#xff0c;爬山之后腿疼是正常的现象&#xff0c;我们在爬山之后要及时拉伸。爬山后小腿肌肉酸痛怎么办1热敷这是很有效的又简单的方法&a…

java实现次方的运算_Java中对于位运算的优化以及运用与思考

引言随着JDK的发展以及JIT的不断优化&#xff0c;我们很多时候都可以写读起来易读但是看上去性能不高的代码了&#xff0c;编译器会帮我们优化代码。之前大学里面学单片机的时候&#xff0c;由于内存以及处理器性能都极其有限(可能很多时候考虑内存的限制优先于处理器)&#xf…

dep指定版本 go_Go 1.12 版本的新特性

Go 1.12昨天&#xff0c;Go 官方发布 1.12 版本。本文介绍下 Go 1.12 版本变更的内容。Go 1.12 正式版发布了&#xff0c;距离上个正式发布版 Go 1.11 已经过去半年。跟往常一样&#xff0c;Go 1.12 保持了 兼容性承诺&#xff0c;预期所有 Go 程序会像之前一样正常编译。新版本…

信号与系统 chapter14 卷积积分的应用

卷积的时移特性 若有一个卷积&#xff1a; f(t)f1(t)∗f2(t)f(t)f_1(t)*f_2(t)f(t)f1​(t)∗f2​(t)&#xff0c;卷积右边的函数都发生了时移&#xff0c;分别为t1,t2t_1,t_2t1​,t2​&#xff0c;则有&#xff1a; 不要管怎么来&#xff0c;记下就完事了 例题&#xff1a; …

java null转换jason_Java笔记Java常量、变量

“要成为绝世高手&#xff0c;并非一朝一夕&#xff0c;除非是天生武学奇才&#xff0c;但是这种人…万中无一”——包租婆这道理放在Java语言学习上也一并受用。在编程方面有着天赋异禀的人毕竟是少数&#xff0c;我们大多数人想要从java语言小白进阶到高手&#xff0c;需要经…

通信系统中的多普勒频移

多普勒现象在通信系统中的表现 当终端在运动特别是在高速运动时&#xff0c;移动终端和基站接收端的信号频率会发生变化&#xff0c;其计算公式如下图所示&#xff1a; fdfc∗v∗cosθf_d\frac{f}{c}*v*cos\thetafd​cf​∗v∗cosθ θ\thetaθ为移动台移动方向与入射方向的夹…

mockito_Mockito – JAXB的RETURNS_DEEP_STUBS

mockito很抱歉没有写一段时间&#xff0c;但是我正忙于为DZone编写JBoss Drools Refcard&#xff0c;而且我正在写一本有关Mockito的书&#xff0c;因此我没有太多时间来写博客了…… 无论如何&#xff0c;最近在我当前的项目中&#xff0c;我对使用Mockito和JAXB结构进行单元…

常见扩频序列

扩频通信就要借助扩频序列 对扩频序列的要求如下&#xff1a; 具有尖锐的自相关特性有尽可能小的互相关特性&#xff0c;最好为0序列平衡&#xff0c;0与1的数量尽可能一样多在扩频序列族中有数目足够多的序列可供选用有尽可能大的序列复杂度 常见的几种扩频序列 PN序列 第一…

删除文件夹下所有的文件_VB删除文件和文件夹的方法

在VB编程中&#xff0c;我们如何删除一个指定的文件&#xff0c;或者文件夹呢&#xff1f;本文&#xff0c;介绍两种方法&#xff0c;详细的介绍如何实现删除文件和文件夹&#xff0c;并对两种方法的区别做一个说明。一、删除文件的方法方法1&#xff1a;使用kill方法删除文件语…

无线网络设计基础

移动电波的传播特点 受到地形影响因素大存在严重的多径衰落迹象存在固定通信中没有的阴影衰落存在相对运动引起的多普勒效应存在由时延散布引起的信号波形展宽 无线收发信设备、天馈线系统、无线电信道组成无线通信系统 自由空间传输损耗 理想条件下&#xff1a; Lbs32.4520…