具体描述
编辑推荐
Spring MVC是一个面向Web应用的轻量级框架。作为Spring框架的一部分,它天然扩展了Spring并为Web相关问题提供了一致的解决方案。
通过设计Maven模块,你将会实现一个企业级、无状态的REST应用。本书的独特之处在于从Spring生态圈中收集了大量的实用开发技术。你将会通过超媒体与HATEOAS来实现客户与产品之间的无状态会话,并掌握如何配置基于WebSocket的消息服务。最后,你将会学到如何创建并组织不同层次的自动化测试。
■ 使用Maven构建项目,并创建自测试、领域特定、可部署的Web归档。
■ 使用AngularJS与Bootstrap为响应式与强大的前端生成模板。
■ 构建高性能、无状态的RESTful与超媒体应用来支持多客户体验。
■ 使用BASIC认证模式与OAuth2通过REST进行认证。
■ 使用Swagger与Swagger UI来文档化并发布REST API。
■ 实现Spring Web应用的可伸缩。
■ 通过WebSocket与STOMP消息进行通信。
内容简介
《Spring MVC实战》由浅入深地介绍了当今流行的Java Web框架Spring MVC的方方面面,从基础的环境搭建到微服务设计与架构,再到持久化、REST API构建、认证与测试……涵盖了Spring MVC诸多重要且常用的特性。值得一提的是,《Spring MVC实战》针对Spring MVC的每一项特性都提供了完整可运行的示例代码,可以帮助读者更好地掌握这项技术。
无论是Spring MVC的初学者,还是拥有一定经验的开发人员,都能够从《Spring MVC实战》中获得启发,更好地理解Spring MVC这一Web开发“利器”。
作者简介
Alex Bretet,是一位知名的Java 与Spring 集成工程师,目前就职于Thunderhead,这是一家全球知名的SaaS 提供商。他拥有能源、保险、财务与互联网等多个领域的丰富开发经历。受到互联网通信能力与诸多初创公司的感染,他深信开发所能带来的价值(志趣相同的一帮人能在很短的时间内实现令人难以置信的目标)。他还是开源,特别是Spring 的拥护者,其实用主义持续不断地“瓦解”着现有的做法,并提供了颇具价值的替代方法。可以通过alex.bretet@gmail.com 与作者取得联系,或者在Twitter 上关注@abretet。
目录
1 企业级Spring应用的搭建.1
引言 1
安装Eclipse JEE开发者版本与Java SE 82
为Eclipse配置Java 8、Maven 3和Tomcat 8 5
定义Maven的项目结构 12
安装Spring、Spring MVC和Web结构24
2 使用Spring MVC设计微服务架构35
引言35
使用简单URL映射配置控制器 36
使用ViewResolver配置回退控制器 49
使用Bootstrap创建并自定义响应式单页面Web设计.53
使用JSTL在视图中显示模型 72
定义通用WebContentInterceptor82
使用AngularJS设计客户端MVC模式88
3 Java持久化与实体100
引言 100
在Spring中配置Java持久化API 101
定义有用的EJB3实体和关系105
使用JPA与Spring Data JPA 115
4 为无状态架构构建REST API122
引言 122
绑定请求与编排响应123
配置内容协商(JSON与XML等) 133
添加分页、过滤器与排序功能 138
全局处理异常149
使用Swagger生成文档与公开API 156
5 使用Spring MVC进行认证.163
引言 163
配置Apache HTTP服务器来代理Tomcat服务器 163
修改用户和角色以适应Spring Security 172
基于BASIC的认证方式.183
第三方OAuth2认证193
在REST环境中保存认证信息 211
服务与控制器授权 220
6 实现HATEOAS.235
引言 235
将DTO改造成Spring HATEOAS资源 236
为超媒体驱动的API创建链接 244
JPA实体的暴露策略 252
通过OAuth从第三方API获取数据259
7 开发CRUD操作与校验266
引言 266
为所有HTTP方法扩展REST处理程序.267
使用Bean Validation校验资源 278
REST消息与内容的国际化.292
使用HTML5和AngularJS校验客户端表单 302
8 通过WebSocket与STOMP进行通信.308
引言 308
通过基于SockJS的STOMP使社交事件流媒体化309
使用RabbitMQ作为多协议消息代理 322
将任务放入RabbitMQ并通过AMQP消费任务 328
通过Spring Session和Redis保证消息安全334
9 测试与故障排除351
引言 351
通过Flyway实现数据库迁移自动化352
使用Mockito和Maven Surefire进行单元测试 357
使用Cargo、Rest-assured和Maven Failsafe进行集成测试 364
在集成测试中注入Spring Bean 373
使用Log4j2记录日志的现代应用 377
前言/序言
欢迎阅读这本独一无二的《Spring MVC实战》,希望你已经为本书的探索之旅做好了准备,本书会带你畅游现代 Spring Web开发实践。本书作者已经创建了 cloudstreetmarket.com网站,这是一个带有社交功能的股票交易平台,本书将会带领你探索网站开发过程的每一步。
1 企业级 Spring应用的搭建
本章介绍了业界的一套标准实践,从配置 Eclipse IDE以对 Java 8、Tomcat 8、GIT与 Maven提供更优化的支持,到理解 Maven作为一个构建自动化工具以及作为一个依赖管理工具的认识,阅读本章后你将会了解如何在一个坚实的基础上部署 Spring框架。
无论一个项目旨在成为一个能够获得丰厚利润的产品,抑或仅仅是一个练习,都是从相同的企业级模式开始的。
本章并不仅仅是开发 Cloud Street Market应用的第一个阶段,还为面向企业级 Spring应用的开发者提供了大量的标准化实践。
2 使用 Spring MVC设计微服务架构
本章内容有些多,介绍了 Spring MVC的核心原则,比如请求流与 DispatcherServlet的中心角色,还介绍了如何通过与控制器相关的注解来配置 Spring MVC控制器与控制器方法处理器。
在微服务架构的搭建过程中,我们在各个模块与 Web项目中安装了 Spring与 Spring MVC,用于构建易于部署且可伸缩的功能性单元。从这个视角来看,我们通过一个 Web模块来构建应用,该模块负责提供一个 Twitter Bootstrap模板,同时与另一个专门用作 REST Web Services的 Web模块搭配使用。
本章将介绍如何通过 JSTL将模型从控制器传递给 JSP视图,以及如何通过 AngularJS来设计 JavaScript MVC模式。
3 Java持久化与实体
本章介绍了持久化相关的内容。在这个阶段,了解如何在 Spring生态圈以及 Spring MVC应用中处理持久化数据很有必要。该章将介绍如何在 Spring中通过 dataSource与 entityManagerFactory来配置 JPA持久化提供者( Hibernate)。你将学习如何从 EJB3实体来构建好处极多的 JPA对象关系映射,接下来会学习如何通过 Spring Data JPA来查询仓库。
4 为无状态架构构建 REST API
本章揭示了如何将 Spring MVC作为 REST Web Services引擎。我们将会看到框架对此所提供的令人惊叹的支持,只需为抽象的与 Web相关的逻辑的方法处理器提供几个注解即可,这样我们就可以将主要精力放在业务上了。这个原则也用在了请求绑定(参数、 URL路径与头信息绑定等)与响应编排注解方面,同时在 Spring Data的集成支持上也用到了。
本章还介绍了如何创建作为 Spring MVC一部分的异常处理器来将预定义的异常类型转换为通用的错误响应。你将学到如何配置内容协商(这是 REST APIs的重要内容),最后还将学习如何通过 Swagger与 Swagger UI来公开并文档化 REST端点信息。
5 使用 Spring MVC进行认证
本章介绍了如何在控制器与服务层对 HTTP BASIC与 OAuth2等标准协议配置认证。你将学习与 Spring Security相关的几个概念与实践,例如过滤器链、 命名空间、认证管理器,以及角色与用户的管理等。我们的 OAuth2流是个客户端实现。我们在用户首次使用第三方提供者 Yahoo! 时在应用中对其进行认证。这些 Yahoo! 的认证与连接信息稍后会被用于从 Yahoo! Finance中拉取最新的财经数据。借助于 Spring Social库,我们可以在后台对 OAuth2实现完全的抽象化。
6 实现 HATEOAS
本章介绍了如何将 RESTful Spring MVC API更进一步。超媒体驱动的应用为每个单独的请求资源都提供了链接,这些链接反映了相关资源的 URL。它们向客户端(无论是何种类型的客户端)提供了实时的导航选择—精确的文档,同时也是实际的实现。该章将会介绍如何通过 JPA实体关联或控制器层来构建这种链接。
7 开发 CRUD操作与校验
本章介绍更加高级的 Spring MVC概念,通过认识支持交互式 HTTP方法( PUT、POST 与 DELETE)的工具与技术,我们将学习如何使用 HTTP1/1规范( RFC 7231语义与内容)来返回恰当的响应状态码与头信息。
本章通过 Spring Validator与 ValidationUtils辅助类的搭配使用来提供与验证相关的 JSR-303和 JSR-349规范的兼容实现。该章的最后一节将会介绍消息与内容的国际化( I18N)。我们还通过 AngularJS提供了一个客户端实现,使用了已发布的国际化 Web Services。
8 通过 WebSocket与 STOMP进行通信
本章将会聚焦于“冉冉升起”的 WebSocket技术,并为我们的应用构建面向消息的中间件。该章提供了一个大家很少会见到的示例,通过 Spring实现了关于 WebSockets的大部分内容,从默认的嵌入式 WebSocket消息代理的使用,到特性完备的外部代理(借助于 STOMP与 AMQP协议)。我们将会了解如何向多个客户端广播消息,以及如何通过优秀的可伸缩特性推迟耗时任务的执行。
通过本章你还将学到如何动态创建私有队列,以及如何获取认证客户端并通过这些私有队列与其收发消息。
为了实现 WebSocket认证与消息认证,我们将 API置为有状态的。对于有状态来说,我们要知道的是 API将会使用 HTTP会话在多个请求间保持用户的认证状态。借助于 Spring Session与高度集群化的 Redis服务器的支持,会话将可以在多个 Web应用间共享。
9 测试与故障排除
本章介绍了一套用于维护、调试与改进应用状态的工具与一般做法。作为本书的最后一部分内容,我们将会学习如何通过 Flyway Maven Plugin将数据库模式从一个应用版本升级为另一个,并将其作为 Maven构建的一部分。我们还会学习如何编写自动化单元测试(借助于 Maven Sure.re与 Mockito)与集成测试(使用一套库,例如 Cargo、Rest-assured与 Maven Failsafe)。
该章的最后一节介绍了将 Log4j2作为全局日志框架的做法,无论什么环境,我们都可以通过这一日志解决方案来高效排错。
书中多个章节都列出了系统需要具备的硬件与软件条件。而且,学习本书经常需要访问互联网资源,有不少扩展内容都给出了链接,或者需要下载必备软件。此外更加重要的是,本书使用 Git版本系统来管理每章的代码基,本地的 Git仓库需要对应于项目的远程仓库(位于 GitHub上),要能够访问这个远程仓库。
本书的示例支持三种操作系统: MS Windows、Linux与 Mac OS X。对于硬件平台,推荐使用主流、高性能的工作站,最低 2 GB内存, 500 MB以上空闲硬盘空间。
在编写本书时,作者的一个目标就是一方面尽量保持内容的可读性,另一方面则尽量多地向读者介绍现代 Web开发的实践。
我们相信,对 Spring MVC感兴趣的大多数读者的主要目的在于寻求一个入门套件和工具箱,来开发现代、基于 Spring的 Web应用。我们还相信,大多数读者都倾向于通过实践而非理论来强化对概念的理解。当下,我们都知道人们具有不同的学习习惯与方式。
鉴于此,本书的各个章节都是逐步推进的,从直观的第 1章到更具挑战性的第 8章。相比后面的章节来说,前几章更适合大多数 Java开发者。
话虽如此,本书却几乎包含了你所要的一切!本书配套的示例应用已经处于运行状态,等待着你的探索,理解其工作方式。
一般来说,我们假定你是一名具有 Web开发经验的 Java开发者。此外,我们期望你对学习 Spring Web技术拥有浓厚的兴趣。
《 Java Web 开发精髓:从零构建高性能应用 》 前言 在信息爆炸的时代,互联网已成为人们获取信息、进行交流、享受娱乐的核心平台。而支撑这一切的,正是那些稳定、高效、用户体验卓越的 Web 应用。Java,作为一门久经考验、生态成熟的编程语言,在 Web 开发领域扮演着举足轻重的角色。本书旨在带领读者深入探索 Java Web 开发的方方面面,从基础概念到高级技巧,从框架选型到性能优化,从安全防护到部署运维,构建一套完整的知识体系,帮助开发者们掌握构建高性能、可扩展、易维护的 Java Web 应用的核心能力。 我们都知道,Web 应用的开发并非一蹴而就,它涉及多个层面:前端的用户交互、后端的业务逻辑处理、数据的持久化存储、服务器的部署与管理等等。其中,后端开发是 Web 应用的灵魂所在,它负责处理海量请求,执行复杂业务,确保数据的安全与一致。Java 凭借其跨平台性、强大的库支持、活跃的社区以及成熟的框架生态,成为了后端开发的首选语言之一。 本书的核心目标是帮助读者理解 Java Web 开发的内在逻辑,而非仅仅停留在 API 的调用层面。我们将从最底层的 Servlet API 入手,逐步深入到各种主流框架的设计思想和实现机制。通过大量的案例分析和代码示例,读者将能够亲身体验如何将抽象的概念转化为实际可用的功能,如何解决开发过程中遇到的各种挑战。 我们深知,对于很多开发者而言,Web 开发的道路充满了迷茫与困惑。尤其是在面对众多的框架和技术选项时,选择哪一条路径才能事半功倍,常常令人头疼。本书正是为了解决这一痛点而生。我们将以一种循序渐进、由浅入深的方式,引导读者逐步建立起对 Java Web 开发的全局观,理解不同技术之间的联系与区别,从而能够根据实际项目需求,做出最明智的技术选型。 本书并非一本枯燥的技术手册,而是一次深入的实践探索之旅。我们将结合真实世界的开发场景,讨论在性能瓶颈、并发处理、数据一致性、安全性等方面可能遇到的问题,并提供切实可行的解决方案。无论是初学者希望系统学习 Java Web 开发,还是有一定经验的开发者希望深化理解、提升技能,本书都将是您不可或缺的良伴。 第一部分:Java Web 开发基石 在深入探讨高级框架和技术之前,理解 Java Web 开发的最底层原理至关重要。本部分将带领读者回顾并深入理解 Java Web 开发的核心基石——Servlet API。 第一章:HTTP 协议与 Web 工作原理 HTTP 协议详解: 深入剖析 HTTP 的请求与响应模型,理解请求方法(GET, POST, PUT, DELETE等)的含义及其应用场景,探讨状态码的意义(2xx, 3xx, 4xx, 5xx)以及它们在 Web 应用中的作用。我们将详细分析 HTTP 请求头(Headers)与响应头(Headers)中常见字段的含义,例如 `Content-Type`, `Cookie`, `Cache-Control`, `User-Agent` 等,理解它们如何影响浏览器与服务器之间的通信。 Web 服务器的工作流程: 了解 Web 服务器(如 Tomcat, Jetty)如何接收客户端请求,如何解析请求,如何将请求分发给后端的 Java 应用,以及如何将响应返回给客户端。我们将探讨 Web 服务器与 Servlet 容器之间的关系,以及它们在整个 Web 请求处理流程中的角色。 URL 与 URI 的区别与联系: 清晰界定 URL(统一资源定位符)和 URI(统一资源标识符)的概念,理解它们在 Web 应用中的应用。 第二章:Servlet API 核心精髓 Servlet 接口与生命周期: 深入理解 `Servlet` 接口,分析 `init()`, `service()`, `destroy()` 方法的调用时机与作用。我们将通过示例代码演示如何编写一个简单的 Servlet,并理解其在 Web 应用中的实例化和管理过程。 HttpServletRequest 与 HttpServletResponse: 详细讲解 `HttpServletRequest` 接口,学习如何获取请求参数(包括表单提交、URL参数)、请求头信息、客户端 IP 地址等。同时,深入掌握 `HttpServletResponse` 接口,学习如何设置响应状态码、响应头信息、向客户端输出内容(文本、HTML、JSON等)。 Servlet 容器(ServletContext): 理解 `ServletContext` 的作用,它代表着整个 Web 应用的上下文环境。学习如何通过 `ServletContext` 获取 Web 应用的配置信息、初始化参数,以及在不同 Servlet 之间共享数据。 Filter 与 Listener: 探索 `Filter` 接口,学习如何拦截和处理 Web 请求与响应,例如实现请求日志记录、权限校验、字符编码转换等功能。理解 `Listener` 接口,掌握事件监听机制,例如 `ServletContextListener` 用于 Web 应用的启动与关闭,`HttpSessionListener` 用于会话的管理等。 RequestDispatcher 与重定向/请求转发: 区分 `RequestDispatcher` 提供的请求转发(forward)与客户端重定向(redirect)机制,理解它们在页面跳转、资源共享等场景下的应用和区别。 第三章:JSP 技术与 EL/JSTL JSP 页面生命周期: 理解 JSP 页面如何被翻译成 Servlet,以及其从源代码到可执行代码的整个过程。 JSP 标签与指令: 掌握 JSP 中的常用指令(`page`, `include`, `taglib`)和动作标签(`forward`, `include`, `useBean`, `setProperty`, `getProperty`),理解它们如何简化页面开发。 EL (Expression Language): 学习 EL 表达式,如何简洁地访问 Java Bean 的属性、获取请求域、会话域、应用域中的数据。 JSTL (JSP Standard Tag Library): 深入使用 JSTL 标签库,包括核心标签(`c:if`, `c:forEach`, `c:out`)、格式化标签、XML 标签等,实现更复杂的页面逻辑控制和数据展示,摆脱脚本的束缚。 第二部分:构建现代化 Java Web 应用 在掌握了 Java Web 开发的基础知识后,我们将进入更加广阔和实用的领域:现代化的 Java Web 应用构建。本部分将重点介绍当前主流的开发模式和技术栈,帮助读者构建出更具可维护性、可扩展性和高性能的 Web 应用。 第四章:MVC 设计模式解析 MVC 模式的演进与优势: 深入理解 Model-View-Controller (MVC) 设计模式的核心思想,分析其在 Web 开发中的重要性,包括关注点分离、代码重用、可维护性等优势。 Spring MVC 框架深入解析(非本书核心内容,仅为对比提及): (此处为避免重复,我们仅提及 Spring MVC 的存在,但详细内容将围绕本书主题展开)… 设计模式在 Web 应用中的实践: 探讨其他与 Web 开发紧密相关的设计模式,如工厂模式、单例模式、适配器模式、观察者模式等,以及它们如何在实际项目中应用。 第五章:RESTful API 设计与实践 REST 架构风格: 理解 REST(Representational State Transfer)架构风格的核心原则,包括无状态性、客户端-服务器、统一接口、可缓存性、分层系统、按需代码(可选)。 HTTP 方法与资源映射: 如何利用 HTTP 方法(GET, POST, PUT, DELETE)来操作资源,以及如何设计清晰、一致的资源 URI。 JSON 与 XML 数据格式: 掌握 JSON 和 XML 作为数据交换格式的应用,以及如何在 Java 中进行 JSON/XML 的序列化与反序列化。 API 版本控制与文档: 讨论 API 版本控制的策略,以及使用 Swagger/OpenAPI 等工具生成 API 文档的重要性。 安全性考量: 在设计 RESTful API 时,需要考虑的身份验证、授权、输入验证等安全问题。 第六章:数据持久化与数据库交互 关系型数据库基础: 简要回顾关系型数据库的基本概念,包括表、字段、主键、外键、索引等。 JDBC (Java Database Connectivity): 学习使用 JDBC API 直接与数据库进行交互,理解连接管理、SQL 执行、结果集处理等。 ORM (Object-Relational Mapping) 框架: MyBatis 框架实战: 深入学习 MyBatis 的核心概念,包括 SQL Mapper, 动态 SQL, 缓存机制, 插件等。通过大量实例演示如何配置 MyBatis,如何编写 SQL 映射文件,以及如何实现高效的数据库操作。我们将着重讲解 MyBatis 的映射配置,注解开发,以及如何利用其强大的动态 SQL 功能应对复杂查询。 JPA (Java Persistence API) 概念介绍: (此处仅为介绍,不深入讲解) 数据库连接池: 理解数据库连接池(如 C3P0, HikariCP)的重要性,以及如何配置和使用连接池来提高数据库访问性能。 事务管理: 讲解数据库事务的 ACID 特性,以及如何在 Java 应用中进行有效的事务控制,确保数据的一致性。 第七章:构建高性能 Web 应用 性能优化基础: 识别 Web 应用的性能瓶颈,包括 CPU、内存、I/O、网络等。 缓存策略: 内存缓存: 介绍 Guava Cache, Caffeine 等内存缓存库的应用,以及如何在应用层实现缓存。 分布式缓存: 深入学习 Redis 的基本用法,包括数据结构(String, List, Set, Hash, Sorted Set)、持久化机制、集群部署等。通过实际案例演示如何利用 Redis 实现页面缓存、数据缓存、Session 共享等,显著提升应用响应速度。 异步处理与并发: Java 多线程与并发包: 回顾 Java 并发编程的基础,包括线程创建、同步机制、线程池等。 CompletableFuture 异步编程: 学习使用 `CompletableFuture` 实现异步非阻塞的 I/O 操作,以及如何构建复杂的异步任务流程。 消息队列(如 RabbitMQ, Kafka 概念): (此处仅为介绍) 代码优化技巧: 内存泄漏的排查与避免,减少不必要的对象创建,优化算法复杂度等。 HTTP/2 协议特性: (概念介绍) 第八章:安全防护与身份验证 Web 安全威胁: 识别常见的 Web 安全威胁,如 SQL 注入、XSS(跨站脚本攻击)、CSRF(跨站请求伪造)、DDoS 攻击等。 输入验证与过滤: 讲解如何对用户输入进行严格的验证和过滤,防止恶意数据的注入。 身份验证(Authentication): Session 与 Cookie: 理解 Session 和 Cookie 在用户身份维持中的作用。 JWT (JSON Web Token): 学习 JWT 的工作原理,如何生成、验证 Token,以及如何在无状态的 RESTful API 中实现身份验证。 授权(Authorization): 讲解基于角色的访问控制(RBAC)等授权策略,确保用户只能访问其被授权的资源。 HTTPS: (概念介绍) 第三部分:部署、运维与进阶 成功构建应用只是第一步,如何将其稳定地部署到生产环境,并进行有效的运维管理,是整个 Web 开发生命周期中不可或缺的环节。本部分将涵盖这些重要内容。 第九章:项目构建与部署 Maven 和 Gradle: 深入学习 Maven 或 Gradle 等构建工具的使用,掌握项目依赖管理、构建生命周期、打包部署等。 Web 服务器配置: 学习如何配置和优化常用的 Web 服务器(如 Tomcat, Jetty),包括连接数、线程池、日志等参数。 Docker 容器化部署: 介绍 Docker 的基本概念,如何构建 Docker 镜像,以及如何将 Java Web 应用部署到 Docker 容器中。 CI/CD 基础: 简要介绍持续集成 (CI) 和持续部署 (CD) 的概念,以及如何自动化构建、测试和部署流程。 第十章:日志管理与监控 日志框架: 学习使用 SLF4J + Logback/Log4j2 等日志框架,理解日志级别、配置、输出方式等。 日志分析: 探讨如何收集、分析日志,用于排查问题、监控应用状态。 应用性能监控 (APM): 介绍 APM 工具(如 SkyWalking, Pinpoint)的作用,如何集成 APM 工具来实时监控应用的性能指标、追踪分布式链路。 第十一章:分布式系统初探 微服务架构概念: (概念介绍) 服务发现与注册: (概念介绍) 分布式事务: (概念介绍) 附录: 常见问题解答 (FAQ) 推荐资源 结语 Java Web 开发是一个广阔且不断发展的领域。本书通过系统性的讲解和大量的实践案例,力求为读者构建一个扎实的知识体系,并培养解决实际问题的能力。我们鼓励读者在学习过程中,不断实践,勇于探索,将所学知识融会贯通,最终成为一名优秀的 Java Web 开发者。愿本书成为您在 Java Web 开发道路上的一盏明灯,助您披荆斩棘,成就卓越。