Ich versuche, eine App zu erstellen, die einige Werte aus der Datenbank auflisten und ändern, hinzufügen und bei Bedarf mit Spring 4 löschen kann. Ich erhalte die folgende Fehlermeldung (nur wenn die Anmerkung "@Controller" in beiden Controller-Dateien vorhanden ist Wenn ich die Annotation aus einer der Dateien lösche, funktioniert sie, aber ich erhalte in der Konsole die Meldung "keine Zuordnung gefunden ... in dispatcherservlet mit Name ...):"
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/edit/{id}],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public Java.lang.String com.bookReview.app.BookController.editBook(int,org.springframework.ui.Model)
WARN : org.springframework.web.context.support.XmlWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0': Invocation of init method failed; nested exception is Java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'reviewController' bean method
public Java.lang.String com.bookReview.app.ReviewController.editReview(int,org.springframework.ui.Model)
to {[/edit/{id}],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}: There is already 'bookController' bean method
public Java.lang.String com.bookReview.app.BookController.editBook(int,org.springframework.ui.Model) mapped.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.Java:1574)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.Java:539)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.Java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.Java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.Java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.Java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.Java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.Java:755)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.Java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.Java:480)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.Java:403)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.Java:306)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.Java:106)
at org.Apache.catalina.core.StandardContext.listenerStart(StandardContext.Java:4728)
at org.Apache.catalina.core.StandardContext.startInternal(StandardContext.Java:5166)
at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:150)
at org.Apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.Java:1409)
at org.Apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.Java:1399)
at Java.util.concurrent.FutureTask.run(FutureTask.Java:266)
at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1142)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:617)
at Java.lang.Thread.run(Thread.Java:745)
Caused by: Java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'reviewController' bean method
public Java.lang.String com.bookReview.app.ReviewController.editReview(int,org.springframework.ui.Model)
to {[/edit/{id}],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}: There is already 'bookController' bean method
public Java.lang.String com.bookReview.app.BookController.editBook(int,org.springframework.ui.Model) mapped.
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.registerHandlerMethod(AbstractHandlerMethodMapping.Java:212)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.detectHandlerMethods(AbstractHandlerMethodMapping.Java:184)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods(AbstractHandlerMethodMapping.Java:144)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.afterPropertiesSet(AbstractHandlerMethodMapping.Java:123)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.afterPropertiesSet(RequestMappingHandlerMapping.Java:126)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.Java:1633)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.Java:1570)
... 21 more
Dies ist meine pom.xml-Datei
<project xmlns="http://maven.Apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.Apache.org/POM/4.0.0 http://maven.Apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bookReview.app</groupId>
<artifactId>BookReviewApp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>BookReviewApp</name>
<description>review app</description>
<!-- <properties>
Generic properties
<Java.version>1.8</Java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
Spring
<spring-framework.version>4.0.3.RELEASE</spring-framework.version>
Hibernate / JPA
<hibernate.version>4.3.5.Final</hibernate.version>
<hibernate.version>3.6.9.Final</hibernate.version>
Logging
<logback.version>1.0.13</logback.version>
<slf4j.version>1.7.5</slf4j.version>
</properties> -->
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.6.RELEASE</version>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.9.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.9.Final</version>
</dependency>
<!-- Apache Commons DBCP -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<!-- Spring ORM -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.5</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.12</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.Sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.Sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2.1-b03</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-Java</artifactId>
<version>5.1.35</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
</dependencies>
</project>
Dies ist meine web.xml-Datei
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://Java.Sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://Java.Sun.com/xml/ns/javaee http://Java.Sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/app/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/app/servlet/sevlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Dies ist meine Datei sevlet-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
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/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing
infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving
up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources
in the /WEB-INF/views directory -->
<beans:bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<beans:bean id="dataSource" class="org.Apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
<beans:property name="url"
value="jdbc:mysql://localhost:3306/test" />
<beans:property name="username" value="serban" />
<beans:property name="password" value="serban" />
</beans:bean>
<!-- Hibernate 4 SessionFactory Bean definition -->
<beans:bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="annotatedClasses">
<beans:list>
<beans:value>com.bookReview.app.model.book</beans:value>
<beans:value>com.bookReview.app.model.review</beans:value>
</beans:list>
</beans:property>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<beans:bean id="bookDAO" class="com.bookReview.app.dao.bookDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</beans:bean>
<beans:bean id="bookService" class="com.bookReview.app.service.BookServiceImpl">
<beans:property name="bookDAO" ref="bookDAO"></beans:property>
</beans:bean>
<beans:bean id="reviewDAO" class="com.bookReview.app.dao.reviewDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</beans:bean>
<beans:bean id="reviewService" class="com.bookReview.app.service.ReviewServiceImpl">
<beans:property name="reviewDAO" ref="reviewDAO"></beans:property>
</beans:bean>
<!-- <default-servlet-handler/> -->
<context:component-scan base-package="com.bookReview.app" />
<tx:annotation-driven transaction-manager="transactionManager"/>
<beans:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</beans:bean>
</beans:beans>
Dies ist meine BookController.Java-Datei
package com.bookReview.app;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.bookReview.app.model.book;
import com.bookReview.app.service.BookService;
@Controller
public class BookController {
private BookService bookService;
@Autowired(required=true)
@Qualifier(value="bookService")
public void setBookService(BookService bs){
this.bookService = bs;
}
@RequestMapping(value = "/books", method = RequestMethod.GET)
public String listBooks(Model model) {
model.addAttribute("book", new book());
model.addAttribute("listBooks", this.bookService.listBooks());
return "book";
}
//For add and update book both
@RequestMapping(value= "/book/add", method = RequestMethod.POST)
public String addBook(@ModelAttribute("book") book b){
if(b.getBookid() == 0){
//new book, add it
this.bookService.addBook(b);
}else{
//existing book, call update
this.bookService.updateBook(b);
}
return "redirect:/books";
}
@RequestMapping("/remove/{id}")
public String removeBook(@PathVariable("id") int id){
this.bookService.removeBook(id);
return "redirect:/books";
}
@RequestMapping("/edit/{id}")
public String editBook(@PathVariable("id") int id, Model model){
model.addAttribute("book", this.bookService.getBookById(id));
model.addAttribute("listBooks", this.bookService.listBooks());
return "book";
}
}
Und das ist meine ReviewController.Java-Datei
package com.bookReview.app;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.bookReview.app.model.review;
import com.bookReview.app.service.ReviewService;
@Controller
public class ReviewController {
private ReviewService reviewService;
@Autowired(required=true)
@Qualifier(value="reviewService")
public void setReviewService(ReviewService rs){
this.reviewService = rs;
}
@RequestMapping(value = "/reviews", method = RequestMethod.GET)
public String listReviews(Model model) {
model.addAttribute("book", new review());
model.addAttribute("listReviews", this.reviewService.listReviews());
return "review";
}
//For add and update review both
@RequestMapping(value= "/review/add", method = RequestMethod.POST)
public String addReview(@ModelAttribute("review") review r){
if(r.getId() == 0){
//new review, add it
this.reviewService.addReview(r);
}else{
//existing review, call update
this.reviewService.updateReview(r);
}
return "redirect:/reviews";
}
@RequestMapping("/remove/{id}")
public String removeReview(@PathVariable("id") int id){
this.reviewService.removeReview(id);
return "redirect:/reviews";
}
@RequestMapping("/edit/{id}")
public String editReview(@PathVariable("id") int id, Model model){
model.addAttribute("review", this.reviewService.getReviewById(id));
model.addAttribute("listReviews", this.reviewService.listReviews());
return "review";
}
}
Vielen Dank
Du solltest schreiben
@Controller("/review")
public class ReviewController {
und
@Controller("/book")
public class BookController {
weil in Ihrem Code die zwei Methoden ohne expliziten/eindeutigen Pfad für das Mapping vorhanden sind (z. B. wenn wir einen Aufruf/edit/1 haben, ist es unmöglich, die Methode eines Controllers eindeutig aus Ihrem editBook BookController
oder ReviewController editReview
zu bestimmen)
Wenn es sich bei dem Problem um eine ambitionierte Methode handelt, sollte der @RequestMapping
wahrscheinlich das Problem sein. Von @RequestMapping ( name = ...) in @RequestMapping ( value = ...) ändern
@RequestMapping(name = "xxx.htm", method = RequestMethod.GET)
zu
@RequestMapping(value = "xxx.htm", method = RequestMethod.GET)
Das Hinzufügen des Attributs "params" in @RequestMapping funktionierte für mich wie gezeigt
@ResponseBody
@RequestMapping(method = RequestMethod.GET, params = {"id"})
public User getUserById(final @RequestParam(name="id", required = true) String Id)
throws InvalidArgumentException {
return userService.getUserById(UUID.fromString(Id));
}
/**
* REST service endpoint.
* @param name Unique name for the user in the system.
* @return Object of type {@link User} if exists otherwise null.
*/
@ResponseBody
@RequestMapping(method = RequestMethod.GET, params = {"name"})
public User getUserByName(final @RequestParam(name="name", required = true) String name)
throws InvalidArgumentException {
return userService.getUserByName(name);
}
Durch das gleichzeitige Hinzufügen beider Parameter in der Abfragezeichenfolge wird jedoch ein Fehler mit der folgenden Meldung angezeigt:
Mehrdeutige Handler-Methoden, die dem HTTP-Pfad zugeordnet sind
In diesem Fall können Sie eine andere Controller-Methode verwenden, die beide Parameter übernimmt, aber nur eine davon verwendet, die meiner Meinung nach nicht notwendig ist.
In meinem Fall hatte ich zwei Methoden in zwei verschiedenen Controllern in einer Spring-Boot-Anwendung, beide mit der gleichen @DeleteMapping("/detailbonadelete/{id}") // delete
, ich habe eine davon in @DeleteMapping("/bonadelete/{id}") // delete
geändert und es funktioniert.
Das Gleiche, wenn Sie haben:
@PutMapping("/detailbonaupdate/{id}") // update
@PostMapping("/detailbonainsert") // insert
@GetMapping("/detailbonaidbon/{idBona}") // selectByBonaId
Stellen Sie sicher, dass es für jeden Controller eindeutig ist.