Spring Boot将Spring框架提升到了一个新的水平。它极大地缩短了Spring项目所需的配置和设置时间。
您可以设置几乎为零配置的项目,并开始构建对您的应用程序而言非常重要的事物。
如果你是Spring的新手,想快速入门,那么这篇博文就是为你准备的。
在这篇文章中,我们将为简单的笔记应用程序构建一个Restful CRUD API。注释可以有标题和一些内容。我们将首先构建apis来创建,检索,更新和删除一个Note,然后使用POSTMAN测试它们。
Spring Boot提供了一个名为Spring Initializer的Web工具来快速引导应用程序。只需访问http://start.spring.io并按照以下步骤生成一个新项目。
第1步:在http://start.spring.io页面上单击切换到完整版本。
第2步:输入详细信息如下 -
输入完所有细节后,单击生成项目以生成并下载项目。Spring初始化程序将生成具有您输入的详细信息的项目并下载包含所有项目文件夹的zip文件。
接下来,解压下载的zip文件并将其导入到您最喜欢的IDE中。
以下是我们的笔记记录应用程序的目录结构 -
让我们了解一些重要文件和目录的细节 -
1. EasyNotesApplication
这是我们的Spring Boot应用程序的主要入口点。
package com.example.easynotes;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class EasyNotesApplication {
public static void main(String[] args) {
SpringApplication.run(EasyNotesApplication.class, args);
}
}
它包含一个简单的注释@SpringBootApplication
,它是以下更具体的Spring注释的组合 -
@Configuration
Annotation注解的任何类由Spring引导,并且也被认为是其他bean定义的来源。pom.xml
文件中的依赖来自动配置你的应用程序。spring-data-jpa
在类路径中,则它会自动尝试DataSource
通过从application.properties
文件中读取数据库属性来配置一个。该main()
方法调用Spring Boot的SpringApplication.run()
方法来启动应用程序。
2.资源/
顾名思义,该目录专用于所有静态资源,模板和属性文件。
资源/静态 - 包含静态资源,如css,js和图像。
资源/模板 - 包含由Spring呈现的服务器端模板。
resources / application.properties - 这个文件非常重要。它包含应用程序范围内的属性。Spring读取这个文件中定义的属性来配置你的应用程序。您可以在此文件中定义服务器的默认端口,服务器的上下文路径,数据库URL等。
您可以参考此页面来了解Spring Boot中使用的常见应用程序属性。
3. EasyNotesApplicationTests - 在这里定义单元和集成测试。
4. pom.xml - 包含所有的项目依赖关系
正如我前面指出的那样,Spring Boot 通过从文件中读取数据库配置,尝试在类路径中自动配置DataSource
if 。spring-data-jpa
application.properties
所以,我们只需要添加配置,而Spring Boot将负责其余部分。
打开application.properties
文件并向其中添加以下属性。
## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url = jdbc:mysql://localhost:3306/notes_app?useSSL=false
spring.datasource.username = root
spring.datasource.password = root
## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update
您需要在MySQL中创建一个名为notes_app的数据库,并根据您的MySQL安装更改spring.datasource.username
&spring.datasource.password
属性。
在上面的属性文件中,最后两个属性用于休眠。Spring Boot使用Hibernate作为默认的JPA实现。
该属性spring.jpa.hibernate.ddl-auto
用于数据库初始化。我已经使用这个属性的值“update”。
它做了两件事 -
使用更新的spring.jpa.hibernate.ddl-auto
财产是好的发展。但是,对于生产,您应该保留此属性的值以“验证”,并使用像Flyway这样的数据库迁移工具来管理数据库模式中的更改。
好吧!现在让我们来创建Note
模型。我们的Note
模型有以下领域 -
id
:带自动递增的主键。title
:备注的标题。(NOT NULL字段)content
:笔记的内容。(NOT NULL字段)createdAt
:Note
创建时间。updatedAt
:Note
更新时间。model
inside 的新包,com.example.easynotes
并添加一个名为Note.java
以下内容的类-
package com.example.easynotes.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import java.util.Date;
@Entity
@Table(name = "notes")
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(value = {"createdAt", "updatedAt"},
allowGetters = true)
public class Note implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank
private String title;
@NotBlank
private String content;
@Column(nullable = false, updatable = false)
@Temporal(TemporalType.TIMESTAMP)
@CreatedDate
private Date createdAt;
@Column(nullable = false)
@Temporal(TemporalType.TIMESTAMP)
@LastModifiedDate
private Date updatedAt;
// Getters and Setters ... (Omitted for brevity)
}
@Entity
注释。它用于将该类标记为持久的Java类。@Table
注释用于提供此实体将映射到的表的详细信息。@Id
注释用于定义主键。@GeneratedValue
注释用于定义主键生成策略。在上述情况下,我们宣布主键是一个Auto Increment
字段。@NotBlank
注释用于验证注释字段是否为not null
空。@Column
注释用于定义将映射到注释字段的列的属性。您可以定义多个属性,如名称,长度,可为空,可更新等。默认情况下,名为的字段将createdAt
映射到created_at
数据库表中指定的列。即所有的骆驼案件都被下划线取代。
如果您想将字段映射到不同的列,可以使用以下命令指定它 -
@Column(name = "created_on")
private String createdAt;
@Temporal
注释java.util.Date
和java.util.Calendar
类一起使用。它将Java Object中的日期和时间值转换为兼容的数据库类型,反之亦然。@JsonIgnoreProperties
注释是杰克逊的注释。Spring Boot使用Jackson将JSON序列化和反序列化Java对象。createdAt
和updatedAt
值。如果他们提供这些值,那么我们会简单地忽略它们。但是,我们将在JSON响应中包含这些值。在我们的Note
模型中,我们已经注解createdAt
,并updatedAt
与领域@CreatedDate
,并@LastModifiedDate
分别标注。
现在,我们想要的是,只要我们创建或更新实体,这些字段就会自动填充。
要做到这一点,我们需要做两件事 -
1.将Spring Data JPA添加AuditingEntityListener
到域模型中。
我们已经在我们的Note
模型中使用了注释@EntityListeners(AuditingEntityListener.class)
。
2.在主应用程序中启用JPA审核。
打开EasyNotesApplication.java
并添加@EnableJpaAuditing
注释。
@SpringBootApplication
@EnableJpaAuditing
public class EasyNotesApplication {
public static void main(String[] args) {
SpringApplication.run(EasyNotesApplication.class, args);
}
}
接下来我们要做的是创建一个存储库来访问数据库中的Note数据。
那么,Spring Data JPA已经在这里介绍了我们。它带有一个JpaRepository
接口,该接口定义实体上所有CRUD操作的方法,以及一个默认的JpaRepository
调用实现SimpleJpaRepository
。
现在创建存储库。首先,创建一个repository
在基础包内调用的新包com.example.easynotes
。然后,创建一个接口NoteRepository
并将其从JpaRepository
-
package com.example.easynotes.repository;
import com.example.easynotes.model.Note;
import org.springframework.data.jpa.repository.JpaRepository;
@Repository
public interface NoteRepository extends JpaRepository<Note, Long> {
}
请注意,我们使用注释标注了界面@Repository
。这告诉Spring在组件扫描期间引导存储库。
大!这就是您在存储库层中必须做的所有事情。现在,您将能够使用JpaRepository的方法,如save()
,findOne()
,findAll()
,count()
,delete()
等。
你不需要实现这些方法。Spring Data JPA已经实现了它们SimpleJpaRepository
。这个实现在运行时被Spring自动插入。
检查SimpleJpaRepository文档中提供的所有方法。
我们将Note
在下一节中定义用于创建,检索,更新和删除a的Rest API 。
ResourceNotFoundException
只要在数据库中找不到Note
给定的API,API就会抛出id
。
以下是定义ResourceNotFoundException
。(我创建了一个名为exception
inside 的包com.example.easynotes
来存储这个异常类) -
package com.example.easynotes.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
private String resourceName;
private String fieldName;
private Object fieldValue;
public ResourceNotFoundException( String resourceName, String fieldName, Object fieldValue) {
super(String.format("%s not found with %s : '%s'", resourceName, fieldName, fieldValue));
this.resourceName = resourceName;
this.fieldName = fieldName;
this.fieldValue = fieldValue;
}
public String getResourceName() {
return resourceName;
}
public String getFieldName() {
return fieldName;
}
public Object getFieldValue() {
return fieldValue;
}
}
注意@ResponseStatus
在上述异常类中使用注释。这将导致Spring引导以指定的HTTP状态码进行响应,无论何时从您的控制器抛出此异常。
最后一步 - 我们现在将创建REST API来创建,检索,更新和删除注释。
首先,controller
在里面创建一个新的包com.example.easynotes
。然后,创建一个NoteController.java
包含以下内容的新课程-
package com.example.easynotes.controller;
import com.example.easynotes.exception.ResourceNotFoundException;
import com.example.easynotes.model.Note;
import com.example.easynotes.repository.NoteRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping("/api")
public class NoteController {
@Autowired
NoteRepository noteRepository;
// Get All Notes
// Create a new Note
// Get a Single Note
// Update a Note
// Delete a Note
}
@RestController
注释是Spring @Controller
和@ResponseBody
注释的组合。
该@Controller
注释被用来定义一个控制器和所述@ResponseBody
注释被用于指示一个方法的返回值应作为所述请求的响应主体。
@RequestMapping("/api")
声明此控制器中所有apis的url将以/api
。
现在我们来看看所有apis的执行情况。
// Get All Notes
@GetMapping("/notes")
public List<Note> getAllNotes() {
return noteRepository.findAll();
}
上述方法非常简单。它调用JpaRepository的findAll()
方法从数据库中检索所有注释并返回整个列表。
此外,@GetMapping("/notes")
注释是一种简短形式@RequestMapping(value="/notes", method=RequestMethod.GET)
。
// Create a new Note
@PostMapping("/notes")
public Note createNote(@Valid @RequestBody Note note) {
return noteRepository.save(note);
}
该@RequestBody
注释用于将请求主体与方法参数绑定。
该@Valid
注释可以确保请求主体是有效的。请记住,我们在模型中标注了注释的标题和@NotBlank
注释内容Note
?
如果请求主体没有标题或内容,那么spring会400 BadRequest
向客户端返回错误。
// Get a Single Note
@GetMapping("/notes/{id}")
public Note getNoteById(@PathVariable(value = "id") Long noteId) {
return noteRepository.findById(noteId)
.orElseThrow(() -> new ResourceNotFoundException("Note", "id", noteId));
}
的@PathVariable
注释,顾名思义,是用来与方法参数路径变量绑定。
在上面的方法中,我们抛出一个没有找到给定id的ResourceNotFoundException
a Note
。
这将导致Spring Boot向客户端返回一个404 Not Found错误(请记住,我们已经@ResponseStatus(value = HttpStatus.NOT_FOUND)
为ResourceNotFoundException
该类添加了注释)。
// Update a Note
@PutMapping("/notes/{id}")
public Note updateNote(@PathVariable(value = "id") Long noteId,
@Valid @RequestBody Note noteDetails) {
Note note = noteRepository.findById(noteId)
.orElseThrow(() -> new ResourceNotFoundException("Note", "id", noteId));
note.setTitle(noteDetails.getTitle());
note.setContent(noteDetails.getContent());
Note updatedNote = noteRepository.save(note);
return updatedNote;
}
// Delete a Note
@DeleteMapping("/notes/{id}")
public ResponseEntity<?> deleteNote(@PathVariable(value = "id") Long noteId) {
Note note = noteRepository.findById(noteId)
.orElseThrow(() -> new ResourceNotFoundException("Note", "id", noteId));
noteRepository.delete(note);
return ResponseEntity.ok().build();
}
我们已经成功为我们的应用程序构建了所有apis。现在运行该应用并测试apis。
只需转到应用程序的根目录并输入以下命令即可运行它 -
$ mvn spring-boot:run
该应用程序将从Spring Boot的默认tomcat端口8080开始。
大!现在,是时候用邮差测试我们的apis了。
POST /api/notes
API 创建新的noteGET /api/notes
API 检索所有NotesGET /api/notes/{noteId}
API 检索单个NotePUT /api/notes/{noteId}
API 更新noteDELETE /api/notes/{noteId}
API 删除notehttps://www.leftso.com/article/406.html