使用React和Spring Boot构建一个简单的CRUD应用

“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证。

React的设计使创建交互式UI变得轻松自如。 它的状态管理非常有效,并且仅在数据更改时才更新组件。 组件逻辑是用JavaScript编写的,这意味着您可以将状态保持在DOM之外,并创建封装的组件。

开发人员喜欢CRUD(创建,读取,更新和删除)应用程序,因为它们显示了创建应用程序时需要的许多基本功能。 一旦在应用程序中完成了CRUD的基础知识,大多数客户端-服务器管道就完成了,您可以继续实施必要的业务逻辑。

今天,我将向您展示如何在React中使用Spring Boot创建一个基本的CRUD应用。 您可能还记得我去年为Angular撰写的一篇类似文章: 使用Angular 5.0和Spring Boot 2.0构建Ba​​sic CRUD应用程序 。 该教程使用OAuth 2.0的隐式流程和我们的Okta Angular SDK 。 在本教程中,我将使用OAuth 2.0授权代码流,并将React应用打包在Spring Boot应用中进行生产。 同时,我将向您展示如何保持React高效的工作流以进行本地开发。

您将需要安装Java 8Node.js 8Yarn才能完成本教程。 您可以使用npm代替Yarn,但是您需要将Yarn语法转换为npm。

使用Spring Boot 2.0创建API应用

我经常在世界各地的会议和用户组中演讲。 我最喜欢发言的用户组是Java用户组(JUG)。 我从事Java开发人员已有近20年的时间,而且我喜欢Java社区。 我的一个好朋友詹姆斯·沃德(James Ward)表示,进行水罐巡游是他当时最喜欢的开发商倡导者活动之一。 我最近接受了他的建议,并在海外会议上进行了JUG聚会在美国的聚会。

我为什么要告诉你呢? 因为我认为今天创建一个“ JUG Tours”应用很有趣,它允许您创建/编辑/删除JUG,以及查看即将发生的事件。

首先,导航至start.spring.io并进行以下选择:

  • 组: com.okta.developer
  • 神器: jugtours
  • 依赖项JPAH2WebLombok

反应

单击生成项目 ,下载后展开jugtours.zip ,然后在您喜欢的IDE中打开该项目。

提示:如果您使用的是IntelliJ IDEA或Spring Tool Suite,则在创建新项目时也可以使用Spring Initializr。

添加一个JPA域模型

您需要做的第一件事是创建一个保存数据的域模型。 在高层次上,有一个Group表示酒壶,一个Event有一个多到一的关系Group ,以及User具有与一个一对多的关系Group

在其中创建一个src/main/java/com/okta/developer/jugtours/model目录和一个Group.java类。

package com.okta.developer.jugtours.model;

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;

import javax.persistence.*;
import java.util.Set;

@Data
@NoArgsConstructor
@RequiredArgsConstructor
@Entity
@Table(name = "user_group")
public class Group {

    @Id
    @GeneratedValue
    private Long id;
    @NonNull
    private String name;
    private String address;
    private String city;
    private String stateOrProvince;
    private String country;
    private String postalCode;
    @ManyToOne(cascade=CascadeType.PERSIST)
    private User user;

    @OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
    private Set<Event> events;
}

在同一包中创建一个Event.java类。

package com.okta.developer.jugtours.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import java.time.Instant;
import java.util.Set;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
public class Event {

    @Id
    @GeneratedValue
    private Long id;
    private Instant date;
    private String title;
    private String description;
    @ManyToMany
    private Set<User> attendees;
}

还有一个User.java类。

package com.okta.developer.jugtours.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.Entity;
import javax.persistence.Id;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class User {

    @Id
    private String id;
    private String name;
    private String email;
}

创建一个GroupRepository.java来管理组实体。

package com.okta.developer.jugtours.model;

import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface GroupRepository extends JpaRepository<Group, Long> {
    Group findByName(String name);
}

要加载一些默认数据,请在com.okta.developer.jugtours包中创建一个Initializer.java类。

package com.okta.developer.jugtours;

import com.okta.developer.jugtours.model.Event;
import com.okta.developer.jugtours.model.Group;
import com.okta.developer.jugtours.model.GroupRepository;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.time.Instant;
import java.util.Collections;
import java.util.stream.Stream;

@Component
class Initializer implements CommandLineRunner {

    private final GroupRepository repository;

    public Initializer(GroupRepository repository) {
        this.repository = repository;
    }

    @Override
    public void run(String... strings) {
        Stream.of("Denver JUG", "Utah JUG", "Seattle JUG",
                "Richmond JUG").forEach(name ->
                repository.save(new Group(name))
        );

        Group djug = repository.findByName("Denver JUG");
        Event e = Event.builder().title("Full Stack Reactive")
                .description("Reactive with Spring Boot + React")
                .date(Instant.parse("2018-12-12T18:00:00.000Z"))
                .build();
        djug.setEvents(Collections.singleton(e));
        repository.save(djug);

        repository.findAll().forEach(System.out::println);
    }
}

提示:如果您的IDE Event.builder()问题,则意味着您需要打开注释处理和/或安装Lombok插件。 我必须在IntelliJ IDEA中卸载/重新安装Lombok插件才能正常工作。

如果在添加此代码后启动应用程序(使用./mvnw spring-boot:run ),您将看到控制台中显示的组和事件列表。

Group(id=1, name=Denver JUG, address=null, city=null, stateOrProvince=null, country=null, postalCode=null, user=null, events=[Event(id=5, date=2018-12-12T18:00:00Z, title=Full Stack Reactive, description=Reactive with Spring Boot + React, attendees=[])])
Group(id=2, name=Utah JUG, address=null, city=null, stateOrProvince=null, country=null, postalCode=null, user=null, events=[])
Group(id=3, name=Seattle JUG, address=null, city=null, stateOrProvince=null, country=null, postalCode=null, user=null, events=[])
Group(id=4, name=Richmond JUG, address=null, city=null, stateOrProvince=null, country=null, postalCode=null, user=null, events=[])

添加一个GroupController.java类(在src/main/java/.../jugtours/web/GroupController.java ), src/main/java/.../jugtours/web/GroupController.java可用于CRUD组。

package com.okta.developer.jugtours.web;

import com.okta.developer.jugtours.model.Group;
import com.okta.developer.jugtours.model.GroupRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collection;
import java.util.Optional;

@RestController
@RequestMapping("/api")
class GroupController {

    private final Logger log = LoggerFactory.getLogger(GroupController.class);
    private GroupRepository groupRepository;

    public GroupController(GroupRepository groupRepository) {
        this.groupRepository = groupRepository;
    }

    @GetMapping("/groups")
    Collection<Group> groups() {
        return groupRepository.findAll();
    }

    @GetMapping("/group/{id}")
    ResponseEntity<?> getGroup(@PathVariable Long id) {
        Optional<Group> group = groupRepository.findById(id);
        return group.map(response -> ResponseEntity.ok().body(response))
                .orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

    @PostMapping("/group")
    ResponseEntity<Group> createGroup(@Valid @RequestBody Group group) throws URISyntaxException {
        log.info("Request to create group: {}", group);
        Group result = groupRepository.save(group);
        return ResponseEntity.created(new URI("/api/group/" + result.getId()))
                .body(result);
    }

    @PutMapping("/group/{id}")
    ResponseEntity<Group> updateGroup(@PathVariable Long id, @Valid @RequestBody Group group) {
        group.setId(id);
        log.info("Request to update group: {}", group);
        Group result = groupRepository.save(group);
        return ResponseEntity.ok().body(result);
    }

    @DeleteMapping("/group/{id}")
    public ResponseEntity<?> deleteGroup(@PathVariable Long id) {
        log.info("Request to delete group: {}", id);
        groupRepository.deleteById(id);
        return ResponseEntity.ok().build();
    }
}

如果重新启动服务器应用程序,并使用浏览器或命令行客户端访问http://localhost:8080/api/groups ,则应看到组列表。

您可以使用以下HTTPie命令创建,读取,更新和删除组。

http POST :8080/api/group name='Dublin JUG' city=Dublin country=Ireland
http :8080/api/group/6
http PUT :8080/api/group/6 name='Dublin JUG' city=Dublin country=Ireland address=Downtown
http DELETE :8080/api/group/6

使用Create React App创建一个React UI

Create React App是一个命令行实用程序,可为您生成React项目。 这是一个方便的工具,因为它还提供了一些命令,这些命令将生成和优化您的项目以进行生产。 它使用webpack在后台进行构建。 如果您想了解更多关于webpack的信息,我建议使用webpack.academy

使用Yarn在jugtours目录中创建一个新项目。

yarn create react-app app

应用程序创建过程完成后,导航至app目录并安装Bootstrap ,对React的cookie支持,React Router和Reactstrap

cd app
yarn add bootstrap@4.1.2 react-cookie@2.2.0 react-router-dom@4.3.1 reactstrap@6.3.0

您将使用BootstrapCSS和Reactstrap的组件来使UI看起来更好,尤其是在手机上。 如果您想了解有关Reactstrap的更多信息,请参见https://reactstrap.github.io 。 它具有有关其各种组件以及如何使用它们的大量文档。

将BootstrapCSS文件添加为app/src/index.js的导入文件。

import 'bootstrap/dist/css/bootstrap.min.css';

调用您的Spring Boot API并显示结果

修改app/src/App.js以使用以下代码调用/api/groups并在UI中显示列表。

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值