Spring 实战(第五版)
  • Spring 实战(第 5 版)
  • 第一部分 Spring 基础
  • 第 1 章 Spring 入门
    • 1.1 什么是 Spring?
    • 1.2 初始化 Spring 应用程序
      • 1.2.1 使用 Spring Tool Suite 初始化 Spring 项目
      • 1.2.2 检查 Spring 项目结构
    • 1.3 编写 Spring 应用程序
      • 1.3.1 处理 web 请求
      • 1.3.2 定义视图
      • 1.3.3 测试控制器
      • 1.3.4 构建并运行应用程序
      • 1.3.5 了解 Spring Boot DevTools
      • 1.3.6 回顾
    • 1.4 俯瞰 Spring 风景线
      • 1.4.1 Spring 核心框架
      • 1.4.2 Spring Boot
      • 1.4.3 Spring Data
      • 1.4.4 Spring Security
      • 1.4.5 Spring Integration 和 Spring Batch
      • 1.4.6 Spring Cloud
    • 1.5 小结
  • 第 2 章 开发 Web 应用程序
    • 2.1 展示信息
      • 2.1.1 建立域
      • 2.1.2 创建控制器类
      • 2.1.3 设计视图
    • 2.2 处理表单提交
    • 2.3 验证表单输入
      • 2.3.1 声明验证规则
      • 2.3.2 在表单绑定时执行验证
      • 2.3.3 显示验证错误
    • 2.4 使用视图控制器
    • 2.5 选择视图模板库
      • 2.5.1 缓存模板
    • 2.6 小结
  • 第 3 章 处理数据
    • 3.1 使用 JDBC 读写数据
      • 3.1.1 为域适配持久化
      • 3.1.2 使用 JdbcTemplate
      • 3.1.3 定义模式并预加载数据
      • 3.1.4 插入数据
    • 3.2 使用 Spring Data JPA 持久化数据
      • 3.2.1 添加 Spring Data JPA 到数据库中
      • 3.2.2 注解域作为实体
      • 3.2.3 声明 JPA repository
      • 3.2.4 自定义 JPA repository
    • 3.3 小结
  • 第 4 章 Spring 安全
    • 4.1 启用 Spring Security
    • 4.2 配置 Spring Security
      • 4.2.1 内存用户存储
      • 4.2.2 基于 JDBC 的用户存储
      • 4.2.3 LDAP 支持的用户存储
      • 4.2.4 自定义用户身份验证
    • 4.3 保护 web 请求
      • 4.3.1 保护请求
      • 4.3.2 创建用户登录页面
      • 4.3.3 登出
      • 4.3.4 阻止跨站请求伪造攻击
    • 4.4 了解你的用户
    • 4.5 小结
  • 第 5 章 使用配置属性
    • 5.1 微调自动配置
      • 5.1.1 理解 Spring 环境抽象
      • 5.1.2 配置数据源
      • 5.1.3 配置嵌入式服务器
      • 5.1.4 配置日志
      • 5.1.5 使用特殊的属性值
    • 5.2 创建自己的配置属性
      • 5.2.1 定义配置属性持有者
      • 5.2.2 声明配置属性元数据
    • 5.3 使用 profile 文件进行配置
      • 5.3.1 定义特定 profile 的属性
      • 5.3.2 激活 profile 文件
      • 5.3.3 有条件地使用 profile 文件创建 bean
    • 5.4 小结
  • 第二部分 集成 Spring
  • 第 6 章 创建 REST 服务
    • 6.1 编写 RESTful 控制器
      • 6.1.1 从服务器获取数据
      • 6.1.2 向服务器发送数据
      • 6.1.3 更新服务器上的资源
      • 6.1.4 从服务器删除数据
    • 6.2 启用超媒体
      • 6.2.1 添加超链接
      • 6.2.2 创建资源装配器
      • 6.2.3 嵌套命名关系
    • 6.3 启用以数据为中心的服务
      • 6.3.1 调整资源路径和关系名称
      • 6.3.2 分页和排序
      • 6.3.3 添加用户端点
      • 6.3.4 向 Spring Data 端点添加用户超链接
    • 6.4 小结
  • 第 7 章 调用 REST 服务
    • 7.1 使用 RestTemplate 调用 REST 端点
      • 7.1.1 请求 GET 资源
      • 7.1.2 请求 PUT 资源
      • 7.1.3 请求 DELETE 资源
      • 7.1.4 请求 POST 资源
    • 7.2 使用 Traverson 引导 REST API
    • 7.3 小结
  • 第 8 章 发送异步消息
    • 8.1 使用 JMS 发送消息
      • 8.1.3 接收 JMS 消息
      • 8.1.2 使用 JmsTemplate 发送消息
      • 8.1.1 设置 JMS
    • 8.2 使用 RabbitMQ 和 AMQP
      • 8.2.1 添加 RabbitMQ 到 Spring 中
      • 8.2.2 使用 RabbitTemplate 发送消息
      • 8.2.3 从 RabbitMQ 接收消息
    • 8.3 使用 Kafka 发送消息
      • 8.3.1 在 Spring 中设置 Kafka
      • 8.3.2 使用 KafkaTemplate 发送消息
      • 8.3.3 编写 Kafka 监听器
    • 8.4 小结
  • 第 9 章 集成 Spring
    • 9.1 声明简单的集成流
      • 9.1.1 使用 XML 定义集成流
      • 9.1.2 在 Java 中配置集成流
      • 9.1.3 使用 Spring Integration 的 DSL 配置
    • 9.2 探索 Spring Integration
      • 9.2.1 消息通道
      • 9.2.2 过滤器
      • 9.2.3 转换器
      • 9.2.4 路由
      • 9.2.5 分割器
      • 9.2.6 服务激活器
      • 9.2.7 网关
      • 9.2.8 通道适配器
      • 9.2.9 端点模块
    • 9.3 创建 Email 集成流
    • 9.4 总结
  • 第三部分 响应式 Spring
  • 第 10 章 Reactor 介绍
    • 10.1 理解响应式编程
      • 10.1.1 定义响应式流
    • 10.2 Reactor
      • 10.2.1 图解响应式流
      • 10.2.2 添加 Reactor 依赖
    • 10.3 通用响应式操作实战
      • 10.3.1 创建响应式类型
      • 10.3.2 响应式类型结合
      • 10.3.3 转换和过滤响应式流
      • 10.3.4 对反应类型执行逻辑操作
    • 10.4 总结
  • 第 11 章 开发响应式 API
    • 11.1 使用 Spring WebFlux
      • 11.1.1 Spring WebFlux 介绍
      • 11.1.2 编写响应式 Controller
    • 11.2 定义函数式请求处理程序
    • 11.3 测试响应式 Controller
      • 11.3.1 测试 GET 请求
      • 11.3.2 测试 POST 请求
      • 11.3.3 使用线上服务器进行测试
    • 11.4 响应式消费 REST API
      • 11.4.1 通过 GET 方式获取资源
      • 11.4.2 通过 POST 方式发送资源
      • 11.4.3 删除资源
      • 11.4.4 处理请求错误
      • 11.4.5 请求转换
    • 11.5 保护响应式 web API
      • 11.5.1 配置响应式 Web 安全
      • 11.5.2 配置响应式用户信息服务
    • 11.6 总结
  • 第 12 章 响应式持久化数据
    • 12.1 理解 Spring Data 响应式历程
      • 12.1.1 Spring Data 响应式精髓
      • 12.1.2 在响应式与非响应式之间进行转换
      • 12.1.3 开发响应式库
    • 12.2 使用响应式 Cassandra 库
      • 12.2.1 开启 Spring Data Cassandra
      • 12.2.2 理解 Cassandra 数据模型
      • 12.2.3 Cassandra 持久化实体映射
      • 12.2.4 编写响应式 Cassandra 库
    • 12.3 编写响应式 MongoDB 库
      • 12.3.1 开启Spring Data MongonDB
      • 12.3.2 MongoDB 持久化实体映射
      • 12.3.3 编写响应式 MongoDB 库
    • 12.4 总结
  • 第四部分 云原生 Spring
  • 第 13 章 服务发现
    • 13.1深入思考微服务
    • 13.2 配置服务注册
      • 13.2.1 配置 Eureka
      • 13.2.2 扩展 Eureka
    • 13.3 注册并发现服务
      • 13.3.1 配置 Eureka 客户端属性
      • 13.3.2 消费服务
    • 13.4 总结
  • 第 14 章 配置管理
    • 14.1 共享配置
    • 14.2 运行配置服务器
      • 14.2.1 启动配置服务器
      • 14.2.2 填写配置库
    • 14.3 消费共享的配置
    • 14.4 服务应用程序和特定配置文件的属性
      • 14.4.1 服务特定应用程序的属性
      • 14.4.2 服务配置文件属性
    • 14.5 为配置的属性加密
      • 14.5.1 在 Git 中加密属性
      • 14.5.2 在 Vault 中存储密码
    • 14.6 远程刷新配置属性
      • 14.6.1 手动刷新配置属性
      • 14.6.2 自动刷新配置属性
    • 14.7 总结
  • 第 15 章 处理失败和时延
    • 15.1 了解断路器
    • 15.2 定义断路器
      • 15.2.1 缓解时延
      • 15.2.2 管理断路器阈值
    • 15.3 管理失败事件
      • 15.3.1 介绍 Hystrix 面板
      • 15.3.2 了解 Hystrix 线程池
    • 15.4 聚合多个 Hystrix 流
    • 15.5 总结
  • 第五部分 部署Spring
  • 第 16 章 使用 SpringBoot Actuator
    • 16.1 介绍 Actuator
      • 16.1.1 配置 Actuator 基本路径
      • 16.1.2 启用和禁用 Actuator 端点
    • 16.2 使用 Actuator 端点
      • 16.2.1 获取重要的应用程序信息
      • 16.2.2 查看配置详细信息
      • 16.2.3 查看应用程序活动
      • 16.2.4 利用运行时指标
    • 16.3 自定义 Actuator
      • 16.3.1 向 /info 端点提供信息
      • 16.3.2 自定义健康指标
      • 16.3.3 注册自定义指标
      • 16.3.4 创建自定义端点
    • 16.4 保护 Actuator
    • 16.5 总结
  • 第 17 章 管理 Spring
    • 17.1 使用 SpringBoot Admin
      • 17.1.1 创建 Admin 服务端
      • 17.1.2 注册 Admin 客户端
    • 17.2 深入 Admin 服务端
      • 17.2.1 查看普通应用程序运行状况和信息
      • 17.2.2 观察关键指标
      • 17.2.3 检查环境属性
      • 17.2.4 查看并设置 log 级别
      • 17.2.5 监控线程
      • 17.2.6 追踪 HTTP 请求
    • 17.3 保护 Admin 服务端
      • 17.3.1 在 Admin 服务端中启用登录
      • 17.3.2 使用 Actuator 进行认证
    • 17.4 总结
  • 第 18 章 使用 JMX 监控 Spring
    • 18.1 使用 Actuator MBean
    • 18.2 创建自己的 MBean
    • 18.3 发送通知
    • 18.4 总结
  • 第 19 章 部署 Spring
    • 19.1 权衡部署选项
    • 19.2 构建并部署 WAR 文件
    • 19.3 将 JAR 文件推送到 Cloud Foundry
    • 19.4 在 Docker 容器中运行 SpringBoot
    • 19.5 终章
    • 19.6 总结
由 GitBook 提供支持
在本页

这有帮助吗?

  1. 第 2 章 开发 Web 应用程序
  2. 2.1 展示信息

2.1.2 创建控制器类

控制器是 Spring MVC 框架的主要参与者。它们的主要工作是处理 HTTP 请求,或者将请求传递给视图以呈现 HTML(浏览器显示),或者直接将数据写入响应体(RESTful)。在本章中,我们将重点讨论使用视图为 web 浏览器生成内容的控制器的类型。在第 6 章中,我们将讨论如何在 REST API 中编写处理请求的控制器。

对于 Taco Cloud 应用程序,需要一个简单的控制器来执行以下操作:

  • 处理请求路径为 /design 的 HTTP GET 请求

  • 构建成分列表

  • 将请求和成分数据提交给视图模板,以 HTML 的形式呈现并发送给请求的 web 浏览器

下面的 DesignTacoController 类处理这些需求。

程序清单 2.2 Spring 控制器类的开始
package tacos.web;
​
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import lombok.extern.slf4j.Slf4j;
​
import tacos.Taco;
import tacos.Ingredient;
import tacos.Ingredient.Type;
​
@Slf4j
@Controller
@RequestMapping("/design")
public class DesignTacoController {
    @GetMapping
    public String showDesignForm(Model model) {
        List<Ingredient> ingredients = Arrays.asList(
            new Ingredient("FLTO", "Flour Tortilla", Type.WRAP),
            new Ingredient("COTO", "Corn Tortilla", Type.WRAP),
            new Ingredient("GRBF", "Ground Beef", Type.PROTEIN),
            new Ingredient("CARN", "Carnitas", Type.PROTEIN),
            new Ingredient("TMTO", "Diced Tomatoes", Type.VEGGIES),
            new Ingredient("LETC", "Lettuce", Type.VEGGIES),
            new Ingredient("CHED", "Cheddar", Type.CHEESE),
            new Ingredient("JACK", "Monterrey Jack", Type.CHEESE),
            new Ingredient("SLSA", "Salsa", Type.SAUCE),
            new Ingredient("SRCR", "Sour Cream", Type.SAUCE)
        );

        Type[] types = Ingredient.Type.values();
        for (Type type : types) {
            model.addAttribute(type.toString().toLowerCase(),
                filterByType(ingredients, type));
        }

        model.addAttribute("design", new Taco());
        return "design";
    }

    // provided by 'aexiaosong'
    private List<Ingredient> filterByType(List<Ingredient> ingredients, Type type) {
        return ingredients.stream().filter(x -> x.getType().equals(type)).collect(Collectors.toList());
    }
}
private static final org.slf4j.Logger log = 
       org.slf4j.LoggerFactory.getLogger(DesignTacoController.class);

稍后您将使用这个 Logger。

下一个应用到 DesignTacoController 的注释是 @Controller。此注释用于将该类标识为控制器并将其标记为组件扫描的候选对象,以便 Spring 将发现该类并在 Spring 应用程序上下文中自动创建 DesignTacoController 实例作为 bean。

DesignTacoController 也用 @RequestMapping 注释。@RequestMapping 注释在类级应用时,指定该控制器处理的请求的类型。在本例中,它指定 DesignTacoController 将处理路径以 /design 开头的请求。

处理 GET 请求

类级别的 @RequestMapping 注释用于 showDesignForm() 方法时,可以用 @GetMapping 注释进行改进。@GetMapping 与类级别的 @RequestMapping 配对使用,指定何时接收 /design 的 HTTP GET 请求,showDesignForm() 将用来处理请求。

@GetMapping 是一个相对较新的注释,是在 Spring 4.3 中引入的。在 Spring 4.3 之前,可能使用了一个方法级别的 @RequestMapping 注释:

表 2.1 Spring MVC 请求映射注释

注释

描述

@RequestMapping

通用请求处理

@GetMapping

处理 HTTP GET 请求

@PostMapping

处理 HTTP POST 请求

@PutMapping

处理 HTTP PUT 请求

@DeleteMapping

处理 HTTP DELETE 请求

@PatchMapping

处理 HTTP PATCH 请求

让正确的事情变得简单

在控制器方法上声明请求映射时,尽可能具体总是一个好主意。至少,这意味着声明一个路径(或者从类级 @RequestMapping 继承一个路径)和它将处理哪个 HTTP 方法。

长度更长的 @RequestMapping(method=RequestMethod.GET) 使我们很容易采取惰性的方式,同时去掉方法属性。由于 Spring 4.3 的新映射注释,正确的做法也很容易做到 —— 只需较少的输入。

新的请求映射注释具有与 @RequestMapping 相同的所有属性,因此可以在使用 @RequestMapping 的任何地方使用它们。

通常,我倾向于只在类级别上使用 @RequestMapping 来指定基本路径。我在每个处理程序方法上使用更具体的 @GetMapping、@PostMapping 等。

现在已经知道 showDesignForm() 方法将处理请求,让我们来看看方法体,看看它是如何工作的。该方法的大部分构造了一个成份对象列表。这个列表现在是硬编码的。当我们讲到第 3 章的时候,你会从数据库中找到玉米饼的原料列表。

一旦准备好了原料列表,接下来的几行 showDesignForm() 将根据原料类型过滤该列表。然后将成分类型列表作为属性添加到传递到 showDesignForm() 的 Model 对象。Model 是一个对象,它在控制器和负责呈现数据的视图之间传输数据。最后,放置在 Model 类属性中的数据被复制到 servlet 响应属性中,视图可以在其中找到它们。showDesignForm() 方法最后返回 “design”,这是将用于向浏览器呈现 Model 的视图的逻辑名称。

DesignTacoController 真的开始成形了。如果您现在运行应用程序并将您的浏览器指向 /design 路径,DesignTacoController 的 showDesignForm() 将被占用,它从存储库中获取数据并将其放在 Model 中,然后将请求传递给视图。但是因为还没有定义视图,所以请求会发生可怕的转变,导致 HTTP 404(Not Found)错误。为了解决这个问题,让我们将注意力转移到视图上,其中的数据将用 HTML 进行修饰,并在用户的 web 浏览器中显示。

上一页2.1.1 建立域下一页2.1.3 设计视图

最后更新于4年前

这有帮助吗?

关于 DesignTacoController,首先要注意的是在类级应用的一组注释。第一个是 @Slf4j,它是 Lombok 提供的注释,在运行时将自动生成类中的 SLF4J(Java 的简单日志门面,)记录器。这个适当的注释具有与显式地在类中添加以下行相同的效果:

https://www.slf4j.org/