В контроллере Spring можно ли вызвать метод на основе количества параметров запроса?

Я обновил существующий webapp с помощью Spring. Понятно, что проще начинать с Spring, чем добавлять его позже.

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

/doSomething?prod=15

отображает информацию для продукта 15 и

/doSomething?prod=15&owner=99

устанавливает владельца продукта с 15 по 99 и

/doSomething?prod=15&delete=y

удаляет продукт 15.

У меня работает контроллер, но я не знаю, как вызывать разные методы на основе количества параметров. Например, это работает (тривиальный метод, чтобы убедиться, что у меня есть основы работы):

@RequestMapping(method=RequestMethod.GET)
public ModelAndView doIt(@RequestParam("prod") int prod, Model model)
{
  ModelAndView mav = new ModelAndView();
  mav.setViewName("jsonView");
  return mav;
}

но не это:

@RequestMapping(method=RequestMethod.GET)
public ModelAndView doIt(@RequestParam("prod") int prod, Model model)
{
  ModelAndView mav = new ModelAndView();
  mav.setViewName("jsonView");
  return mav;
}

@RequestMapping(method=RequestMethod.GET)
public ModelAndView doIt(@RequestParam("prod") int prod,
                         @RequestParam("owner") int owner,
                         Model model)
{
  ModelAndView mav = new ModelAndView();
  mav.setViewName("jsonView");
  return mav;
}

Это генерирует исключение IllegalStateException, "Нечеткие методы обработчика, сопоставленные для HTTP-пути" /mytest "и продолжает:

Если вы собираетесь обрабатывать один и тот же путь в нескольких методах, затем их коэффициенты выходить в специальный класс обработчика с этим путем, отображаемым по типу уровень!

Я не понимаю, что говорит это сообщение.

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

Пол

Ответ 1

Аннотирование RequestMapping сообщает Spring, какой URL-адрес запрашивает сопоставление с вашим контроллером. Вы можете поместить значение либо на уровне метода, либо на уровне класса.

В вашем примере ничто не отличается между двумя сопоставлениями запросов. Вы можете сделать это, хотя:

@RequestMapping(value="/bar/example.htm", method={RequestMethod.GET}, params={"prod", "owner"})
public String doIt( @RequestParam("prod") int prod,
                    @RequestParam("owner") int owner) {
    LOGGER.trace("in doIt(int,int)");
    return "foo/bar";
}
@RequestMapping(value="/bar/example.htm", method={RequestMethod.GET}, params={"prod"})
public String doIt( @RequestParam("prod") int prod) {
    LOGGER.trace("in doIt(int)");
    return "foo/bar";
}

Вы даже можете поделиться моделью между ними, если хотите:

@Model
public static Map<String,Object> model() {
  LOGGER.trace("in model()");
  Map<String,Object> model = new HashMap<>();
  model.put("hello", "hello world");
  return model;
}

Ответ 2

Ваше сопоставление запросов должно отображать фактический URL, а не только метод HTTP. Вы также можете поместить необходимые параметры на основе каждого метода, например...

@RequestMapping(value="/doSomething", method=RequestMethod.GET, params=["prod", "owner"])
public ModelAndView doIt(@RequestParam("prod") int prod,
                         @RequestParam("owner") int owner,
                         Model model)
{
  ModelAndView mav = new ModelAndView();
  mav.setViewName("jsonView");
  return mav;
}