Как динамически отключить определенный API весной? - PullRequest
1 голос
/ 08 ноября 2019

У меня есть флаг DISABLE_FLAG, и я хочу использовать его для управления несколькими конкретными API-интерфейсами в разных контроллерах.

@RestController
public final class Controller1 {
    @RequestMapping(value = "/foo1", method = RequestMethod.POST)
    public String foo1()
}
@RestController
public final class Controller2 {
    @RequestMapping(value = "/foo2", method = RequestMethod.POST)
    public String foo2()
}

Я могу использовать перехватчик для обработки всех URL-адресов. Есть ли простой способ сделать это, как аннотация?

Ответы [ 3 ]

1 голос
/ 09 ноября 2019

Я не думаю, что есть прямой способ отключить построенное отображение запроса, но мы можем отключить API многими способами с некоторым условием.

Вот 2 способа отключения с помощью профиля Spring или свойств JVM.

public class SampleController {
    @Autowired
    Environment env;

    @RequestMapping(value = "/foo", method = RequestMethod.POST)
    public String foo(HttpServletResponse response) {
        // Using profile
        if (env.acceptsProfiles("staging")) {
            response.setStatus(404);
            return "";
        }

        // Using JVM options
        if("true".equals(System.getProperty("DISABLE_FOO"))) {
            response.setStatus(404);
            return "";
        }

        return "";
    }
}

Если вы думаете, что футуристическое решение с использованием облачной конфигурации является лучшим подходом. https://spring.io/guides/gs/centralized-configuration/

Использование условных компонентов

Это позволяет создать компонент с условиями, если при запуске условие не выполнено, весь компонент никогда не будет построен. Сгруппируйте все дополнительные сопоставления запросов с новым контроллером и добавьте условную аннотацию

@Conditional(ConditionalController.class)
public class SampleController {
    @Autowired
    Environment env;

    @RequestMapping(value = "/foo", method = RequestMethod.POST)
    public String foo(HttpServletResponse response) {
        return "";
    }

    public static class ConditionalController implements Condition {

        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            return context.getEnvironment().acceptsProfiles("staging"); // Or whatever condition
        }

    }
}
0 голосов
/ 09 ноября 2019

Вы можете решить эту проблему с помощью аннотаций, используя пружинные профили. Вы определяете два профиля, один для включенного флага и другой профиль для отключенного флага. Ваш пример будет выглядеть следующим образом:

@Profile("DISABLED_FLAG")
@RestController
public final class Controller1 {
    @RequestMapping(value = "/foo1", method = RequestMethod.POST)
    public String foo1()
}

@Profile("ENABLED_FLAG")
@RestController
public final class Controller2 {
    @RequestMapping(value = "/foo2", method = RequestMethod.POST)
    public String foo2()
}

Вот ссылка на документацию Spring Framework для этой функции: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Profile.html

0 голосов
/ 09 ноября 2019

Вы можете использовать АОП, чтобы сделать что-то подобное.

Создайте собственную аннотацию ...

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Maybe { }

и соответствующий аспект ...

@Aspect
public class MaybeAspect {

  @Pointcut("@annotation(com.example.Maybe)")
  public void callMeMaybe() {}

  @Around("callMeMaybe()")
  public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
    // do your logic here..
    if(DISABLE_FOO) {
      // do nothing ? throw exception?
      // return null;
      throw new IllegalStateException();
    } else {
      // process the request normally
      return joinPoint.proceed();
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...