Spring RESTful API ::为@RestController方法使用Traits

时间:2015-04-26 17:36:57

标签: spring scala traits

我试图设置spring以使用REST控制器的scala特性。

我们说我需要暴露2个资源:作者和出版物。 这是作者:

AuthorController.java
@RestController
class AuthorController extends BaseController
  with ReadTrait
{
  def getSuffix(): String = {
    "author"
  }
}

以及这里的出版物:

PublicationController.java
@RestController
class PublicationController extends BaseController
  with ReadTrait
{
  def getSuffix(): String = {
    "publication"
  }
}

他们都使用读取特征。

和我需要的阅读特性:

ReadTrait.java
@RestController
trait ReadTrait {

  def getSuffix(): String

  @Secured(Array("ROLE_USER"))
  @RequestMapping(value = Array("/{resource}"), method = Array(RequestMethod.GET))
  def read(@PathVariable("resource") resource: String): Author = {

    if (resource == "author") {
      // ... 
    }
  }
}

所以我面临的问题是,当这两个类使用相同的特性时,Spring会爆炸:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'publicationController' bean method 
public abstract com.example.project.core.Author com.example.project.api._trait.ReadTrait.read(java.lang.String)
to {[/{resource}],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}: There is already 'authorController' bean method
public abstract com.example.project.core.Author com.example.project.api._trait.ReadTrait.read(java.lang.String) 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.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
        at com.example.project.Application.main(Application.java:10)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:53)
        at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'publicationController' bean method 
public abstract com.example.project.core.Author com.example.project.api._trait.ReadTrait.read(java.lang.String)
to {[/{resource}],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}: There is already 'authorController' bean method
public abstract com.example.project.core.Author com.example.project.api._trait.ReadTrait.read(java.lang.String) 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 common frames omitted

当我删除其中一个控制器时,一切都很好并且按预期工作。如果我删除ReadTrait上的@RestController注释,它也可以很好地构建但不起作用。我尝试错误的做法是什么?我怎样才能使它发挥作用?

由于

1 个答案:

答案 0 :(得分:1)

你将Spring Boot与多个String title = myEditText.getText().toString().substring(8); 混淆,没有特殊的映射。

您必须为每个RestController类分配不同的RequestMapping值。