我一直在尝试使用spring-data-rest(SDR),我对构建rest api的速度感到非常满意。我的应用程序基于以下存储库,它为我提供了GET /附件和POST /附件
package com.deepskyblue.attachment.repository;
import java.util.List;
import org.springframework.data.repository.Repository;
import com.deepskyblue.attachment.domain.Attachment;
public interface AttachmentRepository extends Repository<Attachment, Long> {
List<Attachment> findAll();
Attachment save(Attachment attachment);
}
我感到困惑的一件事是我如何添加自定义业务逻辑。如果我只想在我的数据中使用rest API,SDR似乎很棒,但传统的Spring应用程序通常会有一个服务层,我可以在其中拥有业务逻辑。有没有办法用SDR添加这个业务逻辑?
答案 0 :(得分:3)
有很多种可能性。
验证器(http://docs.spring.io/spring-data/rest/docs/current/reference/html/#validation)用于验证收到的对象。
事件处理程序http://docs.spring.io/spring-data/rest/docs/current/reference/html/#events)。
答案 1 :(得分:2)
我最终创建了一个围绕存储库方法的自定义Aspect。像这样(groovy):
@Aspect
@Component
@Slf4j
class AccountServiceAspect {
@Around("execution(* com.test.accounts.account.repository.AccountRepository.save*(..))")
Object saveAccount(ProceedingJoinPoint jp) throws Throwable {
log.info("in aspect!")
Object[] args = jp.getArgs()
if (args.length <= 0 || !(args[0] instanceof Account))
return jp.proceed()
Account account = args[0] as Account
account.active = true
jp.proceed(account)
}
}
不太理想,但您可以在保存之前修改模型,而无需从头开始编写弹簧数据静止控制器。
答案 2 :(得分:1)
我猜你在谈论3层架构业务层,表示层和持久层。
我通常按照这个将我的代码组合在一起表示层将是包含所有类的那个[@RestController]休息注释和方法直接与帖子交互并获得前端的调用。
这些类将依次自动化业务层和服务层,以便在从数据库获取数据之前从数据库获取数据或添加一些业务逻辑。
即使你可以使用RepositoryRestController
。利用Spring Data REST的设置,消息转换器,异常处理等,
希望这就是你所看到的。
答案 3 :(得分:0)
要在Spring-Data-Rest中添加自定义逻辑,您必须先注册Interceptor才能接收请求,然后再进入存储库。这是您的方法
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import static java.lang.String.format;
public class MyInterceptor extends HandlerInterceptorAdapter {
@Autowired
private MyRepository myRepository;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// Simple check to see if database object exists for requesting urls otherwise
// throw runtime exception to be picked up by handler for error response
Map pathVariables = getUrlPathVariables(request);
String myId = (String) pathVariables.get("myId"); // e.g. /rest/path/${myParam}
if (myId != null && myRepository.findById(myId) == null) {
throw new RuntimeException("My Object not found");
}
return true;
}
private Map getUrlPathVariables(HttpServletRequest request) {
return (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
}
}
来源:https://gist.github.com/m-x-k/03a87252d2458010e1d69f37e35af6f1
有关更多详细信息:https://www.baeldung.com/spring-mvc-handlerinterceptor
答案 4 :(得分:0)
一个很好的答案:https://www.reddit.com/r/java/comments/90wk5y/spring_rest_business_logic/
如果您的未来服务可能具有任何业务逻辑,甚至简单, 您不应该使用Spring Data Rest。
Spring Data Rest非常适合只需要基本知识的情况 控制实体(想想CRUD)。
在这种情况下,可以从spring web,rest控制器和 使用JSON表示作为您的视图。
如果您的逻辑与一个实体打交道,Events
和Validator
会有所帮助。
不要误会我的意思,在一个普通的项目中,您会发现很多地方没有繁琐的逻辑,Spring Data Rest适合退出并可以节省很多时间。