@Autowired 用于@ModelAttribute

发布于 2025-01-05 01:05:30 字数 1619 浏览 1 评论 0原文

我对 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 字段保持为空。

RegistrationForm.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 论坛上这篇文章的启发)

I'm very new to Spring and I'm encountering the following problem.

I've got the following Controller, in which the @Autowired works perfectly (tried debugging and it works fine).

@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";
    }
}

But when I submit my form, the @Autowired field in my RegistrationForm remains null.

RegistrationForm.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...
}

Here is the form's HTML/JSTL:

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

Can anyone help me?

Thank you.

(inspired by this post on SpringSource forums)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

他夏了夏天 2025-01-12 01:05:30

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

RegistrationForm 这样的类应该表示表单数据,而不是其他任何内容。通常,控制器会向 RegistrationForm 询问用户 ID,然后从 DAO 本身查看实际的 User 对象。如果您希望 RegistrationForm 查找 User 本身,那么您的控制器需要在请求 User 时手动向 RegistrationForm 提供 DAO >用户对象。

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

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

You're mixing up your concepts here. You use the likes of @Component and @Autowired for Spring-managed beans, and @ModelAttribute for transient, throwaway objects that are used to bind form data. The two should not be mixed. Your @Component and @Autowired annotations on RegistrationForm will be ignored by Spring, because they're not appropriate in that context.

Classes like RegistrationForm should represent the form data, and nothing else. Typically, the controller would ask RegistrationForm for the user ID, and would then look at the actual User object from the DAO itself. If you want RegistrationForm to look up the User itself, then your controller needs to manually supply the DAO to RegistrationForm when it asks for the User object.

As far as that post on the Spring forum is concerned, you'll notice that it never received an answer. It's not a good source to take inspiration from.

Note that I'm not saying that desiring to autowire beans into a form back object is a bad idea, I'm just saying that Spring doesn't do that.

不羁少年 2025-01-12 01:05:30

如果您在模型上使用@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
{
   ...
}

It would work if you use the @Configurable annotation on your model, and this aspectJ configuration on your gradle file:

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
    )
}

In this way aspectJ will generate code that does the auto wiring.

@Configurable
public class RegistrationForm
{
   ...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文