春季MVC组件扫描未能识别控制器

huangapple go评论75阅读模式
英文:

Spring MVC component Scan does not pick up controller

问题

All,

我正在尝试设置一个新的Spring MVC项目,并创建了一个虚拟的控制器。
我面临的问题是Spring没有创建控制器的bean。否则构造函数内的日志语句应该已经打印出来了。
控制器的包名也在beans配置的xml中定义了。

<context:component-scan base-package="com.blah.apps" annotation-config="true"/>

Spring版本:5.2.8
Tomcat版本:8

我使用上述版本并使用基于xml的配置有特定的原因。

我收到的错误是:

Aug 25, 2020 10:53:02 AM org.springframework.web.servlet.DispatcherServlet noHandlerFound
WARNING: No mapping for GET /[app-name]/health
这并不令人感到意外,考虑到bean没有被创建。

请找到下面的代码...

package com.blah.apps.xyz.shopping.health;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HealthController {

public HealthController() {
		System.out.println("甚至这个也没有被打印出来...组件扫描应该允许Spring bean的发现..");
	}


	@ResponseBody
	@RequestMapping(value = "/health")
	public String getHealth() {
		return "应用正在运行!";
	}
}

我的Web.xml是

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	id="WebApp_ID" version="3.1">
	<absolute-ordering />
	<servlet>
		<servlet-name>dispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>dispatcherServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>

dispatcherServlet-servlet.xml :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="  
        http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans.xsd  
        http://www.springframework.org/schema/context  
        http://www.springframework.org/schema/context/spring-context.xsd  
        http://www.springframework.org/schema/mvc  
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

<mvc:annotation-driven />

<!-- 也尝试过移除annotation-config -->
	<context:component-scan
		base-package="com.blah.apps" annotation-config="true"/> 
</beans>
英文:

All,

I am trying to setup a new Spring MVC project and have created a dummy controller.
The problem that i am facing is Spring is not creating the bean of the controller. otherwise the logging statement inside the constructor should have printed.
The package of the controller is also defined in the beans configuration xml.

&lt;context:component-scan base-package=&quot;com.blah.apps&quot; annotation-config=&quot;true&quot;/&gt;

Spring Version: 5.2.8
Tomcat Version: 8

There is a specific reason why i am using the above versions and using xml based configuration.

The error that i get is:

Aug 25, 2020 10:53:02 AM org.springframework.web.servlet.DispatcherServlet noHandlerFound
WARNING: No mapping for GET /[app-name]/health

which is not surprising considering the bean did not get created.

Please find the code below...

package com.blah.apps.xyz.shopping.health;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HealthController {

public HealthController() {
		System.out.println(&quot;Event this is not getting printed...the component scan should allow spring bean discovery..&quot;);
	}


	@ResponseBody
	@RequestMapping(value = &quot;/health&quot;)
	public String getHealth() {
		return &quot;App is running!&quot;;
	}
}

My Web.xml is

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;web-app xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns=&quot;http://xmlns.jcp.org/xml/ns/javaee&quot;
	xsi:schemaLocation=&quot;http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd&quot;
	id=&quot;WebApp_ID&quot; version=&quot;3.1&quot;&gt;
	&lt;absolute-ordering /&gt;
	&lt;servlet&gt;
		&lt;servlet-name&gt;dispatcherServlet&lt;/servlet-name&gt;
		&lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;
		&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
	&lt;/servlet&gt;
	&lt;servlet-mapping&gt;
		&lt;servlet-name&gt;dispatcherServlet&lt;/servlet-name&gt;
		&lt;url-pattern&gt;/&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;
&lt;/web-app&gt;

The dispatcherServlet-servlet.xml :

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
	xmlns:mvc=&quot;http://www.springframework.org/schema/mvc&quot;
	xsi:schemaLocation=&quot;  
        http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans.xsd  
        http://www.springframework.org/schema/context  
        http://www.springframework.org/schema/context/spring-context.xsd  
        http://www.springframework.org/schema/mvc  
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

&lt;mvc:annotation-driven /&gt;

&lt;!-- have tried removing annotation-config as well--&gt;

	&lt;context:component-scan
		base-package=&quot;com.blah.apps&quot; annotation-config=&quot;true&quot;/&gt; 
&lt;/beans&gt;

答案1

得分: 0

您需要在您的 web.xml 中添加一个监听器来加载您的 Spring 上下文。

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/dispatcherServlet-servlet.xml</param-value>
</context-param>

<servlet>
  <servlet-name>spring</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value></param-value>
  </init-param>
</servlet>
英文:

You need to add a listener in your web.xml to load you Spring context.

&lt;listener&gt;
  &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
&lt;/listener&gt;

&lt;context-param&gt;
  &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
  &lt;param-value&gt;/WEB-INF/dispatcherServlet-servlet.xml&lt;/param-value&gt;
&lt;/context-param&gt;

&lt;servlet&gt;
  &lt;servlet-name&gt;spring&lt;/servlet-name&gt;
  &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;
  &lt;init-param&gt;
    &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
    &lt;param-value&gt;&lt;/param-value&gt;
  &lt;/init-param&gt;
&lt;/servlet&gt;

答案2

得分: 0

好的,以下是翻译好的部分:

由于您正在使用 Spring MVC,您应该在您的 web.xml 中有一个监听器,即 ContextLoaderListener。请在您的 web.xml 中添加以下代码:

<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/applicationContext.xml</param-value>
</context-param>

<servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value></param-value>
    </init-param>
</servlet>

DispatcherServlet 的主要目的是处理与配置的 URL 模式匹配的传入 web 请求。它接收传入的 URI 并找到正确的控制器和视图组合。

ContextLoaderListener 创建根应用程序上下文,并将与所有 DispatcherServlet 上下文创建的子上下文共享。它的工作是将 Spring 配置文件作为输入,并根据配置创建 Spring 管理的 bean,在服务器启动期间准备好,在服务器关闭期间销毁。

如果您想要了解有关 ContectLoaderListener 的更多信息,请访问 https://www.java67.com/2019/05/contextloaderlistener-in-spring-mvc-10.html

英文:

Well since you are using Spring mvc, you should have a listener i.e. ContextLoaderListener in your web.xml. Add the below code in your web.xml.

 &lt;listener&gt;
      &lt;listener-class&gt;
        org.springframework.web.context.ContextLoaderListener
      &lt;/listener-class&gt;
    &lt;/listener&gt;
      
    &lt;context-param&gt;
      &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
      &lt;param-value&gt;/WEB-INF/spring/applicationContext.xml&lt;/param-value&gt;
    &lt;/context-param&gt;

&lt;servlet&gt;
  &lt;servlet-name&gt;spring&lt;/servlet-name&gt;
  &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;
  &lt;init-param&gt;
    &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
    &lt;param-value&gt;&lt;/param-value&gt;
  &lt;/init-param&gt;
&lt;/servlet&gt;

DispatcherServlet primary purpose is to handle incoming web requests matching the configured URL pattern. It take an incoming URI and find the right combination of controller and view.

ContextLoaderListener creates the root application context and will be shared with child contexts created by all DispatcherServlet contexts. Its job is to take the Spring configuration files as input and creates the Spring-managed beans as per configuration and make it ready during server startup and destroys them during server shutdown.

If you want to read more about ContectLoaderListener do visit https://www.java67.com/2019/05/contextloaderlistener-in-spring-mvc-10.html.

答案3

得分: 0

All,

终于弄清楚问题所在。代码完全正确...尽管目标文件夹中有控制器类文件,但是Eclipse会将默认输出文件夹更改为项目特定的输出文件夹(尽管我没有在任何地方指定...不确定为什么每次构建都会发生这种情况...)。

英文:

All,

Finally figured out what the problem was. The code was all correct... Even though the target folder had the controller class files, eclipse was changing the default output folder to project specific output folder (even though I have not specified anywhere.. not sure why this is hapenning on every build...).

huangapple
  • 本文由 发表于 2020年8月25日 13:17:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/63572460.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定