【问题标题】:Spring boot - Adding data read onlySpring boot - 添加数据只读
【发布时间】:2021-12-05 05:51:06
【问题描述】:

我正在考虑以下案例的最佳解决方案。假设我们在启动 CRUD 应用程序时使用了 Spring Boot。我想为这个应用程序添加只读状态——它只允许数据读取和块创建、更新、删除管理员角色的数据操作。我考虑添加检查当前应用程序状态(保存在数据库中)并在调用创建、更新、更新操作时启动的方面(@Aspect)。如果应用处于只读状态 - 将抛出异常(由 @ControllerAdvice 处理)

我想知道添加方面是否是最佳选择 - 我不想修改现有代码。你对此有何看法?此外 - 你将如何为 @aspect 编写集成测试 - 测试方面是否正确启动?如何针对这种情况进行方面测试?测试@aspects(集成测试@springboottest)有哪些好的做法

【问题讨论】:

  • 请解释一下为什么不想修改现有代码?

标签: java spring-boot spring-aop aspect


【解决方案1】:

老实说,这样做似乎很不方便。为什么不添加一个拦截器来检查呢?我之前做过类似的事情

@Component
@RequiredArgsConstructor
public class ReadOnlyModeInterceptor implements HandlerInterceptor {

    private final ServerProperties serverProperties;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (serverProperties.isReadOnlyMode()) {
            String method = request.getMethod();
            boolean isReadOnlyMethod = "GET".equals(method) || "OPTIONS".equals(method);
            String servletPath = request.getServletPath();
            boolean isReadOnlyPath = isReadOnlyPath(servletPath);
            if (!isReadOnlyMethod && isReadOnlyPath) {
                throw new ServiceUnavailableException("Server is in read-only mode.");
            }
        }

        return true;
    }

    private boolean isReadOnlyPath(String servletPath) {
        if (serverProperties.isFullyReadOnly()) {
            return true;    // wildcard option, entire server is read-only
        }
        return serverProperties.getReadOnlyPaths().stream().anyMatch(servletPath::contains);
    }

}

你还需要注册

@RequiredArgsConstructor
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    private final ReadOnlyModeInterceptor readOnlyModeInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(readOnlyModeInterceptor).order(0);
    }
}

【讨论】:

  • 可能还包括HEAD HTTP 方法作为只读的完整性
  • @rkosegi 是的,我们永远不会得到这些,但如果这些是预期的,那是一个很好的添加
  • @SebastiaanvandenBroek 谢谢。对于这种情况 - 拦截器将像普通控制器或服务一样进行测试?你会如何为拦截器编写集成测试?
  • @Sunderi 拦截器总是被触发。您只需将测试编写为正常的集成测试,同时设置只读标志。
  • 是否可以使用拦截器禁用控制器上的创建、更新、删除操作?设置只读模式后,我想为离开读取的这 3 个操作返回某种响应 - 无论读取状态如何,这都应该有效
猜你喜欢
  • 2021-08-01
  • 1970-01-01
  • 2021-03-02
  • 2021-02-09
  • 2018-01-24
  • 2018-09-29
  • 2018-09-17
  • 1970-01-01
  • 2017-04-06
相关资源
最近更新 更多