Cdi
JSF 2.3.0以降、標準の
@ManagedBean
アノテーション
@ManagedBean
非推奨になりました。 つまり フォームからJavaコードにアクセスするには、プロジェクトCDI(Context and Dependency Injection)-Weldに追加する必要があります。
pom.xml
ファイルに
pom.xml
追加します。
<dependencies> ... <dependency> <groupId>org.jboss.weld.servlet</groupId> <artifactId>weld-servlet</artifactId> <version>2.4.3.Final</version> </dependency> </dependencies>
ファイル
/src/main/webapp/WEB-INF/beans.xml
作成します。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="all"> </beans>
悪いアドバイス
ファイル
/src/main/webapp/WEB-INF/jetty-env.xml
作成します。
<?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure.dtd"> <Configure id="webAppCtx" class="org.eclipse.jetty.webapp.WebAppContext"> <Call name="prependServerClass"> <Arg>-org.eclipse.jetty.server.handler.ContextHandler</Arg> </Call> <Call name="prependServerClass"> <Arg>-org.eclipse.jetty.servlet.FilterHolder</Arg> </Call> <Call name="prependServerClass"> <Arg>-org.eclipse.jetty.servlet.ServletContextHandler</Arg> </Call> <Call name="prependServerClass"> <Arg>-org.eclipse.jetty.servlet.ServletHolder</Arg> </Call> <New id="BeanManager" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg> <Ref id="webAppCtx"/> </Arg> <Arg>BeanManager</Arg> <Arg> <New class="javax.naming.Reference"> <Arg>javax.enterprise.inject.spi.BeanManager</Arg> <Arg>org.jboss.weld.resources.ManagerObjectFactory</Arg> <Arg/> </New> </Arg> </New> </Configure>
ファイル
/src/main/webapp/WEB-INF/web.xml
追加します。
<web-app ... <resource-env-ref> <resource-env-ref-name>BeanManager</resource-env-ref-name> <resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type> </resource-env-ref> ... </web-app>
@ManagedBean
代わりに
@ManagedBean
が機能するようになりました。 CDIは良好であり、JSF 2.3.0以降重要であると考えると、JSFのCDIは意図された目的に使用され、JSFに直接関連しないことを理解する価値があります。
もうCDIには戻りません!
FormDataおよびFormCtrlクラス
それでは、いくつかのコードを書きましょう。 2つのクラスが必要になります-最初にデータを送信し、2番目にこのデータを処理する関数があります。
リトリート
実装の観点からは、フォームのロジックを2つの別々のクラスに分ける必要はありませんが、これはテストの観点とアーキテクチャの観点の両方から「正しい」です。
データ
/src/main/java/ru/habr/FormData.java
:
package ru.habr; import javax.enterprise.context.RequestScoped; import javax.inject.Named; @Named @RequestScoped public class FormData { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
ハンドラー
/src/main/java/ru/habr/FormCtrl.java
:
package ru.habr; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.inject.Named; @Named @RequestScoped public class FormCtrl { @Inject FormData formData; public String doAction() { // ... System.out.println(formData.getUsername()); System.out.println(formData.getPassword()); return null; } }
FormData
ですべてが明確な場合、
FormData
FormCtrl
詳しく見る価値
FormCtrl
ます。
-
@Inject
おかげで、フォームデータはformData
フィールドのハンドラークラスで利用できます。 - 「ハンドラーメソッドは文字列を返す必要がある」という論文に固執することをお勧めしますが、これは必須ではありません。 この文字列は、後でナビゲーションで使用されますが、後で詳しく説明します。
形
ここではすべてがシンプルです! ファイル
/src/main/webapp/index.xhtml
追加します。
<h:body> ... <h:form id="habrForm"> <h:inputText value="#{formData.username}"/><br/> <h:inputSecret value="#{formData.password}"/><br/> <h:commandButton action="#{formCtrl.doAction}" value="Send"> </h:commandButton> </h:form> </h:body>
実行:
mvn jetty:run
確認:
http://127.0.0.1:8080/
:
http://127.0.0.1:8080/
:
http://127.0.0.1:8080/
アヤックス
それは2017年であり、フォームはまだAJAXなしです!
/src/main/webapp/index.xhtml
ファイル
/src/main/webapp/index.xhtml
、いくつかの変更を行います。
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core"> ... <h:body> ... <h:inputText value="#{formData.username}"/><br/> <h:inputSecret value="#{formData.password}"/><br/> <h:commandButton action="#{formCtrl.doAction}" value="Send"> <f:ajax execute="@form" render="@form"/> </h:commandButton> </h:body> </html>
変更点:
-
xmlns:f="http://xmlns.jcp.org/jsf/core"
タグライブラリ定義を追加xmlns:f="http://xmlns.jcp.org/jsf/core"
これがなければ、AJAXを実装できますが、ペンでそれを処理する必要があります。これは長くて恩知らずです。 -
h:commandButton
内で<f:ajax execute="@form" render="@form"/>
。execute
-サーバーに送信する必要があるもの(フォーム全体/すべてのフォームフィールド)を示しrender
-AJAX実行後にサーバーから更新する必要があるものを示します。
f:ajax
については、個別に記述できます。 これで、ページの現在のフォームだけでなく、ページの任意の要素を送信/更新できることを知っているだけで十分です。
あとがき
プロジェクトの機能はまだ非常に控えめですが、私は続けます!