在SessionScoped bean(CDI,JSF)中更新来自用户POST的数据的最优雅方式

时间:2014-06-18 13:07:10

标签: jsf cdi

我有一个SessionScoped CDI-bean来保存用户数据。

@SessionScoped
public class UserData {
  private String name;
  private String city;
  .. several other attributes
}

用户想要以表格(JSF)更新他的数据。因此,我使用“FrontendModel”来封装所有属性。

FrontendModel

@RequestScoped
@Named
public class UserDataFrontendModel {
  private String name;
  private String city;
  .. several other attributes
}

JSF页:

<h:inputText id="username" value="#{userDataFrontendModel.name}"/>
<h:inputText id="city" value="#{userDataFrontendModel.city}"/>

控制器

@RequestScoped
@Named
public class UserDataController {

  @Inject
  private UserDataFrontendModel userDataFrontendModel;

  @Inject
  private UserData userData;

  public String updateUserData() {
      userData.setName(userDataFrontendModel.getName());
      userData.setCity(userDataFrontendModel.getCity());
      return null;
  }

@PostConstruct
private void initUserDataFrontendModel() {
  if(isUpdate) {
     userDataFrontendModel.setName(userData.getName());
     userDataFrontendModel.setCity(userData.getCity());
  }
}

这是否过度工程?!我不想直接在控制器中拥有所有用户的属性。 UserDataFrontendBean应该是CDI-bean吗?有没有更简单的方法来做我想要的?我不能直接使用我的UserData对象,可以吗?

1 个答案:

答案 0 :(得分:1)

最好将UserDataController声明为@Named @SessionScoped,并在那里设置UserData字段。由于UserDataController将存储在会话范围内,因此其所有字段也将在会话范围内。使用这种方法,您根本不需要UserDataFrontendModel课程。

@Named
@SessionScoped
public class UserDataController {
    @Inject
    private UserData userData;
    @PostConstruct
    private void initUserDataFrontendModel() {
        userData = new UserData();
    }
    public void updateUserData() {
         //logic to update the data in database or something
    }
}

然后只需将UserData中的数据直接绑定到视图中的元素:

<h:form>
    <h:inputText value="#{userDataController.userData.name}" />
    <h:inputText value="#{userDataController.userData.city}" />
    <h:commandButton value="Update User Data"
        action="#{userDataController.updateUserData}" />
</h:form>