【问题标题】:spring interface as @ModelAttribute paramspring 接口作为@ModelAttribute 参数
【发布时间】:2012-08-25 04:17:31
【问题描述】:

我有带有方法的 UsersController:

@RequestMapping(value={"/new"}, method=RequestMethod.GET)
public String showCreationForm(@ModelAttribute User user){
    return "user_registration_form";
}

显示注册表单。我想在我的项目中保持模块化(在其他项目中使用这个控制器会很好),所以 User 是一个接口并且有它的实现 - UserImpl。问题是 Spring 无法实例化用户界面。有没有办法配置spring来使用一些默认的User实现?

【问题讨论】:

  • 为什么要让 Spring 实例化你的类? Spring 带来了 AOP 和 DI,如果你想使用它们,那么你应该创建一个 session-scoped 或 request-scoped bean。
  • @Modelattribute 为我做实例化。
  • 这能回答你的问题吗? Spring MVC ModelAttribute as Interface

标签: spring interface default implementation modelattribute


【解决方案1】:

您可以使用@ModelAttribute-annotated 方法提供一个要填充请求数据的对象:

@ModelAttribute
public User createUser() {
    return new UserImpl();
}

【讨论】:

  • 不是我想要的。我试图避免直接调用 UserImpl。一种想法是在控制器中使用接口 EmptyUserFactory。它的实现将被注入并用于检索 UserImpl 对象。但也许有更好的主意?
  • 我刚刚意识到我之前评论中的解决方案很糟糕。我会失去通过 @Valid 注释来验证用户的能力。
【解决方案2】:

创建一个最小实现接口的简单类。它与接口的想法相同,但它是一个类。它不包含您的任何逻辑或验证或其他任何内容。它只是接口的最简单实现,称之为UserSimple,它实现了你的接口。它被称为数据传输对象。

public class UserSimple implements User {
    String name;
    String address;
    //getters and setters only
}

添加一个转换器,将 UserImpl 的真实属性复制到 UserSimple 中。

@Component
public class ImplToSimpleConverter 
        implements Converter<UserImpl, UserSimple> {

    @Override
    public UserSimple convert(UserImpl source) {
        UserSimple target = new UserSimple();
        BeanUtils.copyProperties(source, target);
        return target;
    }
    
}

在处理程序中使用UserSimple

@RequestMapping(value={"/new"}, method=RequestMethod.GET)
public String showCreationForm(@ModelAttribute UserSimple user){
    return "user_registration_form";
}

这使您可以保持代码通用。要在不同的应用程序中使用相同的类,您只需添加不同的转换器即可。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-23
    • 2021-04-12
    • 2011-11-06
    • 2014-12-20
    • 1970-01-01
    • 2021-04-19
    • 1970-01-01
    • 2011-09-09
    相关资源
    最近更新 更多