将spring数据休息与自定义控制器

时间:2018-02-27 11:33:58

标签: java spring spring-data-rest hateoas

我是一个Spring启动应用程序,它使用spring数据rest来操作mongo db和自定义控制器上的集合。我有一个控制器,当我进行其他数据休息调用时,它的状态看起来已经坏了。

这是我的自定义控制器:

@RequestMapping(value = "/listDeployedServers", method = RequestMethod.GET, produces = MediaTypes.HAL_JSON_VALUE)
@ResponseBody
public ResponseEntity<Resources<String>> getDeployedServerList(){

  MongoOperations mongoOps = getMongo();

  //No filter needed, query object is empty
  String collectionName = mongoOps.getCollectionName(DeploymentRecord.class);
  List<String> servers = Utils.castList(String.class, mongoOps.getCollection(collectionName).distinct("vmName",new Query().getQueryObject()));
  servers.removeAll(getNonActiveServerList());
  servers.sort(null);
  Resources<String> serverResources = new Resources<String>(servers);
  return ResponseEntity.ok(serverResources);
}

此控制器在重新启动后最初调用时工作正常。然后我可以调用一些其他自生成的数据休息api,它继续工作正常。但是如果我从MongoRepository调用一些搜索,下一个调用将会出现错误:

  "exception" : "org.springframework.http.converter.HttpMessageNotWritableException",
  "message" : "Could not write JSON: (was java.lang.NullPointerException); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: org.springframework.hateoas.Resources[\"_embedded\"])",
  "path" : "/api/listDeployedServers"

我的存储库类很标准:

@RepositoryRestResource(collectionResourceRel = "deployment", path = "deployment")
public interface DeploymentRepository extends MongoRepository<DeploymentRecord, String> {

    public List<DeploymentRecord> findByVmNameOrderByDeploymentTimeDesc(@Param("vmName") String vmName);

    public List<DeploymentRecord> findByCuramVersion(@Param("curamVersion") String curamVersion);

    public DeploymentRecord findFirstByVmNameOrderByDeploymentTimeDesc(@Param("vmName") String vmName);

}

并且所有这些调用继续正常工作。如果我不打电话给任何搜索,它可以正常工作。如果我重新启动它,它将正常工作。

错误似乎与我尝试返回资源的方式有关。如果我调试自定义控制器,我创建的Resource<String>对象是完全正确的。这是失败的回报。

我是以错误的方式做的吗?我不应该使用Resources<String>但是使用其他东西吗?有什么建议吗?

更新 我找到的解决方法是创建一个虚拟对象来包含列表,然后返回该对象的Resouce而不是之前使用的Resources。这也可以在调用搜索后发挥作用。

@RequestMapping(value = "/listDeployedServers", method = RequestMethod.GET, produces = MediaTypes.HAL_JSON_VALUE)
    @ResponseBody
    public ResponseEntity<Resource<ListResource>> getDeployedServerList(){

        MongoOperations mongoOps = getMongo();

        //No filter needed, query object is empty
        String collectionName = mongoOps.getCollectionName(DeploymentRecord.class);
        List<String> servers = Utils.castList(String.class, mongoOps.getCollection(collectionName).distinct("vmName",new Query().getQueryObject()));
        servers.removeAll(getNonActiveServerList());
        servers.sort(null);
        Resource<ListResource> resource = new Resource<ListResource>(new ListResource(servers));
        return ResponseEntity.ok(resource);
    }

class ListResource {
    private List<String> list;

    public ListResource(List<String> list){
        this.list = list;
    }
    public List<String> getList() {
        return this.list;
    }
}

虽然看起来浪费时间/代码: - /

0 个答案:

没有答案