ViewResolver

ViewResolver в Spring MVC преобразует логическое имя представления в объект View, который умеет сформировать HTTP-ответ.

Контроллер может вернуть имя шаблона и модель:

@Controller
class ProfileController {
 
    @GetMapping("/profile")
    String profile(Model model) {
        model.addAttribute("name", "Alex");
        return "profile";
    }
}

Здесь "profile" — не готовый HTML и не путь, который обязан существовать буквально. Зарегистрированные ViewResolver пытаются подобрать представление с таким логическим именем.

Место в обработке запроса

Упрощённая цепочка Spring MVC:

DispatcherServlet
→ HandlerMapping
→ controller
→ имя view + model
→ ViewResolver
→ View.render(...)
→ HTTP response

Если контроллер возвращает ModelAndView, результат тот же: модель и логическое имя передаются механизму представлений.

Пример с JSP

@Configuration
@EnableWebMvc
class WebConfig implements WebMvcConfigurer {
 
    @Bean
    ViewResolver jspViewResolver() {
        var resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    }
}

Имя "profile" будет преобразовано в /WEB-INF/views/profile.jsp.

Для Thymeleaf или FreeMarker используются соответствующие интеграции и resolver-ы. В Spring Boot значительную часть конфигурации обычно создаёт автоконфигурация на основании зависимостей и настроек приложения.

Когда ViewResolver не участвует

Для REST-ответа представление обычно не требуется:

@RestController
class ProfileApi {
 
    @GetMapping("/api/profile")
    ProfileDto profile() {
        return new ProfileDto("Alex");
    }
}

Здесь результат обрабатывает HttpMessageConverter: например, Jackson сериализует DTO в JSON. То же относится к методу с @ResponseBody.

Частые ошибки

  • использовать @RestController, а затем ожидать поиск HTML-шаблона;
  • возвращать имя с расширением или полным путём, хотя prefix и suffix уже настроены;
  • путать перенаправление redirect:/path с рендерингом view;
  • держать JSP в каталоге, который не совпадает с настройкой resolver-а;
  • считать ViewResolver механизмом маршрутизации: URL сопоставляет с контроллером HandlerMapping.

На собеседовании

Чем ViewResolver отличается от HttpMessageConverter?

ViewResolver выбирает представление для серверного рендеринга модели. HttpMessageConverter преобразует тело запроса или возвращаемый объект в формат вроде JSON, XML или текста.

Связанные заметки