【问题标题】:springboot override controller methodsspring boot 覆盖控制器方法
【发布时间】:2021-07-13 11:41:03
【问题描述】:

我不得不问,因为我找到的答案都无法帮助我解决问题。

我有控制器

@RestController
@RequestMapping("/path")
DefaultController

我想重写它的方法,因为一个特定的客户有特定的逻辑,带有控制器

@RestController
@RequestMapping("/path")
CustomController

可以具有完全相同的方法签名或重写方法,RequestBody 扩展原始请求。

  1. 我尝试为放置注释的控制器定义一个接口
  2. 我在 CustomController 上使用了 @Primary 和 @Profile 来强制 Spring 加载它而不是默认版本

解决方案不起作用,因为 Spring 检测到方法的双重映射,即著名的“模糊映射”。

有人知道我该如何解决这个问题吗?

我想只在我需要的地方插入控制器的自定义实现,只覆盖我需要的方法,而不改变请求路径。 自定义服务是不够的,因为有时我必须传递带有附加字段的 RequestBody

我们使用的是springboot 2.4.7,spring 5.3.8

提前致谢

【问题讨论】:

  • 如果您能够通过使用每个客户的配置文件来启动应用程序,您就可以做到。但是您是否同时需要这两个客户,您管理这种行为的唯一方法是实施不同的服务。而且我认为以这种方式解决它没有任何问题。

标签: java spring-boot controller customization


【解决方案1】:

不要为此使用@Profile,@Profile 适用于自定义测试或构建之类的事情。您只需要创建一个单独的控制器并相应地命名路径,实际上没有充分的理由尝试覆盖控制器方法。由于路径重复,Spring 甚至不允许您这样做。即使它以某种方式可行,想象一下它会造成的故障排除噩梦,除了你之外的任何人都怎么知道生产系统中实际部署了“哪个”控制器。

【讨论】:

  • 感谢您的建议。当您编写“创建一个单独的控制器并相应地命名路径”时,您的意思是 CustomController 应该映射到 @Path("/path/custom") 或类似的下面?但是这样一来,前端就应该意识到不同路径的存在。我错了吗?
  • 是的,完全正确。关键是端点应该始终是唯一的。即使他们在幕后做类似的事情,您也可以在后端层重用代码。控制器应该是应用程序中最笨、最简单的层。
  • 问题不在于将逻辑放在哪里,而在于如何允许使用扩展 bean 或相同签名覆盖方法
  • 您不应该尝试覆盖控制器方法。使用服务层重用任何重复的业务逻辑
【解决方案2】:

我终于能够解决我的问题。 我做了这个,如果有人感兴趣的话

  1. 通过@Profile("what you want") 将特定配置文件分配给覆盖控制器
  2. 通过@RequestMapping 属性“headers”向控制器请求映射添加了自定义标头
  3. 仅适用于 post 和 put 方法,我必须在原始控制器和自定义控制器上再次为属性“headers”设置一个值

【讨论】:

    【解决方案3】:

    如果你不关心内容类型,你可以尝试改变消费者/生产者

    @RestController
    @RequestMapping("/path", consumes = MediaType.TEXT_PLAIN_VALUE)
    CustomController
    

    【讨论】:

    • 感谢您的建议,但我更愿意利用本机对象反序列化
    猜你喜欢
    • 2020-06-21
    • 2020-04-09
    • 2020-05-15
    • 1970-01-01
    • 2016-08-14
    • 1970-01-01
    • 2020-11-06
    • 2011-07-16
    • 2011-12-05
    相关资源
    最近更新 更多