Spring mvc — Используйте ModelAttribute внутри метода вместо аргумента метода в качестве аннотации

#java #spring-mvc #modelattribute

#java #spring-mvc #modelattribute

Вопрос:

Ниже приведен фрагмент кода, в котором мы можем использовать @ModelAttribute на уровне параметра метода

     @ReqestMapping(value = useruri)
    public void submitInfo(@ModelAttribute User user) {
       // Business logic
    }

    @ReqestMapping(value = personuri)
    public void submitInfo(@ModelAttribute Person person) {
       // Business logic
    }
  

Можем ли мы сделать следующее?

    @RequestMapping(value = genericuri)
    public void submitInfo(HttpServletRequest request, @PathVariable String type) {
           if (type.equals("user")) {
                User user = someSpringMvcMethod(request, User.class)
            } else if (type.equals("person")) {
                Person person = someSpringMvcMethod(request, Person.class)
            }
         //Business logic

    }
  

Причина в том, что я ожидаю другой тип отправляемых данных на основе типа, и я хочу написать универсальный контроллер, поскольку единственным отличием является преобразование данных запроса в определенный класс Java.
Класс User и Person содержит много разных данных, и я не думаю, что смогу использовать наследование / полиморфизм для решения моего варианта использования здесь

Ответ №1:

Я не рекомендую такую вещь.
Посмотрите здесь

 if (type.equals("user")) {
    User user = someSpringMvcMethod(request, User.class)
} else if (type.equals("person")) {
    Person person = someSpringMvcMethod(request, Person.class)
}
  

Это уже неправильно, имхо. Единый метод, управляющий несколькими моделями.
Что, если вам нужен другой тип модели? Другая if ветвь.

Например, это намного лучше

 @ReqestMapping("base-path/user")
public void submitInfo(@ModelAttribute final User user) {
   commonLogic(user.valueOne, user.valueTwo);
}

@ReqestMapping("base-path/person")
public void submitInfo(@ModelAttribute final Person person) {
   commonLogic(person.valueOne, person.valueTwo);
}

private void commonLogic(final String one, final String two) {
   ... // Business logic
}
  

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

Комментарии:

1. хорошо, спасибо. Я понимаю, что подход if-else плох. Другим вариантом было, я мог бы заменить его хэш-картой типа и соответствующего класса. Но в первую очередь я хотел посмотреть, есть ли какая-либо альтернатива для аннотации, доступная внутри метода. Но большое спасибо за ваше предложение. В основном я буду придерживаться описанного выше общего метода.

2. @mihirS При подходе HashMap вам все равно придется поддерживать жестко запрограммированную инициализацию. Я бы сказал, поместите общую бизнес-логику в сервис и автоматически подключите сервис в контроллере. Это самое чистое решение (и то, что я обычно делаю сам).