javascript
使用React,Spring Boot和用户身份验证构建CRUD应用程序
建筑物身份管理,包括身份驗證和授權? 嘗試Stormpath! 我們的REST API和強大的Java SDK支持可以消除您的安全風險,并且可以在幾分鐘內實現。 注冊 ,再也不會建立auth了!
React是用于創建Web應用程序前端的最受歡迎的庫之一。 使用Spring Boot 為面向React的應用程序創建CRUD后端比以往任何時候都更加容易。 在本教程中,我們將它們捆綁在一起,然后使用Stormpath添加身份驗證和授權協議。
我們將從使用React創建一個靜態數據視圖開始。 然后,我們將使用Spring Boot創建一個REST后端,進行綁定,并使用Stormpath添加用戶安全性。 即使您以前從未使用過React,一切也應該簡單明了。
支持這篇文章的源代碼可以在這個GitHub repo中找到。
服務前線
通常,React應用程序是使用Node.js來提供服務的,但是如果您是Java開發人員,則可能會對這種Spring Boot方法感到非常滿意。
最初,您將整個應用程序放在一個文件index.html 。 要告訴Spring Boot將其用作主頁,可以使用@Controller批注。
@Controller public class HomeController {@RequestMapping(value = "/")public String index() {return "index.html";} }創建一個空目錄,并將上面的代碼放入src/main/java/tutorial/HomeController.java 。 然后,當您加載站點時,Spring Boot將尋找src/main/resources/static/index.html 。
<!DOCTYPE html> <html> <head><title>React + Spring</title> </head> <body> </body> </html>創建一個pom.xml和一個Spring Boot應用程序類。 將以下內容用于您的POM。
<project><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.4.1.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build> </project>將以下內容放入src/main/java/tutorial/Application.java 。
@SpringBootApplication public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);} }當使用mvn spring-boot:run啟動服務器并訪問localhost:8080您應該看到一個空白頁,標題為“ React + Spring”。
刪除重啟
通常,每次更改前端時都必須重新啟動服務器,這很麻煩。 使用Spring Boot的開發人員工具可以使我們解決這個問題。 將以下依賴項添加到您的POM。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional> </dependency>還要將此配置添加到您的Spring Boot Maven插件中:
<configuration><addResources>true</addResources> </configuration>現在,當您更改應用程序或重新編譯任何類時,刷新瀏覽器時它應該會更新。
反應準系統HTML
開始反應! 最基本的React頁面包含三件事:根元素,JavaScript導入和腳本標簽。
<!DOCTYPE html> <html> <head><title>React + Spring</title> </head> <body><div id='root'></div><script src="https://fb.me/react-15.0.1.js"></script><script src="https://fb.me/react-dom-15.0.1.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script><script type="text/babel"></script> </body> </html>根元素是React將在其中插入視圖HTML的位置。 導入引入了三個庫-兩個用于React本身,另一個用于使用babel翻譯我們的視圖模板。
注意:為了便于測試,我們使用CDN引入庫,但是通常您會使用webpack之類的東西將所有Javascript合并到一個文件中。
現在,將您的React代碼放入script標簽中。
React基礎
如反應教程中的想法所述,您應該通過將接口分解為components來開始對應用程序進行編碼。
<script type="text/babel"> var Employee = React.createClass({}); var EmployeeTable = React.createClass({}); </script>在這里,您創建了兩個-一個用于雇員表,另一個用于雇員條目。 然后,每個組件都需要一個渲染函數,該函數描述要生成HTML。
<script type="text/babel"> var Employee = React.createClass({render: function() {return (<div>employee</div>);} }); var EmployeeTable = React.createClass({render: function() {return (<div>employee table</div>);} }); </script>這是Babel編譯器用來將HTML代碼轉換為正確的React語句的地方。 注意div標簽如何從render語句返回。
您需要告訴React將父組件HTML插入根元素。 這是使用ReactDOM.render方法完成的。
<script type="text/babel"> var Employee = React.createClass({render: function() {return (<div>employee</div>);} }); var EmployeeTable = React.createClass({render: function() {return (<div>employee table</div>);} });ReactDOM.render(<EmployeeTable />, document.getElementById('root') ); </script>通過刷新瀏覽器,您應該看到您創建的簡單文本元素。
要查看插入到根元素中HTML React,可以使用瀏覽器的檢查器(Chrome中的Ctrl-Shift-J)。
將組件捆綁在一起
現在您已經有了組件,讓我們將它們綁在一起。 您可以從嘗試呈現硬編碼的數據開始。 您稍后將使用REST服務器。
在ReactDOM命令上方,輸入以下內容:
var EMPLOYEES = [{name: 'Joe Biden', age: 45, years: 5},{name: 'President Obama', age: 54, years: 8},{name: 'Crystal Mac', age: 34, years: 12},{name: 'James Henry', age: 33, years: 2} ];然后在實例化表時添加employees={EMPLOYEES} 。
ReactDOM.render(<EmployeeTable employees={EMPLOYEES} />, document.getElementById('root') );如您所料,這會將數據傳遞到名為employees的變量中。 在EmployeeTable內部,您可以使用this.props進行訪問。 讓我們用它來為每個雇員生成一個帶有一行的表。
var EmployeeTable = React.createClass({render: function() {var rows = [];this.props.employees.forEach(function(employee) {rows.push(<Employee employee={employee} />);});return (<table><thead><tr><th>Name</th><th>Age</th><th>Years</th></tr></thead><tbody>{rows}</tbody></table>);} });這將為數據中的每個元素實例化一個新的Employee類(設置employee屬性)并將其推入數組。 然后{rows}從子類中放入所需HTML。
現在,您需要做的就是更新Employee上的render方法。
var Employee = React.createClass({render: function() {return (<tr><td>{this.props.employee.name}</td><td>{this.props.employee.age}</td><td>{this.props.employee.years}</td></tr>);} });您可以添加Bootstrap以使表看起來不錯。 在腳本導入標簽的下方添加以下內容:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">然后用容器div包圍主表,并為表元素提供一些Bootstrap類名稱。
<div className="container"><table className="table table-striped"><thead><tr><th>Name</th><th>Age</th><th>Years</th></tr></thead><tbody>{rows}</tbody></table> </div>刷新瀏覽器應該可以很好地查看您硬編碼的數據!
添加真實數據
要使用來自服務器的數據對象,您需要添加服務器! 使用Spring Boot做到這一點非常簡單。 在src/main/java/tutorial/Employee.java添加以下代碼:
@Data @Entity public class Employee {private @Id @GeneratedValue Long id;private String name;private int age;private int years;private Employee() {}public Employee(String name, int age, int years) {this.name = name;this.age = age;this.years = years;} }這是我們的豆。 注意: @Data批注來自Project Lombok 。
現在,使用Spring Data JPA創建一個存儲庫。
public interface EmployeeRepository extends CrudRepository<Employee, Long> {}要加載數據,請創建一個CommandLineRunner實現,該實現使用存儲庫在數據庫中創建新記錄。
@Component public class DatabaseLoader implements CommandLineRunner {private final EmployeeRepository repository;@Autowiredpublic DatabaseLoader(EmployeeRepository repository) {this.repository = repository;}@Overridepublic void run(String... strings) throws Exception {this.repository.save(new Employee("Joe Biden", 45, 5));this.repository.save(new Employee("President Obama", 54, 8));this.repository.save(new Employee("Crystal Mac", 34, 12));this.repository.save(new Employee("James Henry", 33, 2));} }剩下的唯一事情就是引入依賴關系。 將以下內容添加到pom.xml將使您的存儲庫成為REST端點。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-rest</artifactId> </dependency> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>您還需要包括Project Lombok (可讓您忽略為bean創建getter和setter)。
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.16.10</version><scope>provided</scope> </dependency>并且您需要一個數據庫(Spring Boot會自動配置該數據庫)。 您可以使用H2,它是嵌入式的(即在內存中/不會重新啟動)。
<dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId> </dependency>就是這樣! 如果現在重新啟動,您將擁有一個具有數據功能的REST服務器。
映射URL
如果將以下內容添加到src/main/resources/application.properties則所有REST端點調用都將位于localhost:8080/api
spring.data.rest.basePath=/api從命令行調用localhost:8080/api/employees應該會給出您加載的數據的列表。
反應和REST
現在,您需要將數據從REST端點拉入React視圖。 您可以使用jQuery完成此操作。 將以下導入添加到HTML:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>現在創建一個包裝器類,該包裝器類在其render方法中返回EmployeeTable 。
var App = React.createClass({loadEmployeesFromServer: function () {var self = this;$.ajax({url: "http://localhost:8080/api/employees"}).then(function (data) {self.setState({employees: data._embedded.employees});});},getInitialState: function () {return {employees: []};},componentDidMount: function () {this.loadEmployeesFromServer();},render() {return ( <EmployeeTable employees={this.state.employees}/> );} });您必須首先使用getInitialState進行初始化來設置state ,然后使用componentDidMount來完成加載所有內容時所需的操作。
現在,將主ReactDOM.render替換為新類。
ReactDOM.render(<App />, document.getElementById('root') );刷新后,您應該會看到與以前相同的視圖,只是現在正在從服務器加載數據。
互動性
您需要為前端做的最后一件事是交互性。 讓我們添加一個delete按鈕,看看它如何工作。
將以下列添加到您的員工渲染中。
<td><button className="btn btn-info" onClick={this.handleDelete}>Delete</button> </td>您將在handleDelete秒鐘內編寫handleDelete方法。 在雇員表類中添加另一個標題后,您應該看到每個條目旁邊都出現了按鈕。
從服務器刪除
在將刪除請求發送到后端之前,最好添加通知消息。 為此,您可以使用Toastr ,這將允許您顯示彈出窗口。 在HTML頂部添加以下內容:
<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.3/toastr.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.3/toastr.min.css">現在,您可以在腳本中使用toastr.error('something went wrong')類的命令發送消息。
讓我們測試一下! 將您的員工類別更改為以下內容:
var Employee = React.createClass({getInitialState: function() {return {display: true };},handleDelete() {var self = this;$.ajax({url: self.props.employee._links.self.href,type: 'DELETE',success: function(result) {self.setState({display: false});},error: function(xhr, ajaxOptions, thrownError) {toastr.error(xhr.responseJSON.message);}});},render: function() {if (this.state.display==false) return null;else return (<tr><td>{this.props.employee.name}</td><td>{this.props.employee.age}</td><td>{this.props.employee.years}</td><td><button className="btn btn-info" onClick={this.handleDelete}>Delete</button></td></tr>);} });這將設置一個display狀態,該狀態決定是否渲染。 如果成功刪除了員工,則此變量設置為true。 handleDelete方法將刪除請求發送到服務器(使用從get請求返回的href)。 如果成功,則將display設置為false并更新渲染。 否則,Toastr會通知用戶發生錯誤。
嘗試刪除條目并刷新頁面。 它應該保持刪除狀態。
注意:由于您正在使用內存數據庫,因此重新啟動服務器將恢復相同的數據。
添加用戶身份驗證
讓我們在React應用程序中添加一項最終功能,即Stormpath,以進行用戶身份驗證。 您將需要使用Stormpath永久免費的開發人員帳戶 。
您需要做的第一件事是將Stormpath應用程序詳細信息放在application.properties 。
stormpath.application.href = <your app href> stormpath.client.apiKey.id = <your api key id> stormpath.client.apiKey.secret = <your api key secret>注意:出于安全原因,您不應將Stormpath密鑰存儲在項目文件中。 而是使用環境變量。 看這里 。
接下來,將Stormpath啟動器添加到您的Maven依賴項中。
<dependency><groupId>com.stormpath.spring</groupId><artifactId>stormpath-default-spring-boot-starter</artifactId><version>1.1.2</version> </dependency>您還需要將index.html文件移動到src/main/resources/templates這是因為Stormpath的Spring Boot啟動程序默認使用Thymeleaf模板庫。 更改HomeController以也返回index 。
@Controller public class HomeController {@RequestMapping(value = "/")public String index() {return "index";} }您還需要將您的React代碼移動到一個單獨的文件中。 這是因為Thymeleaf不喜歡某些角色。 將代碼從腳本標簽的內部移至src/main/webapp/public/app.js 默認情況下,此文件夾對公眾開放。 然后將此腳本導入HTML的底部。
<script type="text/babel" src="/public/app.js"></script>然后創建一個安全適配器,調用該適配器適用于stormpath() 。
@Configuration public class Security extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.apply(stormpath());} }現在,當您重新啟動服務器并嘗試訪問主頁時,將出現登錄頁面提示。
輸入您在application.properties放入的Stormpath應用程序附帶的詳細信息,應像以前一樣將您帶到數據視圖頁面。
注銷
您還需要能夠注銷。 這就像添加一個將帖子發送到/logout的表單一樣簡單(Stormpath會默認設置該表單)。
<div class='container'><div id='root'></div><form action="/logout" method="post"><input class="btn btn-danger center-block" type="submit" value="Logout" /></form> </div>您可以用Bootstrap容器包圍React根元素和表單,以更好地對齊。
單擊注銷按鈕將使您返回到以前的登錄屏幕。
設置授權
最后,您只想讓具有正確訪問權限的用戶刪除員工。 要鎖定內容,可以使用Spring Security的PreAuthorize注釋。 將存儲庫代碼更改為以下內容:
public interface EmployeeRepository extends CrudRepository<Employee, Long> {@PreAuthorize("hasAuthority('ROLE_ADMIN')")@Overridevoid delete(Long aLong); }現在,只有具有ROLE_ADMIN權限的用戶才能刪除。 如果重新啟動服務器并嘗試單擊“刪除”,則應收到一條消息,提示“訪問被拒絕”。
要為用戶提供所需的權限,您需要通過管理控制臺將其添加到Stormpath組中。
在此示例中,有一個名為Supervisor的組已附加到相關應用程序。 要與該組集成,只需將ROLE_ADMIN字符串替換為該組的HREF并重新啟動。 如果登錄的用戶是Supervisor組的成員(請參閱帳戶),則應允許您刪除。
塵埃落定
就像您已經創建了一個以授權和React為前端的兼容CRUD Web應用程序。 希望本教程對您有所幫助! 如果您對集成React,Spring Boot和Stormpath有任何疑問,請發表評論。
要查看使用Spring Boot后端的更完整的React應用程序,請參閱React.js和Spring Data REST 。
建筑物身份管理,包括身份驗證和授權? 嘗試Stormpath! 我們的REST API和強大的Java SDK支持可以消除您的安全風險,并且可以在幾分鐘內實現。 注冊 ,再也不會建立auth了!
翻譯自: https://www.javacodegeeks.com/2016/12/build-crud-application-react-spring-boot-user-authentication.html
總結
以上是生活随笔為你收集整理的使用React,Spring Boot和用户身份验证构建CRUD应用程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 联想电脑网线怎么接(联想电脑网线接口什么
- 下一篇: 15分钟内使用Twilio和Stormp