【问题标题】:Constructor Dependency Injection in Spring MVC 3Spring MVC 3 中的构造函数依赖注入
【发布时间】:2013-06-20 17:43:43
【问题描述】:

我试图在我的控制器中进行依赖注入,而不是使用 setters 方法,但它不起作用。

我想要什么:只需在使用 springframework 3.1 的控制器类中将域模型与我的表单绑定。

我的域类:

public class Person {

  private String name;

  @Autowired
  public Person(String name) {
    this.name = name;
  }

  public String getName() {
    return this.name;
  }

}

我的 jsp(person-get):

<form action="test-person" method="post">
<table cellpadding="0" cellspacing="0" align="center">
    <tr>
        <td> <b> NAME: </b> </td>
        <td> <input type="text" id="name" name="name"> </td>
    </tr>
</table> 
</form>

我的控制器:

@Controller
public class PersonController {

@RequestMapping(value = "test-person", method = RequestMethod.GET)
public String loadViewGet() {       
    return "person-get";
}

@RequestMapping(value = "test-person", method = RequestMethod.POST)
public String doPost(Person person, Model model) {

    model.addAttribute("person", person);

    return "person-post";
}

}

最后一个jsp显示用户输入的人名(person-post):

<table cellpadding="0" cellspacing="0" align="center">
    <tr>
        <td> <b> NAME: </b> </td>
        <td> ${person.name} </td>
    </tr>
</table> 

抛出的异常:

java.lang.NoSuchMethodException: models.Person.<init>()
java.lang.Class.getConstructor0(Unknown Source)
java.lang.Class.getDeclaredConstructor(Unknown Source)
org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:104)
org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttri    bute(ModelAttributeMethodProcessor.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodPr    ocessor.createAttribute(ServletModelAttributeMethodProcessor.java:81)
org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgu    ment(ModelAttributeMethodProcessor.java:103)
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resol    veArgument(HandlerMethodArgumentResolverComposite.java:75)
org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValu    es(InvocableHandlerMethod.java:156)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(Invo    cableHandlerMethod.java:117)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod    .invokeAndHandle(ServletInvocableHandlerMethod.java:96)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.    invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.    handleInternal(RequestMappingHandlerAdapter.java:578)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(Abst    ractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java    :923)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:    852)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.ja    va:882)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
br.gov.sp.mococa.filtros.FiltroDeConexao.doFilter(FiltroDeConexao.java:31)

我认为spring正在寻找一个默认的构造函数whitout参数。为什么会这样?

谢谢!

【问题讨论】:

  • 您在 ApplicationContext 中的何处以及如何声明您的 Person bean?
  • 问题是您没有定义无参数构造函数(public Person() {,这是框架试图调用的)。另外,您为什么要在Person 中自动装配name?您应该在定义 bean 时传递一个值。
  • 您好,感谢您的关注!所以,这就是问题所在:如果我放置一个默认构造函数,框架使用setter方式进行依赖注入,我想使用构造函数注入方式。我知道有办法做到这一点,但不知道如何。再次感谢!

标签: java spring


【解决方案1】:

对于构造函数注入,您需要在 spring-context 中或使用注释将 bean 声明为 spring bean。

但是我怀疑它在用作formbean时是否会将参数作为构造函数传递。 Spring 应该使用 setter 设置参数。使用标准构造函数并添加一个 setter。

【讨论】:

  • "对于构造函数注入,您需要在 spring-context 中或使用注释将 bean 声明为 spring bean。"
【解决方案2】:

spring 使用反射创建需要默认构造函数的对象。在这里,您创建了一个参数化构造函数,因此默认构造函数不可用。所以提供默认构造函数

【讨论】:

  • 我这样做了,但是我无法设置从 POST 数据传递到我的模型的属性值——我认为 Spring MVC 使用反射和 setter 方法来做到这一点。我现在该怎么办?谢谢!
【解决方案3】:

你确定依赖注入是你想要的吗? 您的代码看起来更像您想要基于构造函数的表单绑定。

在后一种情况下,@ModelAttribute 注释可能会对您有所帮助。

要根据请求参数创建模型属性,您可以使用@ModelAttribute 注释:

@ModelAttribute
public Person addPerson(@RequestParam String name) {
    return new Person(name);
}

@RequestMapping(value = "test-person", method = RequestMethod.POST)
public String doPost(Model model) {
    // model already contains "person"
    return "person-post";
}

您还可以在RequestMapping 方法中接收模型值:

@RequestMapping(value = "test-person", method = RequestMethod.POST)
public String doPost(@ModelAttribute("person") Person person, Model model) {
    // do someting with person..    
    return "person-post";
}

Using @ModelAttribute on a method argumentUsing @ModelAttribute on a method

【讨论】:

  • 您好,感谢关注!所以,我已经做了你播种我的两种方式,但不起作用。 HTTP 错误 400。
  • 关于依赖注入,我指的是spring MVC的内部DI——它用DI传递对象人,对吗?
  • 完成,你说得对,我正在尝试将表单与我的域绑定。使用 setter 方式,可能会损害我的对象的业务 - 不是在这种简单的情况下,但在另一种情况下可以。这是我担心的原因吗?
猜你喜欢
  • 2021-08-14
  • 2011-02-02
  • 2018-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多