Используя Spring MVC 3.0.0. ВЫПУСК, у меня есть следующий Контроллер:
@Controller
@RequestMapping("/addIntake.htm")
public class AddIntakeController{
private final Collection<String> users;
public AddIntakeController(){
users = new ArrayList<String>();
users.add("user1");
users.add("user2");
// ...
users.add("userN");
}
@ModelAttribute("users")
public Collection<String> getUsers(){
return this.users;
}
@RequestMapping(method=RequestMethod.GET)
public String setupForm(ModelMap model){
// Set up command object
Intake intake = new Intake();
intake.setIntakeDate(new Date());
model.addAttribute("intake", intake);
return "addIntake";
}
@RequestMapping(method=RequestMethod.POST)
public String addIntake(@ModelAttribute("intake")Intake intake, BindingResult result){
// Validate Intake command object and persist to database
// ...
String caseNumber = assignIntakeACaseNumber();
return "redirect:intakeDetails.htm?caseNumber=" + caseNumber;
}
}
Информация о Потреблении чтений Контроллера от объекта команды, заполненного от HTML-формы, проверяет объект команды, сохраняет информацию к базе данных и возвращает номер дела.
Все работает отлично, за исключением того, когда я перенаправляю к странице intakeDetails.htm, я получаю URL, который похож на это:
http://localhost:8080/project/intakeDetails.htm?caseNumber=1&users=user1&users=user2&users=user3&users=user4...
Как я препятствую тому, чтобы пользовательский Набор обнаружился в URL?
Нет хороших способов решить эту проблему (то есть без создания пользовательских компонентов, без чрезмерного количества явшей конфигурации XML и без ручной реализации RedirectView
).
Вы можете либо инвестиционировать RedirectView
вручную через его 4-аргурирующий конструктор или объявить следующий боб в вашем контексте (рядом с другими резолью просмотра):
public class RedirectViewResolver implements ViewResolver, Ordered {
// Have a highest priority by default
private int order = Integer.MIN_VALUE;
// Uses this prefix to avoid interference with the default behaviour
public static final String REDIRECT_URL_PREFIX = "redirectWithoutModel:";
public View resolveViewName(String viewName, Locale arg1) throws Exception {
if (viewName.startsWith(REDIRECT_URL_PREFIX)) {
String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length());
return new RedirectView(redirectUrl, true, true, false);
}
return null;
}
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
}
Аннотация метода @ModelAttribute
предназначена для использования для предоставления справочных данных слою представления. Я не могу сказать наверняка в вашем случае, но я бы не сказал, что совокупность пользователей квалифицируется как справочные данные. Я предлагаю вам явно передать эту информацию модели в ваших @RequestMapping
-аннотированных методах обработчика.
Если вы все еще хотите использовать @ModelAttribute
, есть запись в блоге , в которой обсуждается проблема перенаправления.
Но все предыдущие примеры имеют общую проблему, поскольку все методы @ModelAttribute запускаются до того, как обработчик будет выполнен, если обработчик возвращает {{1} } перенаправить данные модели будут добавлены к URL-адресу в виде строки запроса. Этого следует избегать любой ценой, поскольку это может раскрыть некоторые секреты того, как вы собрали свое приложение.
Его предложенное решение (см. Часть 4 блога) - использовать HandlerInterceptorAdapter
, чтобы сделать общие справочные данные видимыми для представления. Поскольку справочные данные не должны быть тесно связаны с контроллерами, это не должно создавать проблем с точки зрения дизайна.
Не используйте @ModelAttribute
. Явно сохраните пользователей в ModelMap
. В любом случае вы делаете то же самое с командным объектом.
@RequestMapping(method=RequestMethod.GET)
public String setupForm(ModelMap model){
// Set up command object
Intake intake = new Intake();
intake.setIntakeDate(new Date());
model.addAttribute("intake", intake);
model.addAttribute("users", users);
return "addIntake";
}
Недостатком этого является то, что ошибка проверки имеет место в addIntake ()
. Если вы хотите просто вернуть логическое имя формы, вы также должны не забыть повторно заполнить модель пользователями, иначе форма не будет правильно настроена.