Spring 批处理管理 + Spring 引导 - 模糊映射。无法映射 'org.springframework.batch.admin.web.JobController#1' 方法
Spring Batch Admin + Spring Boot - Ambiguous mapping. Cannot map 'org.springframework.batch.admin.web.JobController#1' method
我正在尝试使用 spring-batch-admin-samples Spring 批处理管理 UI
项目.
我的工作使用 Spring Boot,我已经将我的主应用程序 class 更改为可使用 this link 部署到 Weblogic。
所以应用程序 class 看起来像
@SpringBootApplication(exclude = { HypermediaAutoConfiguration.class,
MultipartAutoConfiguration.class })
@EnableBatchAdmin
public class MyApplication extends SpringBootServletInitializer
implements WebApplicationInitializer {
@Override
protected SpringApplicationBuilder configure(
SpringApplicationBuilder builder) {
return configureApplication(builder);
}
public static void main(String[] args) {
configureApplication(new SpringApplicationBuilder()).run(args);
}
private static SpringApplicationBuilder configureApplication(
SpringApplicationBuilder builder) {
return builder.sources(MyApplication.class).bannerMode(Banner.Mode.OFF);
}
}
我也从配置 class 中删除了 - @EnableBatchProcessing
。
到目前为止,我收到了很多错误(超过 10 个),并且能够通过覆盖 xml 等或添加属性来克服每个错误。
下面这个错误是我无法修复的,
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'org.springframework.batch.admin.web.JobController#1' method
public java.lang.String org.springframework.batch.admin.web.JobController.launch(org.springframework.ui.ModelMap,java.lang.String,org.springframework.batch.admin.web.LaunchRequest,org.springframework.validation.Errors,java.lang.String)
to {[/jobs/{jobName}],methods=[POST]}: There is already 'org.springframework.batch.admin.web.JobController#0' bean method
public java.lang.String org.springframework.batch.admin.web.JobController.launch(org.springframework.ui.ModelMap,java.lang.String,org.springframework.batch.admin.web.LaunchRequest,org.springframework.validation.Errors,java.lang.String) mapped.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:776)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:369)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:313)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:134)
at com.hms.responsematching.batch.ResponseMatchingApplication.main(ResponseMatchingApplication.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:59)
Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'org.springframework.batch.admin.web.JobController#1' method
public java.lang.String org.springframework.batch.admin.web.JobController.launch(org.springframework.ui.ModelMap,java.lang.String,org.springframework.batch.admin.web.LaunchRequest,org.springframework.validation.Errors,java.lang.String)
to {[/jobs/{jobName}],methods=[POST]}: There is already 'org.springframework.batch.admin.web.JobController#0' bean method
public java.lang.String org.springframework.batch.admin.web.JobController.launch(org.springframework.ui.ModelMap,java.lang.String,org.springframework.batch.admin.web.LaunchRequest,org.springframework.validation.Errors,java.lang.String) mapped.
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.assertUniqueMethodMapping(AbstractHandlerMethodMapping.java:576)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.register(AbstractHandlerMethodMapping.java:540)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.registerHandlerMethod(AbstractHandlerMethodMapping.java:264)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.detectHandlerMethods(AbstractHandlerMethodMapping.java:250)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods(AbstractHandlerMethodMapping.java:214)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.afterPropertiesSet(AbstractHandlerMethodMapping.java:184)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.afterPropertiesSet(RequestMappingHandlerMapping.java:128)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
... 23 common frames omitted
我可以想到两个问题,
1.org.springframework.batch.admin.web.JobController 有两个具有相同 URL 但不同 HTTP 方法的方法 - launch
和 details
。
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-admin-manager</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
</dependency>
web.xml in spring-batch-admin-resources 项目使用来自两个 xml 的 contextConfigLocation
所以可能是上下文加载问题。
<context-param><param-name>contextConfigLocation</param-name> <param-value>classpath*:/org/springframework/batch/admin/web/resources/webapp-config.xml</param-value> </context-param>
和
<servlet>
<servlet-name>Batch Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/org/springframework/batch/admin/web/resources/servlet-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
如果需要更多详细信息,请提出建议并告诉我。
编辑:通过查看 接受的答案,似乎相同的 URL 可以应用于不同的 HTTP 方法并且不会产生错误。原因在别处。
我只是不明白为什么当 运行ning jar of spring-batch-admin-samples 时一切正常
project. 但在尝试自己的类似代码时开始收到问题。应用程序 class 与示例中提到的相同。当您尝试通过覆盖下面提到的这两个 xml 来解决以下有关对象映射器的问题时,您开始收到问题映射问题。
Constructor in org.springframework.boot.actuate.autoconfigure.EndpointMBeanExportAutoConfiguration required a single bean, but 2 were found:
- jacksonMapper: defined in URL [jar:file:/D:/RunRC/ResponseMatching/ResponseMatchingWithAdmin-0.0.1-SNAPSHOT.jar!/BOOT-INF/lib/spring-batch-admin-resources-2.0.0.BUILD-SNAPSHOT.jar!/META-INF/spring/batch/servlet/resources/resources-context.xml]
- objectMapper: defined in URL [jar:file:/D:/RunRC/ResponseMatching/ResponseMatchingWithAdmin-0.0.1-SNAPSHOT.jar!/BOOT-INF/lib/spring-batch-admin-manager-2.0.0.BUILD-SNAPSHOT.jar!/META-INF/spring/batch/servlet/manager/controller-context-legacy.xml]
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
修复完成后开始收到上述问题 Proxy Issue on SimpleJobService
覆盖 controller-context-legacy.xml
没有条目/空文件或单个条目,如 <bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper" primary="true"/>
没有影响。
总而言之,我只是想运行说示例项目配合我的工作。一个区别是示例项目使用 Gradle
而我使用 Maven
来构建我的项目。我的工作已经使用 Maven 编写,所以继续这样做。
经过几天的点击和试用,我能够让示例 Github 项目为我的工作工作。两个根本原因,
1.@Configuration
& @SpringBootApplication
与我的工作在同一个包中:我的上下文被初始化了两次,因为我有两个 classes 在同一个包中,所以我不得不将配置 class 移动到与 main class.
不同的包
2.Spring 引导版本: 示例项目在 Spring 引导版本 1.2.2.RELEASE 中编码,而我的工作使用的是 1.4 .0.RELEASE 这导致了 objectMapper
问题。项目使用 1.2.2.RELEASE 以及最新版本 1.5.2.RELEASE,所以我将自己升级到 1.5.2.RELEASE。
我遇到了其他各种问题,
JNDI数据源使用
应用上下文路径更改
通过 Spring 调度程序启动作业
Logback 日志记录
读取非标准引导属性
我的部署环境是 Weblogic,RDBMS 是 DB2。我能够解决所有这些问题,主要是我的 spring-batch-admin-manager API 的重写 XML。
希望这对任何打算使用该示例项目作为起点的人有所帮助。
我正在尝试使用 spring-batch-admin-samples Spring 批处理管理 UI 项目.
我的工作使用 Spring Boot,我已经将我的主应用程序 class 更改为可使用 this link 部署到 Weblogic。
所以应用程序 class 看起来像
@SpringBootApplication(exclude = { HypermediaAutoConfiguration.class,
MultipartAutoConfiguration.class })
@EnableBatchAdmin
public class MyApplication extends SpringBootServletInitializer
implements WebApplicationInitializer {
@Override
protected SpringApplicationBuilder configure(
SpringApplicationBuilder builder) {
return configureApplication(builder);
}
public static void main(String[] args) {
configureApplication(new SpringApplicationBuilder()).run(args);
}
private static SpringApplicationBuilder configureApplication(
SpringApplicationBuilder builder) {
return builder.sources(MyApplication.class).bannerMode(Banner.Mode.OFF);
}
}
我也从配置 class 中删除了 - @EnableBatchProcessing
。
到目前为止,我收到了很多错误(超过 10 个),并且能够通过覆盖 xml 等或添加属性来克服每个错误。
下面这个错误是我无法修复的,
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'org.springframework.batch.admin.web.JobController#1' method
public java.lang.String org.springframework.batch.admin.web.JobController.launch(org.springframework.ui.ModelMap,java.lang.String,org.springframework.batch.admin.web.LaunchRequest,org.springframework.validation.Errors,java.lang.String)
to {[/jobs/{jobName}],methods=[POST]}: There is already 'org.springframework.batch.admin.web.JobController#0' bean method
public java.lang.String org.springframework.batch.admin.web.JobController.launch(org.springframework.ui.ModelMap,java.lang.String,org.springframework.batch.admin.web.LaunchRequest,org.springframework.validation.Errors,java.lang.String) mapped.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:776)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:369)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:313)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:134)
at com.hms.responsematching.batch.ResponseMatchingApplication.main(ResponseMatchingApplication.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:59)
Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'org.springframework.batch.admin.web.JobController#1' method
public java.lang.String org.springframework.batch.admin.web.JobController.launch(org.springframework.ui.ModelMap,java.lang.String,org.springframework.batch.admin.web.LaunchRequest,org.springframework.validation.Errors,java.lang.String)
to {[/jobs/{jobName}],methods=[POST]}: There is already 'org.springframework.batch.admin.web.JobController#0' bean method
public java.lang.String org.springframework.batch.admin.web.JobController.launch(org.springframework.ui.ModelMap,java.lang.String,org.springframework.batch.admin.web.LaunchRequest,org.springframework.validation.Errors,java.lang.String) mapped.
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.assertUniqueMethodMapping(AbstractHandlerMethodMapping.java:576)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.register(AbstractHandlerMethodMapping.java:540)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.registerHandlerMethod(AbstractHandlerMethodMapping.java:264)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.detectHandlerMethods(AbstractHandlerMethodMapping.java:250)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods(AbstractHandlerMethodMapping.java:214)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.afterPropertiesSet(AbstractHandlerMethodMapping.java:184)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.afterPropertiesSet(RequestMappingHandlerMapping.java:128)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
... 23 common frames omitted
我可以想到两个问题,
1.org.springframework.batch.admin.web.JobController 有两个具有相同 URL 但不同 HTTP 方法的方法 - launch
和 details
。
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-admin-manager</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
</dependency>
web.xml in spring-batch-admin-resources 项目使用来自两个 xml 的
contextConfigLocation
所以可能是上下文加载问题。<context-param><param-name>contextConfigLocation</param-name> <param-value>classpath*:/org/springframework/batch/admin/web/resources/webapp-config.xml</param-value> </context-param>
和
<servlet>
<servlet-name>Batch Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/org/springframework/batch/admin/web/resources/servlet-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
如果需要更多详细信息,请提出建议并告诉我。
编辑:通过查看
我只是不明白为什么当 运行ning jar of spring-batch-admin-samples 时一切正常 project. 但在尝试自己的类似代码时开始收到问题。应用程序 class 与示例中提到的相同。当您尝试通过覆盖下面提到的这两个 xml 来解决以下有关对象映射器的问题时,您开始收到问题映射问题。
Constructor in org.springframework.boot.actuate.autoconfigure.EndpointMBeanExportAutoConfiguration required a single bean, but 2 were found:
- jacksonMapper: defined in URL [jar:file:/D:/RunRC/ResponseMatching/ResponseMatchingWithAdmin-0.0.1-SNAPSHOT.jar!/BOOT-INF/lib/spring-batch-admin-resources-2.0.0.BUILD-SNAPSHOT.jar!/META-INF/spring/batch/servlet/resources/resources-context.xml]
- objectMapper: defined in URL [jar:file:/D:/RunRC/ResponseMatching/ResponseMatchingWithAdmin-0.0.1-SNAPSHOT.jar!/BOOT-INF/lib/spring-batch-admin-manager-2.0.0.BUILD-SNAPSHOT.jar!/META-INF/spring/batch/servlet/manager/controller-context-legacy.xml]
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
修复完成后开始收到上述问题 Proxy Issue on SimpleJobService
覆盖 controller-context-legacy.xml
没有条目/空文件或单个条目,如 <bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper" primary="true"/>
没有影响。
总而言之,我只是想运行说示例项目配合我的工作。一个区别是示例项目使用 Gradle
而我使用 Maven
来构建我的项目。我的工作已经使用 Maven 编写,所以继续这样做。
经过几天的点击和试用,我能够让示例 Github 项目为我的工作工作。两个根本原因,
1.@Configuration
& @SpringBootApplication
与我的工作在同一个包中:我的上下文被初始化了两次,因为我有两个 classes 在同一个包中,所以我不得不将配置 class 移动到与 main class.
2.Spring 引导版本: 示例项目在 Spring 引导版本 1.2.2.RELEASE 中编码,而我的工作使用的是 1.4 .0.RELEASE 这导致了 objectMapper
问题。项目使用 1.2.2.RELEASE 以及最新版本 1.5.2.RELEASE,所以我将自己升级到 1.5.2.RELEASE。
我遇到了其他各种问题,
JNDI数据源使用
应用上下文路径更改
通过 Spring 调度程序启动作业
Logback 日志记录
读取非标准引导属性
我的部署环境是 Weblogic,RDBMS 是 DB2。我能够解决所有这些问题,主要是我的 spring-batch-admin-manager API 的重写 XML。
希望这对任何打算使用该示例项目作为起点的人有所帮助。