在自定义控制器中接受 Spring Data REST URI

2022-09-02 13:54:37

我有一个Spring Data Rest webmvc应用程序,我想为批处理操作添加一些自定义功能。

我已经创建了一个控制器,并将其混合到uri命名空间中,但我希望它能够像自定义查询一样接受URI,而不仅仅是一个ID。/search

我尝试注册自定义转换器(我的实体具有ID类型,但似乎被忽略了。有没有办法配置我的控制器,使其采用自动实现的 SDR 控制器的行为?<String, Long>Long

即使有某种我可以调用的方法可以将URI自动解析为实体,那也可以很好地工作(因为我可以简单地在我的控制器中接受一个)String

这就是我所在的地方。

@Configuration
public class CustomWebConfiguration extends WebMvcConfigurationSupport {

    //irrelevant code omitted

    @Bean
    public DomainClassConverter<?> domainClassConverter() {
        DomainClassConverter<FormattingConversionService> dc = new DomainClassConverter<FormattingConversionService>(mvcConversionService());
        return dc;
    }

    @Override
    public void addFormatters(FormatterRegistry registry) {
          registry.addConverter(String.class, Long.class, testConverter());
    }

    @Bean 
    Converter<String, Long> testConverter() {
        return new Converter<String, Long>() {

            @Override
            public Long convert(String source) {
                //this code does _not_ get run at any point
                if (source.indexOf('/') == -1) { return Long.parseLong(source); }

                source = source.substring(source.lastIndexOf('/') + 1);
                Long id = Long.parseLong(source);

                return id;
            }   
        };
    }
}

SDR 配置

@Configuration
@EnableHypermediaSupport(type = { HypermediaType.HAL })
public class CustomRestConfiguration extends RepositoryRestMvcConfiguration {

    @Override
    public RepositoryRestConfiguration config() {
      RepositoryRestConfiguration config = super.config();
      config.setBasePath("/api");
      config.exposeIdsFor(ApplicationMembership.class);
      return config;
    }


}

还有我的(人为的)控制器:

ApplicationType 是我的实体之一,由 SDR/repository magic 正确管理

@BasePathAwareController
@RepositoryRestController
@RequestMapping("applications/special")
public class ApplicationExtensionController {
    @RequestMapping("a")
    public ResponseEntity<?> reply(@RequestParam("type") ApplicationType type) {
        return new ResponseEntity<String>(type.getIcon(), HttpStatus.OK);
    }
}

我已经环顾四周,但无法完全设法使任何事情发挥作用。当我创建一个利用存储库的转换器时,它也不会被调用,因为 DomainClassConverter 只是调用其底层转换器(这显然会失败,因为它无法正确解析为长转换器。<String, ApplicationType><String, Long>types/1

感谢您的帮助!

忘了提

  • 弹簧数据休息 2.4.0
  • 春季仇恨 0.19.0
  • 弹簧 4.2.1

使用 JPA 存储库


答案 1

事实证明,我在添加转换器方面走在正确的轨道上,不幸的是,我以错误的配置方法进行了操作。

我能够通过将我的bean移动到扩展配置类,然后添加来获得所需的功能testConverter()RepositoryRestMvcConfiguration

@Override
public void configureConversionService(ConfigurableConversionService service) {
    service.addConverter(testConverter());
}

并按预期工作。我现在觉得有点傻,因为首先把它扔在错误的地方,但希望这能帮助别人!


答案 2

我正在根据我最后的评论发布答案。

显然,您需要的逻辑 ( 将 URI 从 自动转换为存储库托管实体 - 是在 一些私有方法中实现的(请参阅和),因此没有简单的方法可以在自定义控制器中获取它。@RequestParamRepositorySearchControllerexecuteQueryMethodprepareUris

您可以尝试使用Spring HATEOAS创建自己的参数解析器。查看解析器是如何实现的。它根据其 解析了一个实体。PersistentEntityResourceHandlerMethodArgumentResolver@BackendId