Стандартное приложение Spring MVC будет обслуживать все запросы через объект, DispatcherServlet
который вы зарегистрировали в своем контейнере сервлетов.
Он DispatcherServlet
просматривает его ApplicationContext
и, если он доступен, ApplicationContext
зарегистрированный с помощью ContextLoaderListener
специальных bean-компонентов, необходимых для настройки логики обслуживания запросов. Эти bean-компоненты описаны в документации .
Возможно, наиболее важные компоненты типа HandlerMapping
map
входящие запросы к обработчикам и список пре- и постпроцессоров (обработчиков-перехватчиков) на основе некоторых критериев, детали которых зависят от HandlerMapping
реализации. Самая популярная реализация поддерживает аннотированные контроллеры, но существуют и другие реализации.
В javadocHandlerMapping
далее описывается, как должны вести себя реализации.
Он DispatcherServlet
находит все компоненты этого типа и регистрирует их в некотором порядке (можно настроить). Обслуживая запрос, проходит DispatcherServlet
цикл по этим HandlerMapping
объектам и тестирует каждый из них, getHandler
чтобы найти тот, который может обрабатывать входящий запрос, представленный как стандарт HttpServletRequest
. Начиная с 4.3.x, если он не находит ничего , он регистрирует предупреждение, которое вы видите
Отображение не найдено для запроса HTTP с URI [/some/path]
в DispatcherServlet
с именем SomeName
и либо выдает, NoHandlerFoundException
либо немедленно фиксирует ответ с кодом состояния 404 Not Found.
Почему не удалось DispatcherServlet
найти объект HandlerMapping
, способный обработать мой запрос?
Наиболее распространенная HandlerMapping
реализация RequestMappingHandlerMapping
, которая обрабатывает регистрацию @Controller
bean-компонентов как обработчиков (на самом деле их @RequestMapping
аннотированных методов). Вы можете объявить bean-компонент этого типа самостоятельно (с помощью @Bean
или <bean>
или другим механизмом) или использовать встроенные параметры . Это:
- Аннотируйте свой
@Configuration
класс с помощью @EnableWebMvc
.
- Объявите
<mvc:annotation-driven />
член в своей конфигурации XML.
Как описано в приведенной выше ссылке, оба из них будут регистрировать RequestMappingHandlerMapping
bean-компонент (и множество других вещей). Однако HandlerMapping
без обработчика a не очень полезен. RequestMappingHandlerMapping
ожидает некоторых @Controller
bean-компонентов, поэтому вам также необходимо объявить их с помощью @Bean
методов в конфигурации Java или <bean>
объявлений в конфигурации XML, или путем сканирования компонентов @Controller
аннотированных классов в любом из них. Убедитесь, что эти бобы присутствуют.
Если вы получаете предупреждающее сообщение и ошибку 404 и правильно настроили все вышеперечисленное, то вы отправляете свой запрос на неправильный URI , который не обрабатывается обнаруженным @RequestMapping
методом аннотированного обработчика.
В spring-webmvc
библиотеке предлагает другие встроенные HandlerMapping
реализации. Например, BeanNameUrlHandlerMapping
карты
от URL до beans с именами, начинающимися с косой черты ("/")
и вы всегда можете написать свой собственный. Очевидно, вам нужно будет убедиться, что отправляемый вами запрос соответствует хотя бы одному из HandlerMapping
обработчиков зарегистрированных объектов.
Если вы неявно или неявно не регистрируете какие-либо HandlerMapping
компоненты (или если detectAllHandlerMappings
есть true
), то DispatcherServlet
регистрируются некоторые значения по умолчанию . Они определены в DispatcherServlet.properties
том же пакете, что и DispatcherServlet
класс. Это BeanNameUrlHandlerMapping
и DefaultAnnotationHandlerMapping
(что аналогично, RequestMappingHandlerMapping
но устарело).
Отладка
Spring MVC будет регистрировать обработчики, зарегистрированные через RequestMappingHandlerMapping
. Например, @Controller
лайк
@Controller
public class ExampleController {
@RequestMapping(path = "/example", method = RequestMethod.GET, headers = "X-Custom")
public String example() {
return "example-view-name";
}
}
будет регистрировать следующее на уровне ИНФОРМАЦИИ
Mapped "{[/example],methods=[GET],headers=[X-Custom]}" onto public java.lang.String com.spring.servlet.ExampleController.example()
Это описывает зарегистрированное отображение. Когда вы видите предупреждение о том, что обработчик не найден, сравните URI в сообщении с отображением, указанным здесь. Все ограничения, указанные в файле, @RequestMapping
должны совпадать с Spring MVC для выбора обработчика.
Другие HandlerMapping
реализации записывают свои собственные операторы, которые должны указывать на их сопоставления и соответствующие обработчики.
Точно так же включите ведение журнала Spring на уровне DEBUG, чтобы увидеть, какие компоненты Spring регистрируются. Он должен сообщать, какие аннотированные классы он находит, какие пакеты сканирует и какие компоненты инициализирует. Если те, которые вы ожидали, отсутствуют, проверьте свою ApplicationContext
конфигурацию.
Другие распространенные ошибки
A DispatcherServlet
- это просто типичный Java EE Servlet
. Вы регистрируете его с вашей типичным <web.xml>
<servlet-class>
и <servlet-mapping>
декларацией, или непосредственно через ServletContext#addServlet
в WebApplicationInitializer
, или с каким - либо механизмом Spring загрузочного использованием. Таким образом, вы должны полагаться на логику сопоставления URL-адресов, указанную в спецификации сервлета , см. Главу 12. См. Также
Имея это в виду, распространенной ошибкой является регистрация DispatcherServlet
объекта с сопоставлением URL-адресов /*
, возвращение имени представления из @RequestMapping
метода обработчика и ожидание отрисовки JSP. Например, рассмотрим такой метод обработчика, как
@RequestMapping(path = "/example", method = RequestMethod.GET)
public String example() {
return "example-view-name";
}
с InternalResourceViewResolver
@Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver vr = new InternalResourceViewResolver();
vr.setPrefix("/WEB-INF/jsps/");
vr.setSuffix(".jsp");
return vr;
}
вы можете ожидать, что запрос будет перенаправлен на ресурс JSP по пути /WEB-INF/jsps/example-view-name.jsp
. Этого не произойдет. Вместо этого, предполагая контекстное имя Example
, DisaptcherServlet
будет сообщать
Отображение не найдено для HTTP запроса с URI [/Example/WEB-INF/jsps/example-view-name.jsp]
в DispatcherServlet
с именем «диспетчером»
Поскольку DispatcherServlet
сопоставлен /*
и /*
соответствует всему (кроме точных совпадений, которые имеют более высокий приоритет), DispatcherServlet
будет выбран для обработки forward
из JstlView
(возвращенного InternalResourceViewResolver
). Практически в каждом случае DispatcherServlet
не будет настроен для обработки такого запроса .
Вместо этого в этом упрощенном случае вы должны зарегистрировать DispatcherServlet
to /
, пометив его как сервлет по умолчанию. Сервлет по умолчанию - это последнее совпадение для запроса. Это позволит вашему типичному контейнеру сервлета выбрать внутреннюю реализацию сервлета, сопоставленную для *.jsp
обработки ресурса JSP (например, Tomcat JspServlet
), прежде чем пытаться использовать сервлет по умолчанию.
Это то, что вы видите в своем примере.
@EnableWebMvc
по себе в@Configuration
аннотированном классе этого не делает. Все, что он делает, - это добавляет в контекст приложения ряд бинов обработчиков / адаптеров Spring MVC по умолчанию. РегистрацияDispatcherServlet
для обслуживания/
- это совершенно отдельный процесс, который выполняется несколькими способами, которые я описываю в разделе « Другие распространенные ошибки ». Я отвечаю на вопрос, заданный двумя абзацами ниже того, что вы цитировали.Я решил свою проблему, когда в дополнение к описанному ранее:
@Bean public InternalResourceViewResolver resolver() { InternalResourceViewResolver vr = new InternalResourceViewResolver(); vr.setPrefix("/WEB-INF/jsps/"); vr.setSuffix(".jsp"); return vr; }
added tomcat-embed-jasper:
`from: файл JSP не отображается в веб-приложении Spring Boot
источник
В моем случае я следил за документацией Interceptors Spring для версии 5.1.2 (при использовании Spring Boot v2.0.4.RELEASE ), и у
WebConfig
класса была аннотация@EnableWebMvc
, которая, казалось, противоречила чему-то еще в моем приложении, что предотвращало мои статические активы не разрешались правильно (т.е. клиенту не возвращались файлы CSS или JS).После попытки много разных вещей, я пытался удалением
@EnableWebMvc
и это сработало!Изменить: вот справочная документация, в которой говорится, что вы должны удалить
@EnableWebMvc
аннотациюПо-видимому, по крайней мере в моем случае, я уже настраиваю свое приложение Spring (хотя не с помощью
web.xml
или любого другого статического файла, это определенно программно), поэтому там был конфликт.источник
Попробуйте внести в код следующие изменения в файл конфигурации. Конфигурация Java используется вместо
application.properties
. Не забудьте включить конфигурацию вconfigureDefaultServletHandling
методе.@Configuration @EnableWebMvc @ComponentScan public class WebConfig implements WebMvcConfigurer { @Override public void configureViewResolvers(ViewResolverRegistry registry) { registry.jsp("/WEB-INF/views/", ".jsp"); } @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } }
Я использую gradle, у вас должны быть следующие зависимости
pom.xml
:dependencies { compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.3.0.RELEASE' compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-jasper', version: '9.0.35' }
источник
Я столкнулся с другой причиной той же ошибки. Это также может быть связано с тем, что файлы классов не созданы для вашего файла controller.java. В результате сервлет диспетчера, упомянутый в web.xml, не может сопоставить его с соответствующим методом в классе контроллера.
@Controller Class Controller{ @RequestMapping(value="/abc.html")//abc is the requesting page public void method() {.....} }
В eclipse в Project-> выберите clean -> Build Project. Проверьте, был ли сгенерирован файл класса для файла контроллера при сборках в вашей рабочей области.
источник
Что касается меня, я обнаружил, что мои целевые классы были сгенерированы в шаблоне папки, отличном от исходного. Возможно, это в eclipse, я добавляю папки для хранения своих контроллеров, а не добавляю их как пакеты. В итоге я указал неверный путь в конфигурации Spring.
Мой целевой класс создавал классы в приложении, и я имел в виду com.happy.app
<context:annotation-config /> <context:component-scan base-package="com.happy.app"></context:component-scan>
Я добавил пакеты (не папки) для com.happy.app и переместил файлы из папок в пакеты в eclipse, и это решило проблему.
источник
Очистите свой сервер. Возможно, удалите сервер и снова добавьте проект и запустите.
Остановите сервер Tomcat
Щелкните сервер правой кнопкой мыши и выберите «Очистить».
Снова щелкните сервер правой кнопкой мыши и выберите «Очистить рабочий каталог Tomcat»
источник
В моем случае я играл с импортом вторичных файлов конфигурации java в основной файл конфигурации java. При создании дополнительных файлов конфигурации я изменил имя основного класса конфигурации, но мне не удалось обновить имя в web.xml. Итак, каждый раз, когда я перезапускал свой сервер tomcat, я не видел обработчиков сопоставления, отмеченных в консоли Eclipse IDE, и когда я пытался перейти на свою домашнюю страницу, я видел эту ошибку:
Исправление заключалось в обновлении файла web.xml так, чтобы старое имя «WebConfig» было вместо «MainConfig», просто переименовав его, чтобы отразить последнее имя основного файла конфигурации java (где «MainConfig» произвольно, а слова « Используемые здесь Web и Main не являются синтаксическими требованиями). MainConfig был важен, потому что это был файл, в котором компонент сканировал "WebController", мой класс весеннего контроллера mvc, который обрабатывает мои веб-запросы.
@ComponentScan(basePackageClasses={WebController.class})
web.xml имел это:
В файле web.xml теперь есть:
Теперь я вижу отображение в окне консоли:
И моя веб-страница снова загружается.
источник
У меня была такая же проблема как
**No mapping found for HTTP request with URI [/some/path] in DispatcherServlet with name SomeName**
После того, как я проанализировал от 2 до 4 дней, я выяснил первопричину. Файлы классов не были созданы после запуска проекта. Я щелкнул вкладку проекта.
Были созданы файлы классов для исходного кода. Это решило мою проблему. Чтобы проверить, были ли сгенерированы файлы классов, проверьте папку Build в папке вашего проекта.
источник