- Spring Boot進階:原理、實戰與面試題分析
- 鄭天民
- 1170字
- 2022-07-05 09:41:53
4.1.4 Spring WebMVC案例分析
本節將通過一個案例來演示如何通過Spring WebMVC構建RESTful風格的Web API。首先,我們在Maven的pom文件中添加如代碼清單4-36所示的依賴包。
代碼清單4-36 Spring WebMVC依賴包定義代碼
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
在本案例里,我們采用MongoDB來實現數據存儲,所以這里還引入了一個spring-boot-starter-data-mongodb依賴包。
現在,讓我們來定義業務領域對象。在本案例中,我們設計一個User對象,該對象可以包含該用戶的好友信息以及該用戶所閱讀的文章信息。User對象的字段定義如代碼清單4-37所示,這里的@Document、@Id以及@Field注解都來自MongoDB。
代碼清單4-37 User類定義代碼
@Document("users") public class User { @Id private String id; @Field("name") private String name; @Field("age") private Integer age; @Field("createAt") private Date createdAt; @Field("nationality") private String nationality; @Field("friendsIds") private List<String> friendsIds; @Field("articlesIds") private List<String> articlesIds; //省略getter/setter方法 }
注意,在這個User對象中存在兩個數組friendsIds和articlesIds,分別用于保存該用戶的好友和所閱讀文章的編號,其中好友信息實際上就是User對象,而文章信息則涉及另一個領域對象Article。
有了領域對象之后,我們就可以設計并實現數據訪問層組件。這里就需要引入Spring家族中的另一個常用框架Spring Data。Spring Data是Spring家族中專門用于實現數據訪問的開源框架,其核心原理是支持對所有存儲媒介進行資源配置從而實現數據訪問。我們知道,數據訪問需要完成領域對象與存儲數據之間的映射,并對外提供訪問入口。Spring Data基于Repository架構模式抽象出了一套統一的數據訪問方式。Spring Data的基本使用過程非常簡單,我們在本書第9章中還會對Spring Data詳細講解。
基于Spring Data,我們可以定義一個UserRepository,如代碼清單4-38所示。
代碼清單4-38 UserRepository接口定義代碼
public interface UserRepository extends PagingAndSortingRepository<User, String> { User findUserById(String id); }
可以看到UserRepository擴展了PagingAndSortingRepository接口,而后者針對User對象提供了一組CRUD以及分頁和排序方法,開發人員可以直接使用這些方法完成對數據的操作。
注意,這里我們還定義了一個findUserById()方法,該方法實際上使用了Spring Data提供的方法名衍生查詢機制。使用方法名衍生查詢是最方便的一種自定義查詢方式,開發人員唯一要做的就是在Repository接口中定義一個符合查詢語義的方法。例如,如果我們希望通過ID來查詢User對象,那么只需要提供findUserById()這一符合常規語義的方法定義即可。
類似地,ArticleRepository的定義也非常簡單,如代碼清單4-39所示。
代碼清單4-39 ArticleRepository接口定義代碼
public interface ArticleRepository extends PagingAndSortingRepository<Article, String> { Article findArticleById(String id); }
基于數據訪問層組件,Service層組件的實現也并不復雜,基本就是對UserRepository和ArticleRepository中的接口方法的合理利用。UserService和ArticleService的實現過程如代碼清單4-40所示。
代碼清單4-40 UserService和ArticleService類實現代碼
@Service public class UserService { private final UserRepository userRepository; @Autowired public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public User findUserById(String id) { return userRepository.findUserById(id); } public List<User> findByIds(List<String> ids) { List<User> list = new ArrayList<>(); ids.forEach(id -> list.add(userRepository.findUserById(id))); return list; } public List<User> findAllUsers() { return (List<User>) userRepository.findAll(); } } @Service public class ArticleService { private final ArticleRepository articleRepository; @Autowired public ArticleService(ArticleRepository articleRepository) { this.articleRepository = articleRepository; } public List<Article> findAllUserArticles(List<String> articleIds) { List<Article> articles = new ArrayList<>(); articleIds.forEach(id -> articles.add(articleRepository.findArticleById(id))); return articles; } }
最后,我們來根據用戶ID獲取其對應的閱讀文章信息。為此,我們實現如代碼清單4-41所示的ArticleController。
代碼清單4-41 ArticleController類實現代碼
@RestController @RequestMapping("/articles") public class ArticleController { private ArticleService articleService; private UserService userService; @Autowired public ArticleController(ArticleService articleService, UserService userService) { this.articleService = articleService; this.userService = userService; } @GetMapping(value = "/{userId}") public List<Article> getArticlesByUserId(@PathVariable String userId){ List<Article> articles = new ArrayList<Article>(); User user = userService.findUserById(userId); if(user != null) { articles = articleService.findAllUserArticles(user.getArticlesIds()); } return articles; } }
ArticleController的實現過程充分展現了使用Spring Boot開發RESTful風格Web API的簡便性。完整的案例代碼可以參考:https://github.com/tianminzheng/spring-boot-examples/tree/main/SpringWebMvcExample。
在本章4.3節中討論Spring GraphQL框架時,我們還會使用這個案例并對其重構,從而滿足GraphQL的應用場景。
- Java編程指南:基礎知識、類庫應用及案例設計
- Blockly創意趣味編程
- 高級C/C++編譯技術(典藏版)
- VMware虛擬化技術
- 大模型RAG實戰:RAG原理、應用與系統構建
- Jenkins Continuous Integration Cookbook(Second Edition)
- Building Microservices with .NET Core
- Mastering C++ Multithreading
- Python GUI Programming Cookbook(Second Edition)
- Java程序設計
- 網絡綜合布線與組網實戰指南
- HTML5程序開發范例寶典
- Python Natural Language Processing
- JavaScript高級程序設計(第3版)
- Head First Go語言程序設計