13

Reduce Repetitive Code in Spring MVC Controllers

 3 years ago
source link: https://lorenzo-dee.blogspot.com/2020/09/reduce-repetitive-code-in-spring-mvc.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
Thursday, September 17, 2020

Reduce Repetitive Code in Spring MVC Controllers

After spending some time doing sustained engineering (a.k.a. maintaining legacy code), I ventured to reduce repetitive code in Spring MVC @Controllers. I started with an abstract base controller class. But I soon found out that it was a dead-end because @RequestMapping is not inherited from (or combined with) parent classes and/or interfaces (see Spring MVC @RequestMapping Inheritance).

With some free time to further think about this, I took different approach.

@Controller
public class RepositoryCrudController {
private final Repositories repositories;
private final RepositoryInvokerFactory repositoryInvokerFactory;
// ...
@RequestMapping("/{repository}")
String index(@PathVariable("repository") String repositoryKey,
Pageable pageable, Model model) {
// ... (only if repository has findAll(Pageable) method)
return repositoryKey + "/index";
}
@GetMapping("/{repository}/{id}")
String show(@PathVariable("repository") String repositoryKey,
@PathVariable("id") Object id, Model model) {
// ... (only if repository has findById method)
return repositoryKey + "/show";
}
@GetMapping(path = "/{repository}", param = "create")
String create(...) {
// ... (only if repository has save method)
return repositoryKey + "/create";
}
@PostMapping("/{repository}")
String save(...) {
// ... (only if repository has save method)
return "redirect:/" + repositoryKey + "/{id}";
}
@GetMapping(path = "/{repository}/{id}", param = "edit")
// ... edit (only if repository has findById and save methods)
@PutMapping("/{repository}/{id}")
// ... update (only if repository has save method)
// @DeleteMapping("/{repository}/{id}")
// ... delete (only if repository has deleteById method)
}

This approach is largely inspired by RepositoryEntityController of Spring Data REST.

Instead of defining an abstract base controller class, I created a concrete controller class with the default (or repetitive) behavior. The default behavior relies on invoking methods on Spring Data repositories.

For custom controllers, instead of creating subclasses (of the abstract base class), the controller can simply define handler methods that behave differently. For example:

@Entity
public class Article {...}
// Spring Data JPA
public interface ArticleRepository extends CrudRepository<Article, ...> {...}
@Controller
@RequestMapping("/articles")
public class ArticlesController {
// no need for index() handler method
// just set-up "articles/index" view
// no need for show() handler method
// just set-up "articles/show" view
@GetMapping(param = "create")
String create(Model model) {
// Do something that is _not_ *default* behavior
// e.g. provide options for dropdowns, or use form-backing object/JavaBean
// ...
return "articles/create";
}
// no need for save() handler method
// just set-up "articles/show" view
@GetMapping(path = "/{id}", param = "edit")
String edit(@PathVariable("id") ... id, Model model) {
// Do something that is _not_ *default* behavior
// e.g. provide options for dropdowns, or use form-backing object/JavaBean
// ...
return "articles/edit";
}
// no need for update() handler method
// just set-up "articles/show" view
}

The above will work because Spring MVC chooses the more specific mapping first. When a GET /articles?create request is received, the ArticlesController will be chosen to handle it (and not RepositoryCrudController). But if ArticlesController handler methods were not defined, the GET /articles?create request would have been handled by the RepositoryCrudController.

With this simple fall-back controller that has the default behavior, developers (team mates) can then focus on the domain, creating views, or creating controllers with custom behavior (e.g. Ajax, Server-generated JavaScript Responses).

That's all for now.

No comments:

Post a Comment


Recommend

  • 50
    • 微信 mp.weixin.qq.com 6 years ago
    • Cache

    Spring MVC 温故而知新:从零开始

    Spring MVC 温故而知新:从零开始

  • 40
    • www.tuicool.com 5 years ago
    • Cache

    Spring 源码学习(十) Spring mvc

    经过前面的 AOP (面向切面编程) 和 Transaction (事务管理),这次来到了 MVC (Web 应用,进行请求分发和处理) Spring MVC 定义: 分离了控制器(Controller)、模...

  • 62
    • www.tuicool.com 5 years ago
    • Cache

    Spring MVC Framework Tutorial

    Spring MVC helps in building flexible and loosely coupled web applications. The Model-view-controller design pattern helps in seperating the business logic, presentation logic, and navigation logic. Models

  • 62
    • www.tuicool.com 5 years ago
    • Cache

    Spring MVC 浅谈

    MVC这个词儿,最早的定义应该是作为一种软件架构设计模式出现在软工里面的,即使用model、view、controller 来设计及定义web软件的。 Spring MVC 是指Java 当前阶段最大的开源项目Spring 对于MVC 做出了具体的实现,叫做Spring M...

  • 55
    • www.tuicool.com 5 years ago
    • Cache

    Spring MVC拦截器学习

    1 介绍 Spring Web MVC是基于Servlet API构建的原始Web框架。 2 拦截器 2.1 定义 springmvc框架的一种拦截机制 2.2 使用 2.2.1 两步走 实现HandlerInterc...

  • 34
    • 微信 mp.weixin.qq.com 4 years ago
    • Cache

    深入浅出Spring MVC

    摘要 本文旨在详细分析SpringMVC工作原理以及作为开发者如何基于SpringMVC做扩展。因为SpringMVC分析的文章比较多,所以本文重点讲解如何利用SpringMVC的扩展点实现我们的需求。 什么是Spring MVC SpringM...

  • 10
    • marco.dev 4 years ago
    • Cache

    Spring MVC and MongoDB tutorial

    java-version.com: What's new in Java 16? 15? Keep up to date! Spring MVC and MongoDB tutorial This tutorial (not...

  • 10
    • marco.dev 4 years ago
    • Cache

    Spring MVC 3.0

    I found two interesting presentations of Spring MVC 3 (part of Spring Framework, still in RC phase) Slides and a second presentation in

  • 12

    MVC Controllers are Dinosaurs - Embrace API Endpoints Date Published: 20 January 2021I've been programming web applications using the MVC pattern for a very long time. What's more, I've been helping companies dig t...

  • 5

    Simplifying repetitive administrative tasks by using low-code solutions: An overview March 17, 2022March 17, 2022 by Peter van der Woud...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK