Java 向spring数据rest应用程序添加业务逻辑
我一直在试验SpringDataREST(SDR),我对构建RESTAPI的速度印象深刻。我的应用程序基于以下存储库,该存储库提供GET/attachement和POST/attachementJava 向spring数据rest应用程序添加业务逻辑,java,spring,spring-data-rest,Java,Spring,Spring Data Rest,我一直在试验SpringDataREST(SDR),我对构建RESTAPI的速度印象深刻。我的应用程序基于以下存储库,该存储库提供GET/attachement和POST/attachement package com.deepskyblue.attachment.repository; import java.util.List; import org.springframework.data.repository.Repository; import com.deepskyblue.a
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);
}
package com.deepskyblue.attachment.repository;
导入java.util.List;
导入org.springframework.data.repository.repository;
导入com.deepskyblue.attachment.domain.attachment;
公共接口附件存储库扩展{
列出findAll();
附件保存(附件-附件);
}
但有一件事让我感到困惑,那就是如何添加自定义业务逻辑。如果我只想为我的数据使用RESTAPI,SDR看起来很棒,但是传统的Spring应用程序通常会有一个服务层,在那里我可以拥有业务逻辑。有没有一种方法可以将这种业务逻辑添加到SDR中?我想您讨论的是三层体系结构业务层、表示层和持久层 我通常按照这一点将代码分组,表示层将包含所有类[@RestController]Rest注释和方法,这些类直接与前端的post和get调用交互 这些类将依次自动连接业务层和服务层,以便从数据库获取数据或在从数据库获取数据之前添加一些业务逻辑 甚至你也可以使用
RepositoryRestController
。要利用Spring Data REST的设置、消息转换器、异常处理等功能
希望这就是您所看到的。有很多可能性
我最终创建了一个围绕存储库方法的自定义方面。类似这样的内容(groovy):
@方面
@组成部分
@Slf4j
类AccountServiceAspect{
@大约(“执行(*com.test.accounts.account.repository.AccountRepository.save*(..)”)
对象保存帐户(ProceedingJoinPoint jp)抛出可丢弃的{
log.info(“在方面中!”)
对象[]args=jp.getArgs()
如果(args.length要在SpringDataREST中添加自定义逻辑,您必须在请求进入存储库之前注册拦截器以接收请求
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);
}
}
资料来源:
如需了解更多详细信息:以下是一个很好的答案:
如果您未来的服务可能有任何业务逻辑,即使很简单,
您不应该使用Spring数据Rest
SpringDataREST非常适合只需要基本数据的情况
实体控制(想想CRUD)
在这种情况下,可以从SpringWeb、rest控制器和
使用JSON表示作为视图
如果逻辑处理一个实体,则事件
和验证器
会有所帮助
不要误解我的意思,在一个普通的项目中,你可以找到很多没有重逻辑的地方,Spring Data Rest非常适合你,可以节省很多时间。我认为Spring Data Rest缺少一些有用的信息。它应该有一些中间层,你可以用自定义逻辑插入你的服务这将允许在保存它之前修改模型1和2是没有帮助的,因为您无法修改模型。第三种方法使spring data rest的使用变得毫无意义,因为您必须从头开始编写所有内容。例如,如果我需要向补丁请求添加一些业务逻辑,我必须从头开始编写我需要的整个路径控制器方法这是一个相当复杂的选项#4对我来说听起来更好。根本解决不了问题。就像你可以说的那样:不要使用spring数据rest:)
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);
}
}