如何公开Spring Data Rest端点的自定义实现

时间:2017-09-03 07:38:47

标签: java spring rest spring-data spring-data-rest

我有以下问题。我创建了一个使用spring-data的应用程序,并使用spring-data-rest将其公开为REST服务。一切顺利,直到我想要一个自定义实现。我用一个额外的方法创建了一个CustomSomethingRepository和SomethingRepositoryImpl。 Spring数据存储库接口扩展了CustomSomethingRepository,一切都很好,我能够直接从test执行我的方法,也执行了自定义实现。然后我尝试通过REST api获取它,在这里我很惊讶这个方法不能通过/ somethings / search获得。我几乎百分之百地确信它在spring boot 1.3.x和JpaRepositories中运行良好。现在我使用boot 1.5.x和MongoRepository。请看一下我的示例代码:

@RepositoryRestResource
public interface SomethingRepository extends CrudRepository<Something>, CustomSomethingRepository {

    //this one is available in /search 
    @RestResource(exported = true)
    List<Something> findByEmail(String email);
}

和自定义界面

public interface CustomSomethingRepository {
    //this one will not be available in /search which is my problem :(
    List<Something> findBySomethingWhichIsNotAnAttribute();
}

和实施

@RepositoryRestResource
public class SomethingRepositoryImpl implements CustomSomethingRepository {

    @Override
    public List<Something> findBySomethingWhichIsNotAnAttribute() {
        return new ArrayList<>(); //dummy code
    }
}

请您给我一个提示,如何将CustomSomethingImpl作为Rest端点的一部分公开,而不创建另一个常规的spring mvc bean,它只是处理这个请求?

我已经读过这样的问题:Implementing custom methods of Spring Data repository and exposing them through REST说明这是不可能实现的,但不管你信不信,我有一个带有spring-boot 1.3.x的项目,这些实现都暴露了以及:)。

谢谢!

2 个答案:

答案 0 :(得分:0)

由于您的自定义方法返回一个List,您应该将它放在SomethingRepository中,Spring数据将把它放在/ search路径上。添加列表findByNotAttribute()

@RepositoryRestResource public interface SomethingRepository extends CrudRepository<Something> { 
@RestResource(exported = true)
List<Something> findByEmail(String email);

List<Something> findByNotAttribute(@Param String attribute);
}

答案 1 :(得分:0)

所以,我和你有完全相同的问题。我有一个没有经过充分测试的解决方案,因为我仍在努力。我不喜欢它,因为它似乎有点hacky ...而且我还没有完全测试它。这是我走了多远。在CustomSomethingRepository中,将@Query注释添加到要公开的方法中。在注释内添加有效查询。

public interface CustomSomethingRepository {
     @Query("select smt from Something smt")
     List<Something> findBySomethingWhichIsNotAnAttribute();

现在在实现CustomSomethingRepository

的类中
@Repositorypublic
@Transactional(readOnly = true)
class SomethingRepositoryImpl implements CustomSomethingRepository {

     @PersistenceContext
     private EntityManager entityManager;

     @Override
     public List<Something> findBySomethingWhichIsNotAnAttribute() {
          System.out.println("HELLO");
     }
 }

现在,当你转到http://localhost/something/search时,你会看到类似

的内容
{
  "_links" : {
    "findByEmail" : {
      "href" : "http://localhost/something/search/findByEmail{?email}"
    },
    "findBySomethingWhichIsNotAnAttribute" : {
      "href" : "http://localhost/something/search/findBySomethingWhichIsNotAnAttribute"
    },
    "self" : {
      "href" : "http://localhost/something/search/"
    }
  }
}

当您将浏览器指向http://localhost/something/search/findBySomethingWhichIsNotAnAttribute时,您会看到HELLO已打印,@ Query注释中的查询将运行。

我面临另一个问题。在SomethingRepositoryImpl中,我希望能够在SomethingRepository中调用findAll()方法,但如果我将SomethingRepository自动装配到SomethingRepositoryImpl,则应用程序会因为检测到循环而错误。

  

应用程序上下文窗体中某些bean的依赖关系   一个周期: