2

私は現在 JSF を使用していますが、古くて不機嫌な php-dev であるため、常にリクエストの GET パラメータを台無しにします。(PHP では、$_GET["paramname"]Array.

今、私はユーザー管理システムに取り組んでいます。(CRUD) 通常、編集/削除などのオプションを使用して、利用可能なすべてのユーザーのリストを使用します。http:\\localhost\editUser.xhtml?userId=5編集リンクは、たとえばを指しています。

UserEditController基本的にユーザーエンティティを保持し、更新を呼び出すコントローラーも呼び出されます。

したがって、このコントローラー内で、@PostConstructアノテーションを使用して、ID 5 のユーザーを DataService からロードし、プロパティ内に保存しています。

問題は次のとおりです: Wenn が -Phase に PostConstruct-Method を入力するとAPPLY_REQUEST_VALUES、Faces Context のリクエスト パラメータ マップにアクセスできません (userId に対して null が返されます)

コントローラー (簡略化):

@Named
@RequestScoped
UserEditController{


@Inject
private UserDataService userDataService;

private User currentUser;

@PostConstruct
public void initValues(){
    String id = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("userId");

    this.currentUser = userDataService.getUserById(id);
}

public String saveCurrentUser(){
    userDataService.updateUser(this.currentUser);
    return "userManagement"; //return to overview after saving
}

//getter and setter
}

これは意図したとおりに機能します。すべてのフォーム フィールドが、ユーザーのプロパティなどにバインドされるようになりました#{userEditController.currentUser.forename}

アクション属性の保存ボタンを追加しました{userEditController.saveCurrentUser()}

ただし、スクリプトは -Phase に入り、APPLY_REQUEST_VALUESUserEditController の initValues が再度呼び出されます。

  • RequestParameterMap にアクセスしようとすると、nullpointer 例外が発生します。
  • そして明らかに、保存する前にユーザーをリロードしたくありません:-)

これはばかげた質問のように聞こえますが、物事を処理するために PHP スタイルと JSF スタイルの間で混乱していると思います。

任意のヘルプをいただければ幸いです。

4

2 に答える 2

2

ユーザー (またはユーザー ID) を BackingBean に渡す一般的な方法は、次のいずれかのオプションを使用することです。

http://www.mkyong.com/jsf2/4-ways-to-pass-parameter-from-jsf-page-to-backing-bean/

主な問題は、あなたの豆が@RequestScoped. 編集ページで保存ボタンを押すと、新しいリクエストが送信されるため、リクエスト スコープ Bean の新しいインスタンスが作成されます。Bean を に変更するだけ@ViewScopedです。

より詳しい情報:

于 2012-11-13T15:46:26.973 に答える
0

ViewScoped に変更しようとしましたが、プロパティにアクセスするたびに Bean の「コンストラクターを呼び出す」ことになります...

その間、私は多くのことを試しましたが、何も期待どおりに機能しませんでした:

私がそれを機能させることができる唯一のケースは、コントローラーを「SessionScoped」に設定することです。しかし、「クリーニング」値を処理し、多くの不要な (初期化された) Bean を発生させる必要があるため、これは良いアプローチではないと思います...

周りで遊ぶための簡単なプロジェクトを作成しました。動作しているセッション スコープ バージョンを次に示します。しかし、スコープを変更すると、保存ボタンを押すときに現在のユーザーを「リロード」する必要があります。そして、リクエストパラメーターにアクセスできないと、それを達成する方法がわかりません。

(「フォーム」でユーザーIDを再度渡そうとしましたが、「初めて」IDを渡すのに問題があります)

これが私のサンプルです。(ゲッターとセッターは利用可能であり、簡潔にするために言及されていません)

ユーザークラス:

public class User {

   private String firstname;
   private String lastname;

   public User (String f, String l){
       this.firstname = f;
       this.lastname = l;
   }
}

DBシミュレーター:

@Named("dbSimulator")
@SessionScoped
public class DBSimulator implements Serializable {

/**
 * 
 */
private static final long serialVersionUID = 659826879566280911L;

private Map<String, User> data;

public DBSimulator() {
    //Load data
    User u1 = new User("Mickey", "Maus");
    User u2 = new User("Peter", "Pan");

    this.data = new HashMap<String, User>();
    this.data.put("Mickey", u2);
    this.data.put("Max", u1);
}

public List<User> getUserList(){
    List<User> l = new LinkedList<User>();

    for (Map.Entry<String, User> user : data.entrySet()) {
        l.add(user.getValue());
    }

    return l;

}

public void saveUser(User user){
    this.data.put(user.getFirstname(), user);
}
}

ユーザー管理コントローラー:

@Named
@SessionScoped
public class UserManagementController implements Serializable {

/**
 * 
 */
private static final long serialVersionUID = -4300851229329827994L;

@Inject
private DBSimulator dbSimulator;

private List<User> users;

public UserManagementController() {
    System.out.println("UserManagementController:construct()");
}

@PostConstruct
public void LoadUsers(){
    this.setUsers(this.dbSimulator.getUserList());
}
}

ユーザー編集コントローラー

@Named
@SessionScoped
public class UserEditController implements Serializable{

/**
 * 
 */
private static final long serialVersionUID = 1867483972880755108L;

@Inject
private DBSimulator dbSimulator;

private User user;

public UserEditController() {
    System.out.println("UserEditController:construct()");
}

public String activateUser(User user){
    this.setUser(user);
    System.out.println("setting User");
    return "userEdit";
}

public String save(){
    //Save user
    this.dbSimulator.saveUser(user);
    return "userManagement";
}

}

最後に両方の XHTML ファイル: UserManagement.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">

<h:head>
<title>Test</title>
</h:head>
<h:body>
    <h:outputText value="Select user to edit." />

    <h:dataTable value="#{userManagementController.users}" var="user">
        <h:column>
            <f:facet name="header">Firstname</f:facet>
            <h:outputText value="#{user.firstname}" />
        </h:column>

        <h:column>
            <f:facet name="header">Lastname</f:facet>
            <h:outputText value="#{user.lastname}" />
        </h:column>

        <h:column>
            <f:facet name="header">Options</f:facet>
            <h:form>
                <h:commandLink action="userEdit" actionListener="#{userEditController.activateUser(user)}" value="edit user" />
            </h:form>
        </h:column>
    </h:dataTable>
</h:body>
</html>

UserEdit.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">


<h:head>
<title>Test</title>
</h:head>
<h:body>
    <h:form>
        <h:inputText value="#{userEditController.user.firstname}"></h:inputText>
        <br /><br />
        <h:inputText value="#{userEditController.user.lastname}"></h:inputText>
        <br /><br />
        <h:commandButton value="save" action="#{userEditController.save}"></h:commandButton>
    </h:form>

</h:body>
</html>

ps .: 誰にも私のコードを「修正」してほしくありません - しかし、完全な例があれば誰かが見ることができるかもしれません:)

ViewScoped Bean を操作すると、次のコンソール出力が生成されます。

[pageload]
12:07:49,126 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:07:49,334 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:07:49,341 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
[edit click]
12:08:35,410 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,411 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,412 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,413 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,414 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,414 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,415 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,416 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,416 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,417 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,476 INFO  [stdout] (http--0.0.0.0-8090-3) UserEditController:construct()
12:08:35,478 INFO  [stdout] (http--0.0.0.0-8090-3) setting User
12:08:35,494 INFO  [stdout] (http--0.0.0.0-8090-3) UserEditController:construct()
12:08:35,497 INFO  [stdout] (http--0.0.0.0-8090-3) UserEditController:construct()

(ViewScoped) UserEditController はユーザーの設定後に 2 回再構築されているため、明らかにユーザーはもう設定されていません...

于 2012-11-14T11:11:08.133 に答える