mongodb安装_使用Spring Boot和MongoDB创建REST API

mongodb安装

mongodb安装

今年,我以不同的方式迎接圣诞节:我是Java Advent Calendar的一部分。 让我们为圣诞节做准备:

Spring Boot是一个自以为是的框架,可简化Spring应用程序的开发。 它使我们摆脱了复杂的配置文件的束缚,并帮助我们创建了不需要外部servlet容器的独立Spring应用程序。

这听起来实在令人难以置信,但Spring Boot确实可以完成所有这一切

这篇博客文章演示了实现REST API多么容易,该REST API为保存到MongoDB数据库中的待办事项提供CRUD操作。

让我们开始创建我们的Maven项目。

这篇博客文章假定您已经安装了MongoDB数据库。 如果尚未执行此操作,则可以按照博客文章中的说明进行操作:使用MongoDB访问数据

创建我们的Maven项目

我们可以按照以下步骤创建Maven项目:

  1. 使用spring-boot-starter-parent POM作为我们的Maven项目的父POM。 这可以确保我们的项目从Spring Boot继承合理的默认设置。
  2. Spring Boot Maven插件添加到我们的项目中。 这个插件允许我们将应用程序打包到可执行的jar文件中,将其打包到war存档中,然后运行该应用程序。
  3. 配置我们项目的依赖项。 我们需要配置以下依赖项:
    • spring-boot-starter-web依赖关系提供了Web应用程序的依赖关系。
    • spring-data-mongodb依赖项提供了与MongoDB文档数据库的集成。
  4. 启用S​​pring Boot的Java 8支持。
  5. 配置我们的应用程序的主类。 此类负责配置和启动我们的应用程序。

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应用程序:

  1. 创建com.javaadvent.bootrest包的TodoAppConfig类。
  2. 启用S​​pring Boot自动配置。
  3. 配置Spring容器以扫描从com.javaadvent.bootrest包的子包中找到的组件。
  4. 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连接。

补充阅读:

让我们继续并实现我们的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请求必须使用从请求正文中找到的信息来更新现有待办事项的信息,并返回更新后的待办事项的信息。

通过执行以下步骤,我们可以满足这些要求:

  1. 创建包含单个待办事项条目信息的实体。
  2. 创建用于将待办事项保存到MongoDB数据库并从中查找待办事项的存储库。
  3. 创建负责将DTO映射到域对象,反之亦然的服务层。 服务层的目的是将域模型与Web层隔离。
  4. 创建用于处理HTTP请求并将正确的响应返回给客户端的控制器类。

这个例子非常简单,我们可以将存储库注入到控制器中。 但是,由于在实施现实应用程序时这不是可行的策略,因此我们将在Web层和存储库层之间添加一个服务层。

让我们开始吧。

创建实体

我们需要创建包含单个待办事项条目信息的实体类。 我们可以按照以下步骤进行操作:

  1. iddescriptiontitle字段添加到创建的实体类中。 通过使用@Id注释对id字段进行注释来配置实体的id字段。
  2. 指定常量( MAX_LENGTH_DESCRIPTIONMAX_LENGTH_TITLE ),这些常量指定描述标题字段的最大长度。
  3. 将静态生成器类添加到实体类。 此类用于创建新的Todo对象。
  4. 向实体类添加一个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支持,因此必须遵循以下步骤:

  1. 创建一个扩展Repository <T,ID>接口的接口。
  2. 将以下存储库方法添加到创建的接口:
    1. void delete(删除Todo的方法)删除作为方法参数给出的todo条目。
    2. 列表findAll()方法返回从数据库中找到的所有待办事项条目。
    3. 可选的findOne(String id)方法返回单个待办事项的信息。 如果未找到待办事项,则此方法返回一个空的Optional
    4. 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);
}
补充阅读:

让我们继续并创建示例应用程序的服务层。

创建服务层

首先,我们必须创建一个服务接口,为待办事项提供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接口。 我们可以按照以下步骤进行操作:

  1. 通过使用构造函数注入将我们的​​存储库注入服务类。
  2. 私有Todo findTodoById(String id)方法添加到服务类,并通过返回找到的Todo对象或抛出TodoNotFoundException来实现它。
  3. 在服务类中添加一个私有TodoDTO convertToDTO(Todo model)方法,并通过将Todo对象转换为TodoDTO对象并返回创建的对象来实现该方法。
  4. 添加一个私有列表convertToDTOs(Listmodels)并通过将Todo对象的列表转换为TodoDTO对象的列表并返回创建的列表来实现它。
  5. 实现TodoDTO create(TodoDTO todo)方法。 此方法创建一个新的Todo对象,将创建的对象保存到MongoDB数据库,并返回创建的todo条目的信息。
  6. 实现TodoDTO delete(String id)方法。 此方法找到删除的Todo对象,将其删除,然后返回删除的Todo条目的信息。 如果未找到具有给定id的Todo对象,则此方法将抛出TodoNotFoundException
  7. 实现List findAll()方法。 此方法从数据库检索所有Todo对象,将它们转换为TodoDTO对象列表,然后返回创建的列表。
  8. 实现TodoDTO findById(String id)方法。 此方法从数据库中查找Todo对象,将其转换为TodoDTO对象,然后返回创建的TodoDTO对象。 如果未找到待办事项条目,则此方法将抛出TodoNotFoundException
  9. 实现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请求,并将正确的响应发送回客户端。 我们可以按照以下步骤进行操作:

  1. 通过使用构造函数注入将服务注入我们的控制器。
  2. create()方法添加到我们的控制器并通过以下步骤实现它:
    1. 从请求正文中读取创建的待办事项条目的信息。
    2. 验证创建的待办事项条目的信息。
    3. 创建一个新的待办事项条目并返回创建的待办事项条目。 将响应状态设置为201。
  3. 通过将已删除的待办事项条目的ID委派给我们的服务来实现delete()方法,并返回已删除的待办事项条目。
  4. 通过从数据库中找到待办事项并返回找到的待办事项来实现findAll()方法。
  5. 通过从数据库中找到待办事项并返回找到的待办事项来实现findById()方法。
  6. 通过执行以下步骤来实现update()方法:
    1. 从请求正文中读取更新的待办事项条目的信息。
    2. 验证更新的待办事项条目的信息。
    3. 更新待办事项的信息并返回更新的待办事项。
  7. 创建一个@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-webspring-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安装

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值