Что означает, когда Spring MVC @Controller возвращает нулевое имя вида?
Я загрузил код для Spring MVC 3 Showcase. Одна вещь озадачивает меня (ну, более одного), почему это (отредактированное для примера) возвращение образца null
?
@Controller
@RequestMapping("/form")
public class FormController {
@RequestMapping(method=RequestMethod.POST)
public String processSubmit(@Valid FormBean form,
BindingResult result,
WebRequest webRequest,
HttpSession session, Model model) {
if (result.hasErrors()) {
return null;
} else {
session.setAttribute("form", form);
return "redirect:/form";
}
}
}
Ответы
Ответ 1
Если контроллер возвращает имя нулевого представления или объявляет тип возврата void
, Spring будет пытаться вывести имя представления из URL-адреса запроса.
В вашем случае предполагается, что имя представления form
и продолжить это предположение.
Это делается с помощью реализации RequestToViewNameTranslator
, реализация по умолчанию которой DefaultRequestToViewNameTranslator
, javadoc, для которой объясняются точные правила, которые она применяет.
Ответ 2
AnnotationMethodHandlerAdapter.invokeHandlerMethod()
заботится о вызове методов обработчика. Здесь ModelAndView
будет извлекаться через ServletHandlerMethodInvoker.getModelAndView()
.
В вашем случае getModelAndView()
получает предоставленный метод обработчика null
возвращаемое значение. Метод getModelAndView()
проверяет тип возвращаемого значения, но поскольку в Java null никогда не является экземпляром какого-либо класса, эта логика метода создаст новый ModelAndView
. Новый ModelAndView
изначально имеет свойство вида, равное null
.
Затем, затем создайте резервную копию стека вызовов в DispatcherServlet.doDispatch()
, существует тест, если объект ModelAndView
связан с ним View
(mv.hasView()
). Поскольку логика view == null
, doDispatch()
вызывает mv.setViewName(getDefaultViewName(request))
. Он делегирует зарегистрированный RequestToViewNameTranslator
, реализация которого по умолчанию - DefaultRequestToViewNameTranslator
. Этот подкласс переводит URI запроса в имя представления, в вашем случае form
.
Позже в doDispatch()
, через render()
→ resolveViewName()
, этот образец ViewResolver
предоставляется с именем вида form
. В этом примере используется только один ViewResolver
, InternalResourceViewResolver
. Кроме того, этот InternalResourceViewResolver
был настроен в src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml
, чтобы добавить префикс /WEB-INF/views/
и суффикс .jsp
к имени представления. Таким образом, в общей сложности он создаст View
, используя JSP файл /WEB-INF/views/form.jsp
. К счастью, JSP файл существует именно в этом месте.