当前位置: 首页 > 面试题库 >

Spring Data REST:覆盖控制器上的存储库方法

伍成仁
2023-03-14
问题内容

我有以下REST信息库,其实现是在运行时由Spring生成的。

@RepositoryRestResource
public interface FooRepository extends CrudRepository<Foo, Long> {

}

这意味着我将具有save(),find(),exist()和其他可用的方法,并通过REST公开。

现在,我想重写其中一种方法。例如,save()。为此,我将创建一个暴露该方法的控制器,如下所示:

@RepositoryRestController
@RequestMapping("/foo")
public class FooController {

    @Autowired
    FooService fooService;


    @RequestMapping(value = "/{fooId}", method = RequestMethod.PUT)
    public void updateFoo(@PathVariable Long fooId) {
        fooService.updateProperly(fooId);
    }

}

问题: 如果启用此控制器,则不再公开由Spring实现的所有其他方法。因此,例如,我无法再对/ foo / 1进行GET请求

问题: 有没有一种方法可以覆盖REST方法,同时又保留其他自动生成的Spring方法?

额外信息:

  1. 这个问题似乎非常相似: Spring Data Rest:具有相同request-mapping-path的RestController中的Override方法 …但是我不想将路径更改为/ foo / 1 / save之类的东西

  2. 我曾考虑使用@RepositoryEventHandler,但我不太喜欢这个主意,因为我想将其封装在服务下。另外,你似乎失去了对事务上下文的控制。

  3. Spring Data文档的这一部分说明以下内容:

有时你可能想为特定资源编写自定义处理程序。要利用Spring Data REST的设置,消息转换器,异常处理等功能,请使用@RepositoryRestController批注,而不是标准的Spring MVC @Controller或@RestController

因此看来它应该是开箱即用的,但不幸的是不是。


问题答案:

有没有一种方法可以覆盖REST方法,同时又保留其他自动生成的Spring方法?

仔细看一下文档中的示例:虽然没有明确禁止类级请求映射,但它使用了方法级请求映射。我不知道这是否是想要的行为或错误,但据我所知,这是使其工作,如规定的唯一途径这里。

只需将你的控制器更改为:

@RepositoryRestController
public class FooController {

    @Autowired
    FooService fooService;

    @RequestMapping(value = "/foo/{fooId}", method = RequestMethod.PUT)
    public void updateFoo(@PathVariable Long fooId) {
        fooService.updateProperly(fooId);
    }

    // edited after Sergey's comment
    @RequestMapping(value = "/foo/{fooId}", method = RequestMethod.PUT)
    public RequestEntity<Void> updateFoo(@PathVariable Long fooId) {
        fooService.updateProperly(fooId);

        return ResponseEntity.ok().build(); // simplest use of a ResponseEntity
    }
}


 类似资料:
  • > 我有两个控制器(ControllerA和ControllerB) 两个控制器都调用一个服务(MyService)。 MyService调用名为MyRepository的接口,该接口有两个实现(FirstRepository和SecondRepository)。 如何可能在从ControllerA调用服务(MyService)时使用FirstRepository而在调用来自ControllerB

  • 问题内容: 我注意到编译器不会让我用另一个存储的值覆盖存储的属性(这似乎很奇怪): 但是,我可以使用计算属性来执行此操作: 为什么不允许我再给它一个值? 为什么用存储的属性覆盖是可憎的,而要使用计算的一个犹太洁食呢?他们在想什么呢? 问题答案: 为什么不允许我再给它另一个值? 绝对可以为继承的属性赋予不同的值。如果您在采用该初始值的构造函数中初始化属性,然后传递与派生类不同的值,则可以执行此操作:

  • 我有一个4个模型 具有默认字段的用户基本Laravel用户 游览-带有字段['id'、'user\U id'、'name'、'start\U time'、'end\U time'] 总线-带字段['id'、'Tourition\u id'、'staff\u id'、'staff\u qnty'、'staff\u price'] 职员-带字段['id','name'] 这就是关系 我有一个公交员工透

  • 问题内容: 这是一个现实的Angular问题,我无法解决。我喜欢Angular,但是这个问题现在困扰着我很多。 扩展现有控制器功能,并在应用程序的另一页上使用扩展控制器的最佳实践是什么?换句话说: 如何在Angular中继承控制器? 编辑 -2014年9月23日,不要以为我的原始用例的描述会帮助访问者更好地理解我在这里的用意。我认为这使人们偏离了真正的问题。 问题答案: 半年后,我想我完全了解发生

  • 问题内容: 是否有可能覆盖最后的输出,所以我可以例如可视化数组中的更改或创建一个进度栏? 例如,如果我有这个课: 我必须怎么做才能创建一个简单的进度条,而不是显示在10行中? 问题答案: 这可以在我的特定控制台(Windows)上使用,但不是很便携… 还有课程,但据我所知实际上并没有买多少钱……