在将Spring数据中的insert请求添加到MongoDB之前,如何处理它们?

在将Spring数据中的insert请求添加到MongoDB之前,如何处理它们?,spring,mongodb,spring-mvc,spring-boot,spring-data-mongodb,Spring,Mongodb,Spring Mvc,Spring Boot,Spring Data Mongodb,在学习了非常有用的教程之后,我正在尝试创建一个链接缩短器应用程序。我已经编写了一个URL类(使用id、longURL和hash属性)和URLRepository类(目前,只使用演示中所示的findByHash方法)。请注意,我所说的“hash”指的是一个由尚未实现的方法生成的随机短字符串,而不是像MD5这样的实际哈希函数。例如,只需调用独立的generateHash(字符串URL) 我可以使用Spring提供的REST接口将新条目添加到数据库中,并获取它们。但是,我希望应用程序自己生成散列,并在

在学习了非常有用的教程之后,我正在尝试创建一个链接缩短器应用程序。我已经编写了一个URL类(使用
id
longURL
hash
属性)和URLRepository类(目前,只使用演示中所示的
findByHash
方法)。请注意,我所说的“hash”指的是一个由尚未实现的方法生成的随机短字符串,而不是像MD5这样的实际哈希函数。例如,只需调用独立的
generateHash(字符串URL)

我可以使用Spring提供的REST接口将新条目添加到数据库中,并获取它们。但是,我希望应用程序自己生成散列,并在存储它之前进行一些检查和处理——主要检查URL是否已经存储,在这种情况下,它将只返回现有的散列

我想我必须扩展
SimpleMongoRepository
列表保存(Iterable entites)URLRepository
类下的code>方法(由
MongoRepository
扩展),但我不确定如何实现。我还看到了
insert
方法,我不知道应该使用哪种方法

URL.java

public class URL {

    @Id private String id;

    private String longURL;
    private String hash;

    public String getLongURL() {
        return longURL;
    }

    public void setLongURL(String longURL) {
        this.longURL = longURL;
    }

    public String getHash() {
        return hash;
    }

    public void setHash(String Hash) {
        this.hash = Hash;
    }

}
URLRepository.java

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.util.Assert;

@RepositoryRestResource(collectionResourceRel = "urls", path = "urls")
public interface URLRepository extends MongoRepository<URL, String> {

    List<URL> findByHash(@Param("hash") String hash);

}
import org.springframework.data.mongodb.repository.MongoRepository;
导入org.springframework.data.repository.query.Param;
导入org.springframework.data.rest.core.annotation.RepositoryRestResource;
导入org.springframework.util.Assert;
@RepositoryRestResource(collectionResourceRel=“url”,path=“url”)
公共接口URLRepository扩展了MongoRepository{
列出findByHash(@Param(“hash”)字符串哈希);
}

感觉您最好编写一个自定义控制器,而不是在这里使用Spring Data REST,因为您基本上需要两个资源:一个用于添加链接或返回现有的,另一个用于通过散列检索原始URI

在第一种方法中,您只需调用存储库方法
findByLongURL(…)
,如果有结果,则使用获得的
URL
实例,或者采取第二步实际创建哈希并保存
URL
实例存储库。第二个资源基本上只是调用您已经存在的方法

这很直接,也很容易理解

如果需要将前一种方法的实现作为原子操作,则需要手动实现存储库查询方法(有关此方法的一般说明,请参阅中的相关部分):


正如您所看到的,这涉及到处理一些较低级别的细节(尽管通过使用静态导入可以减少详细程度),但基本上为您提供了一个原子操作。

不,扩展
SimpleMongoRepository
通常不是一种方法。您是否介意在您试图实现的目标上添加一些示例(伪)?这篇散文有点难理解。“让应用程序自己生成散列”到底是什么意思?目前它是如何获得散列的?我会马上公布我的代码,对不起!目前,我能够发送一个包含所需长URL及其哈希的POST请求。然而,我想要的是只发送长URL,让应用程序以任何方式生成散列(不必是实际的散列,它可以是随机字符串或其他任何形式,实现还没有完成,将来可能会发生更改)一个很酷的特性是允许两种类型的链接提交:或者(a)一个长URL,让应用程序生成并返回其散列,或者(b)发送长URL和建议的散列,让应用程序返回散列本身,或者如果散列已经存在/无效/发生了其他问题,则发送一条错误消息。但我很高兴至少现在可以选择(a)。为了帮助像我这样的新手,我找到了一些有用的例子来了解我必须编写的控制器的结构。我确实在UrlController类下实现了一个自定义控制器,并将我的控制器映射到处理/api/URL上的请求,这很好。但是,我仍然可以在没有任何验证的情况下将请求发布到/URL。我怎样才能避免这种行为?我无法将一些静态页面映射到/URL,因为我的重定向系统将在那里运行,将/xyzabc转换为正确的URL这是应用程序记录的内容:名为“DispatcherServlet”的DispatcherServlet处理[/URL]的POST请求--查找路径/URL的处理程序方法--找不到[/URL]的处理程序方法--返回给名为“DispatcherServlet”的DispatcherServlet的Null ModelAndView:假设HandlerAdapter已完成请求--请求已成功完成
class UrlRepositoryImpl implements UrlRepositoryCustom {

  private final MongoOperations operations;

  public UrlRepositoryImpl(MongoOperations operations) {
    this.operations = operations;
  }

  @Override
  public URL findOrInsert(String source) {

    // What to find?
    Query query = Query.query(Criteria.where("longURL").is(source);

    // What to write if nothing can be found
    Update update = new Update()
      .setOnInsert("longURL", source)
      .setOnInsert("hash", calculatedHash);

    FindAndModifyOptions options = new FindAndModifyOptions.options()
      .returnNew(true) // returns the document insert (if so)
      .upsert(true); // insert document if it doesn't exist

    return operations.findAndModify(query, update, options, URL.class);
  }
}