2

我对 Spring 很陌生,遇到以下问题。

我有以下控制器,其中 @Autowired 完美运行(尝试调试并且运行良好)。

@Controller
@RequestMapping(value = "/registration")
@SessionAttributes("rf")
public class RegistrationController
{
    @Autowired
    UserJpaDao userDao;

    @RequestMapping(method = RequestMethod.GET)
    @Transactional
    public String setupForm(Model model) throws Exception
    {
        model.addAttribute("rf", new RegistrationForm());
        return "registration";
    }

    @RequestMapping(method = RequestMethod.POST)
    @Transactional
    public String submitForm(@ModelAttribute("rf") RegistrationForm rf, Model model) throws Exception
    {
        // ...

        User user = rf.getUser();
        userDao.save(user);

        // ...

        return "registration";
    }
}

但是当我提交表单时,我的 RegistrationForm 中的 @Autowired 字段仍然为空。

注册表格.java:

@Component
public class RegistrationForm
{
    @Autowired
    CountryJpaDao countryDao;

    // ... fields...

    public RegistrationForm()
    {

    }

    @Transactional
    public User getUser() throws InvalidUserDataException
    {
        //...

        Country c = countryDao.findByCode("GB"); // Throws java.lang.NullPointerException

        // ...
    }

    // ... getters/setters...
}

这是表单的 HTML/JSTL:

<form:form method="POST" modelAttribute="rf">
    ...
</form:form>

谁能帮我?

谢谢你。

(灵感来自SpringSource 论坛上的这篇文章)

4

2 回答 2

1

你在这里混淆了你的概念。对于 Spring 管理的 bean,以及@Component用于绑定表单数据的瞬态、一次性对象,您可以使用和 之类的。两者不应混用。Spring 将忽略您的和注释,因为它们在该上下文中不合适。@Autowired@ModelAttribute@Component@AutowiredRegistrationForm

像这样的类RegistrationForm应该代表表单数据,仅此而已。通常,控制器会询问RegistrationForm用户 ID,然后会User从 DAO 本身查看实际对象。如果要RegistrationForm查找User自身,则控制器需要在RegistrationForm请求User对象时手动提供 DAO。

就 Spring 论坛上的那篇帖子而言,您会注意到它从未收到答案。这不是一个很好的灵感来源。

请注意,我并不是说希望将 bean 自动装配到表单返回对象中是一个坏主意,我只是说 Spring 不会这样做。

于 2012-02-12T23:48:25.420 回答
1

如果您在模型上使用 @Configurable 注释,并且在您的 gradle 文件上使用这个 aspectJ 配置,它将起作用:

compileJava << {
    ant.taskdef(
        resource: 'org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties',
        classpath: configurations.compile.asPath)

    ant.iajc(
        inpath: sourceSets.main.output.classesDir.absolutePath,
          classpath: configurations.compile.asPath,
          aspectPath: configurations.aspects.asPath,
          destDir: sourceSets.main.output.classesDir.absolutePath
    )
}

以这种方式,aspectJ 将生成执行自动连接的代码。

@Configurable
public class RegistrationForm
{
   ...
}
于 2016-01-28T18:07:42.487 回答