Как уменьшить повторяющийся код в контроллерах весенней загрузки

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

if (request == null){
    throw new InvalidRequestException("the request object is null");
}

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

Можете ли вы предоставить образец контроллера, особенно относительно того, откуда берется этот объект запроса?

Andreas 02.11.2018 09:49

Обычно вы используете метод, содержащий общий код. Но как в этом конкретном примере запрос может быть нулевым?

Henry 02.11.2018 09:50

В этом конкретном случае используйте Bean Validation и @RequestBody @Valid MyObject request.

chrylis -cautiouslyoptimistic- 02.11.2018 10:06
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
3
732
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Просто оберните этот код в метод:

protected void checkRequest(Object request){
    if (request == null){
        throw new InvalidRequestException("the request object is null");
    }
}

и объявите его в классе AbstractController. Позвольте вашим контроллерам расширить этот класс.

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

Один из подходов - создать абстрактный класс, который будет содержать метод упаковки, который будет вызываться расширяющим контроллером.

public abstract class CoreController {
  protected void validateRequest(MyRequest request) {
    if (request == null) throw new InvalidRequestException("the request object is null");
  }
}

Расширьте свои контроллеры с помощью этого класса и вызовите метод validateRequest

public class MyController extends CoreController {
  @PostMapping("/some_endpoint")
  public MyResponse endpointMethod (@RequestBody MyRequest request) {
    validateRequest(request);
    ...
    return new MyResponse();
  }
}

В основном то, что вы делаете, - это проверка параметров. Это своего рода сквозные проблемы и идеальный вариант использования подхода АОП.

Spring предоставляет очень хороший способ сделать это

вы можете просто использовать @validate вот так

@PostMapping
    public ResponseEntity<Void> someMEthod(@Validated(CustomChecks.class) @RequestBody request yourRequest)

Затем вы можете поместить всю свою логику проверки в класс CustomChecks. (Вы можете найти несколько примеров)

если у вас очень маленькие и универсальные проверки, вы также можете использовать аннотации.

в вашем случае просто поместите аннотацию @Ненулевой в свой класс запроса. Отметьте это пример

надеюсь это поможет

Ответ принят как подходящий

Вы используете SpringBoot, поэтому в своем приложении, где вы определяете аннотацию @SpringBootApplication, вы можете указать следующий @Bean:

@Bean
public HttpRequestHandler httpRequestHandler () {
    return new MyHttpRequestHandler();
}

Также создайте класс MyHttpRequestHandler, где вы можете сделать любую свою логику с этим:

public class MyHttpRequestHandler implements HttpRequestHandler {

@Override
public void handleRequest (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        if (request == null) {
            throw new InvalidRequestException("the request object is null");
        }
   }
}

Spring АОП?

создайте класс Aspect следующим образом:

@Aspect
class AopDemo{

    @Around("execution(* com.demo.controller.*(..))")
    public Object release(JoinPoint jp){
        try{
            Object[] args = jp.getArgs();
            for(Object arg: args){
                if (arg == null){
                    throw new InvalidRequestException("the request object is null"); 
                }
            }
            return jp.proceed(args);
        }catch(InvalidRequestException ire){
            // handle InvalidRequestException
        }catch(Exception ex){
            // handle Exception
        }
    }

}

Я согласен с @Niraj Sonawane на использование аннотации @Validated для решения конкретного случая, указанного в сообщении.

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

Лучше использовать @Действительный для проверки полезной нагрузки, не проверяя ее вручную. Пожалуйста, следуйте приведенному ниже объяснению.

Вы можете использовать «import org.springframework.validation.Errors;» и @Действительный, как показано ниже.

@PostMapping("/test")
public ResponseEntity<String> editStatus(@Valid @RequestBody Person person, Errors errors) {
    String responseMessage;
    if (errors.hasErrors()) {
        responseMessage = "'" + errors.getFieldError().getField() + "' " + errors.getFieldError().getDefaultMessage();
    } else {
        // You can do ur logic here
        responseMessage = "result";
    }
    return ResponseEntity.accepted().body(responseMessage);
}

Полезную нагрузку человека вы можете проверить, как показано ниже.

public class Person {
    @NotNull
    private String firstName;
    @NotNull
    private String lastName;
    private String city;

    //Getter
    //Setter
}

В этом объяснении я использовал полезную нагрузку Человек. @Действительный проверяет содержимое полезной нагрузки. Как только вы получите полезную нагрузку без обязательных полей, вы можете справиться с ситуацией, используя ошибки.

Другие вопросы по теме