mongodb安装
今年,我以不同的方式迎接圣诞节:我是Java Advent Calendar的一部分。 让我们为圣诞节做准备:
Spring Boot是一个自以为是的框架,可简化Spring应用程序的开发。 它使我们摆脱了复杂的配置文件的束缚,并帮助我们创建了不需要外部servlet容器的独立Spring应用程序。
这听起来实在令人难以置信,但Spring Boot确实可以完成所有这一切。
这篇博客文章演示了实现REST API多么容易,该REST API为保存到MongoDB数据库中的待办事项提供CRUD操作。
让我们开始创建我们的Maven项目。
这篇博客文章假定您已经安装了MongoDB数据库。 如果尚未执行此操作,则可以按照博客文章中的说明进行操作:使用MongoDB访问数据。
创建我们的Maven项目
我们可以按照以下步骤创建Maven项目:
- 使用spring-boot-starter-parent POM作为我们的Maven项目的父POM。 这可以确保我们的项目从Spring Boot继承合理的默认设置。
- 将Spring Boot Maven插件添加到我们的项目中。 这个插件允许我们将应用程序打包到可执行的jar文件中,将其打包到war存档中,然后运行该应用程序。
- 配置我们项目的依赖项。 我们需要配置以下依赖项:
- spring-boot-starter-web依赖关系提供了Web应用程序的依赖关系。
- spring-data-mongodb依赖项提供了与MongoDB文档数据库的集成。
- 启用Spring Boot的Java 8支持。
- 配置我们的应用程序的主类。 此类负责配置和启动我们的应用程序。
pom.xml文件的相关部分如下所示:
<properties>
<!-- Enable Java 8 -->
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Configure the main class of our Spring Boot application -->
<start-class>com.javaadvent.bootrest.TodoAppConfig</start-class>
</properties>
<!-- Inherit defaults from Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.1.9.RELEASE</version>
</parent>
<dependencies>
<!-- Get the dependencies of a web application -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Data MongoDB-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Spring Boot Maven Support -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
补充阅读:
让我们继续研究如何配置应用程序。
配置我们的应用
我们可以按照以下步骤配置Spring Boot应用程序:
- 创建com.javaadvent.bootrest包的TodoAppConfig类。
- 启用Spring Boot自动配置。
- 配置Spring容器以扫描从com.javaadvent.bootrest包的子包中找到的组件。
- 将main()方法添加到TodoAppConfig类,并通过运行我们的应用程序来实现。
TodoAppConfig类的源代码如下所示:
package com.javaadvent.bootrest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class TodoAppConfig {
public static void main(String[] args) {
SpringApplication.run(TodoAppConfig.class, args);
}
}
现在,我们已经创建了配置类,用于配置和运行我们的Spring Boot应用程序。 由于从类路径中找到了MongoDB jar,因此Spring Boot使用其默认设置来配置MongoDB连接。
补充阅读:
- Spring Boot参考手册:13.2定位主应用程序类
- Spring Boot参考手册:14.配置类
- @EnableAutoConfiguration批注的Javadoc
- Spring Boot参考手册:15.自动配置
- SpringApplication类的Javadoc
- Spring Boot参考手册:27.2.1连接到MongoDB数据库
让我们继续并实现我们的REST API。
实施我们的REST API
我们需要实现一个REST API,为待办事项提供CRUD操作。 我们的REST API的要求是:
- 发送到url'/ api / todo'的POST请求必须使用从请求正文中找到的信息来创建一个新的todo条目,并返回创建的todo条目的信息。
- 发送到URL'/ api / todo / {id}'的DELETE请求必须删除从URL找到ID的待办事项,并返回已删除的待办事项的信息。
- 发送到URL'/ api / todo'的GET请求必须返回从数据库中找到的所有todo条目。
- 发送到url'/ api / todo / {id}'的GET请求必须返回其id从URL中找到的todo条目的信息。
- 发送到url'/ api / todo / {id}'的PUT请求必须使用从请求正文中找到的信息来更新现有待办事项的信息,并返回更新后的待办事项的信息。
通过执行以下步骤,我们可以满足这些要求:
- 创建包含单个待办事项条目信息的实体。
- 创建用于将待办事项保存到MongoDB数据库并从中查找待办事项的存储库。
- 创建负责将DTO映射到域对象,反之亦然的服务层。 服务层的目的是将域模型与Web层隔离。
- 创建用于处理HTTP请求并将正确的响应返回给客户端的控制器类。
这个例子非常简单,我们可以将存储库注入到控制器中。 但是,由于在实施现实应用程序时这不是可行的策略,因此我们将在Web层和存储库层之间添加一个服务层。
让我们开始吧。
创建实体
我们需要创建包含单个待办事项条目信息的实体类。 我们可以按照以下步骤进行操作:
- 将id , description和title字段添加到创建的实体类中。 通过使用@Id注释对id字段进行注释来配置实体的id字段。
- 指定常量( MAX_LENGTH_DESCRIPTION和MAX_LENGTH_TITLE ),这些常量指定描述和标题字段的最大长度。
- 将静态生成器类添加到实体类。 此类用于创建新的Todo对象。
- 向实体类添加一个update()方法。 如果将有效值作为方法参数给出,则此方法仅更新实体的标题和描述。
Todo类的源代码如下所示:
import org.springframework.data.annotation.Id;
import static com.javaadvent.bootrest.util.PreCondition.isTrue;
import static com.javaadvent.bootrest.util.PreCondition.notEmpty;
import static com.javaadvent.bootrest.util.PreCondition.notNull;
final class Todo {
static final int MAX_LENGTH_DESCRIPTION = 500;
static final int MAX_LENGTH_TITLE = 100;
@Id
private String id;
private String description;
private String title;
public Todo() {}
private Todo(Builder builder) {
this.description = builder.description;
this.title = builder.title;
}
static Builder getBuilder() {
return new Builder();
}
//Other getters are omitted
public void update(String title, String description) {
checkTitleAndDescription(title, description);
this.title = title;
this.description = description;
}
/**
* We don't have to use the builder pattern here because the constructed
* class has only two String fields. However, I use the builder pattern
* in this example because it makes the code a bit easier to read.
*/
static class Builder {
private String description;
private String title;
private Builder() {}
Builder description(String description) {
this.description = description;
return this;
}
Builder title(String title) {
this.title = title;
return this;
}
Todo build() {
Todo build = new Todo(this);
build.checkTitleAndDescription(build.getTitle(), build.getDescription());
return build;
}
}
private void checkTitleAndDescription(String title, String description) {
notNull(title, "Title cannot be null");
notEmpty(title, "Title cannot be empty");
isTrue(title.length() <= MAX_LENGTH_TITLE,
"Title cannot be longer than %d characters",
MAX_LENGTH_TITLE
);
if (description != null) {
isTrue(description.length() <= MAX_LENGTH_DESCRIPTION,
"Description cannot be longer than %d characters",
MAX_LENGTH_DESCRIPTION
);
}
}
}
补充阅读:
让我们继续并创建与MongoDB数据库通信的存储库。
创建存储库
我们必须创建一个存储库接口,该接口用于将Todo对象保存到MondoDB数据库并从中检索Todo对象。
如果我们不想使用Java 8对Spring Data的支持,则可以通过创建扩展CrudRepository <T,ID>接口的接口来创建存储库。 但是,由于我们要使用Java 8支持,因此必须遵循以下步骤:
- 创建一个扩展Repository <T,ID>接口的接口。
- 将以下存储库方法添加到创建的接口:
- void delete(删除Todo的方法)删除作为方法参数给出的todo条目。
- 列表findAll()方法返回从数据库中找到的所有待办事项条目。
- 可选的findOne(String id)方法返回单个待办事项的信息。 如果未找到待办事项,则此方法返回一个空的Optional 。
- Todo save(保存Todo)方法将新的todo条目保存到数据库中,并返回保存的todo条目。
TodoRepository接口的源代码如下所示:
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.Optional;
interface TodoRepository extends Repository<Todo, String> {
void delete(Todo deleted);
List<Todo> findAll();
Optional<Todo> findOne(String id);
Todo save(Todo saved);
}
补充阅读:
- CrudRepository <T,ID>接口的Javadoc
- Repository <T,ID>接口的Javadoc
- Spring Data MongoDB参考手册:5.使用Spring Data存储库
- Spring Data MongoDB参考手册:5.3.1细调存储库定义
让我们继续并创建示例应用程序的服务层。
创建服务层
首先,我们必须创建一个服务接口,为待办事项提供CRUD操作。 TodoService接口的源代码如下所示:
import java.util.List;
interface TodoService {
TodoDTO create(TodoDTO todo);
TodoDTO delete(String id);
List<TodoDTO> findAll();
TodoDTO findById(String id);
TodoDTO update(TodoDTO todo);
}
TodoDTO类是DTO,其中包含单个todo条目的信息。 在创建示例应用程序的Web层时,我们将详细讨论它。
其次,我们必须实现TodoService接口。 我们可以按照以下步骤进行操作:
- 通过使用构造函数注入将我们的存储库注入服务类。
- 将私有Todo findTodoById(String id)方法添加到服务类,并通过返回找到的Todo对象或抛出TodoNotFoundException来实现它。
- 在服务类中添加一个私有TodoDTO convertToDTO(Todo model)方法,并通过将Todo对象转换为TodoDTO对象并返回创建的对象来实现该方法。
- 添加一个私有列表convertToDTOs(Listmodels)并通过将Todo对象的列表转换为TodoDTO对象的列表并返回创建的列表来实现它。
- 实现TodoDTO create(TodoDTO todo)方法。 此方法创建一个新的Todo对象,将创建的对象保存到MongoDB数据库,并返回创建的todo条目的信息。
- 实现TodoDTO delete(String id)方法。 此方法找到删除的Todo对象,将其删除,然后返回删除的Todo条目的信息。 如果未找到具有给定id的Todo对象,则此方法将抛出TodoNotFoundException 。
- 实现List findAll()方法。 此方法从数据库检索所有Todo对象,将它们转换为TodoDTO对象列表,然后返回创建的列表。
- 实现TodoDTO findById(String id)方法。 此方法从数据库中查找Todo对象,将其转换为TodoDTO对象,然后返回创建的TodoDTO对象。 如果未找到待办事项条目,则此方法将抛出TodoNotFoundException 。
- 实现TodoDTO update(TodoDTO todo)方法。 此方法从数据库中查找更新的Todo对象,更新其标题和说明,保存并返回更新的信息。 如果未找到更新的Todo对象,则此方法将抛出TodoNotFoundException 。
MongoDBTodoService的源代码如下所示:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
import static java.util.stream.Collectors.toList;
@Service
final class MongoDBTodoService implements TodoService {
private final TodoRepository repository;
@Autowired
MongoDBTodoService(TodoRepository repository) {
this.repository = repository;
}
@Override
public TodoDTO create(TodoDTO todo) {
Todo persisted = Todo.getBuilder()
.title(todo.getTitle())
.description(todo.getDescription())
.build();
persisted = repository.save(persisted);
return convertToDTO(persisted);
}
@Override
public TodoDTO delete(String id) {
Todo deleted = findTodoById(id);
repository.delete(deleted);
return convertToDTO(deleted);
}
@Override
public List<tododto> findAll() {
List<todo> todoEntries = repository.findAll();
return convertToDTOs(todoEntries);
}
private List<tododto> convertToDTOs(List<todo> models) {
return models.stream()
.map(this::convertToDTO)
.collect(toList());
}
@Override
public TodoDTO findById(String id) {
Todo found = findTodoById(id);
return convertToDTO(found);
}
@Override
public TodoDTO update(TodoDTO todo) {
Todo updated = findTodoById(todo.getId());
updated.update(todo.getTitle(), todo.getDescription());
updated = repository.save(updated);
return convertToDTO(updated);
}
private Todo findTodoById(String id) {
Optional<todo> result = repository.findOne(id);
return result.orElseThrow(() -> new TodoNotFoundException(id));
}
private TodoDTO convertToDTO(Todo model) {
TodoDTO dto = new TodoDTO();
dto.setId(model.getId());
dto.setTitle(model.getTitle());
dto.setDescription(model.getDescription());
return dto;
}
}
现在,我们已经创建了示例应用程序的服务层。 让我们继续创建控制器类。
创建控制器类
首先,我们需要创建DTO类,其中包含单个待办事项的信息,并指定用于确保仅将有效信息保存到数据库的验证规则。 TodoDTO类的源代码如下所示:
import org.hibernate.validator.constraints.NotEmpty;
import javax.validation.constraints.Size;
public final class TodoDTO {
private String id;
@Size(max = Todo.MAX_LENGTH_DESCRIPTION)
private String description;
@NotEmpty
@Size(max = Todo.MAX_LENGTH_TITLE)
private String title;
//Constructor, getters, and setters are omitted
}
补充阅读:
其次,我们必须创建控制器类来处理发送到我们的REST API的HTTP请求,并将正确的响应发送回客户端。 我们可以按照以下步骤进行操作:
- 通过使用构造函数注入将服务注入我们的控制器。
- 将create()方法添加到我们的控制器并通过以下步骤实现它:
- 从请求正文中读取创建的待办事项条目的信息。
- 验证创建的待办事项条目的信息。
- 创建一个新的待办事项条目并返回创建的待办事项条目。 将响应状态设置为201。
- 通过将已删除的待办事项条目的ID委派给我们的服务来实现delete()方法,并返回已删除的待办事项条目。
- 通过从数据库中找到待办事项并返回找到的待办事项来实现findAll()方法。
- 通过从数据库中找到待办事项并返回找到的待办事项来实现findById()方法。
- 通过执行以下步骤来实现update()方法:
- 从请求正文中读取更新的待办事项条目的信息。
- 验证更新的待办事项条目的信息。
- 更新待办事项的信息并返回更新的待办事项。
- 创建一个@ExceptionHandler方法,如果未找到todo条目(抛出TodoNotFoundException ),则将响应状态设置为404。
TodoController类的源代码如下所示:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping("/api/todo")
final class TodoController {
private final TodoService service;
@Autowired
TodoController(TodoService service) {
this.service = service;
}
@RequestMapping(method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
TodoDTO create(@RequestBody @Valid TodoDTO todoEntry) {
return service.create(todoEntry);
}
@RequestMapping(value = "{id}", method = RequestMethod.DELETE)
TodoDTO delete(@PathVariable("id") String id) {
return service.delete(id);
}
@RequestMapping(method = RequestMethod.GET)
List<TodoDTO> findAll() {
return service.findAll();
}
@RequestMapping(value = "{id}", method = RequestMethod.GET)
TodoDTO findById(@PathVariable("id") String id) {
return service.findById(id);
}
@RequestMapping(value = "{id}", method = RequestMethod.PUT)
TodoDTO update(@RequestBody @Valid TodoDTO todoEntry) {
return service.update(todoEntry);
}
@ExceptionHandler
@ResponseStatus(HttpStatus.NOT_FOUND)
public void handleTodoNotFound(TodoNotFoundException ex) {
}
}
如果验证失败,则我们的REST API将验证错误作为JSON返回,并将响应状态设置为400。如果您想了解更多有关此信息,请阅读标题为: Spring从Trenches:向REST API添加验证的博客文章。
这就对了。 现在,我们已经创建了一个REST API,该API为待办事项提供CRUD操作并将其保存到MongoDB数据库中。 让我们总结一下我们从这篇博客文章中学到的知识。
概要
这篇博客文章教会了我们三件事:
- 我们可以通过仅声明两个依赖项来获得Maven所需的依赖项: spring-boot-starter-web和spring-data-mongodb 。
- 如果我们对Spring Boot的默认配置感到满意,则可以通过使用Web应用程序的自动配置支持并将新的jar“丢弃”到类路径来配置我们的Web应用程序。
- 我们学习了如何创建一个简单的REST API,该API将信息保存到MongoDB数据库并从中查找信息。
PS:您可以从Github获得此博客文章的示例应用程序。
翻译自: https://www.javacodegeeks.com/2014/12/creating-a-rest-api-with-spring-boot-and-mongodb.html
mongodb安装