В контроллере 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;
}