<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"> <h:form> <h:inputText value="test"></h:inputText> <!-- <h:inputText value="yorum içinde"></h:inputText> --> </h:form> </html>Ancak bu sayfa çalıştırıldığında yorum içinde yazılanlar sayfanın kodunda görünecektir. Yorum içindeki hiç bir şey sayfa kodunda gözülmesin istenirse aşağıdaki gibi bir parametre eklenmelidir. web.xml'e aşağıdaki gibi ekleme yapılabilir :
<context-param> <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name> <param-value>true</param-value> </context-param>JSF'nin eski versiyonlarında facelets.SKIP_COMMENTS şeklinde kullanılır. FACELETS_SKIP_COMMENTS eklendiğinde tüm yorumlar gözükmez. Bu durum kod içinde gelitiricilerin yorumlarının da sayfanın kodunun gözükmeyeceği anlamına gelir. FACELETS_SKIP_COMMENTS yerine ui:remove elementi de kulanılabilir :
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets"> <h:form> <h:inputText value="test"></h:inputText> <ui:remove> <h:inputText value="yorum içinde"></h:inputText> </ui:remove> </h:form> </html>
Aşağıdaki örnekte kullanıcıya google map gösteriyoruz. Kullanıcı marker'ı sürükleyerek istedediği bir konumu seçmesini sağlıyoruz :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets"> <h:head> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> <script type="text/javascript"> var geocoder = new google.maps.Geocoder(); function updateMarkerPosition(latLng) { document.getElementById('testform:info').innerHTML = [ latLng.lat(), latLng.lng() ].join(', '); document.getElementById('testform:infoLatitude').value = latLng.lat(); document.getElementById('testform:infoLongitude').value = latLng.lng(); } function initialize() { var latLng = new google.maps.LatLng(41.00554818815703, 29.036333984374778); var map = new google.maps.Map(document.getElementById('mapCanvas'), { zoom: 8, center: latLng, mapTypeId: google.maps.MapTypeId.ROADMAP }); var marker = new google.maps.Marker({ position: latLng, title: 'Point A', map: map, draggable: true }); google.maps.event.addListener(marker, 'dragend', function() { updateMarkerPosition(marker.getPosition()); }); } google.maps.event.addDomListener(window, 'load', initialize); </script> <style> #mapCanvas { width: 400px; height: 400px; } </style> </h:head> <body> <h:form id="testform"> <div id="mapCanvas"></div> <h:outputText id="info" value="Koordinarlar Buraya Yazılacak" /> <h:inputHidden value="#{testBean2.latitude}" id="infoLatitude"/> <h:inputHidden value="#{testBean2.longitude}" id="infoLongitude"/> <h:commandButton action="#{testBean2.submit}" value="Ok" /> </h:form> </body> </html>
Java Bean kısmı ise sadece latitude ve longitude şeklinde iki özelliği vardır ve submit edildiğinde bu değerleri ekrana basmaktadır :
@ManagedBean @SessionScoped public class TestBean2 { String latitude; String longitude; public String getLatitude() { return latitude; } public void setLatitude(String latitude) { this.latitude = latitude; } public String getLongitude() { return longitude; } public void setLongitude(String longitude) { this.longitude = longitude; } public String submit(){ System.out.println("latitude:"+latitude); System.out.println("longitude:"+longitude); return ""; } }
Google map varsayılan olarak İstanbul ile açılacaktır. Marker drag işlemi tamamlandığında updateMarkerPosition fonksiyonu çağrılacak ve infoLatitude ve infoLongitude hidded form değerleri set edilir.
import java.util.Arrays; import java.util.List; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.convert.Converter; import javax.faces.convert.FacesConverter; @FacesConverter(value = "com.fibiler.jsf.converter.ListConverter") public class ListConverter implements Converter{ @Override public Object getAsObject(FacesContext context, UIComponent component, String value) { String[] values=value.split(","); return Arrays.asList(values); } @Override" public String getAsString(FacesContext context, UIComponent component, Object value) { List<String> list=(List)value; String joined = String.join(",", list); return joined; } }Gelen değer , ile parçalanıp listeye çevrilmekte, ters olarak da gelen liste aralarına , eklenerek birleştirilmektedir. Aşağıdaki gibi bir bean ve xhtml ile kullanılabilir:
import java.util.ArrayList; import java.util.List; import javax.annotation.ManagedBean; @ManagedBean public class ListConverterTestBean { private List<String> items=new ArrayList<String>(); public ListConverterTestBean() { items.add("ITEM1"); items.add("ITEM2"); items.add("ITEM3"); } public List<String> getItems() { return items; } public void setItems(List<String> items) { this.items = items; } public void submit(){ for (String string : items) { System.out.println("item :" + string); } } }Bu bean aşağıdaki gibi kullanılabilir:
<h:form> <h:inputText value="#{listConverterTestBean.items}" converter="com.fibiler.jsf.converter.ListConverter"></h:inputText> <h:commandButton action="#{listConverterTestBean.submit}" value="Submit"></h:commandButton> </h:form>Görüldüğü gibi converter="com.fibiler.jsf.converter.ListConverter" ile converter verilmiştir.
public enum Test { ITEM1, ITEM2, ITEM3; }Bu enum kullanıldığı bean aşağıdaki gibi olsun :
import javax.faces.bean.ManagedBean; import javax.faces.model.SelectItem; @ManagedBean public class EnumBean { private Test selected; public Test[] getEnums(){ return Test.values(); } public SelectItem[] getEnumsAsSelectItem() { SelectItem[] items = new SelectItem[Test.values().length]; int i = 0; for(Test t: Test.values()) { items[i++] = new SelectItem(t, t.toString()); } return items; } public String submit(){ System.out.println("selected value : " + selected); return ""; } public Test getSelected() { return selected; } public void setSelected(Test selected) { this.selected = selected; } }getEnums() ile Enum değeleri dizi olarak verilmektedir. İstenirse getEnumsAsSelectItem() ile de SelectItem listesi olarak alınabilir.
<h:form> <h3>Enum Test 3</h3> <h:selectOneMenu value="#{enumBean.selected}"> <f:selectItems value="#{enumBean.enums}"></f:selectItems> </h:selectOneMenu> <h:commandButton action="#{enumBean.submit}" value="Submit"></h:commandButton> </h:form>Submit düğmesine basıldığında console'de basılan elementin değeri gösterilir.
public enum Test { ITEM1("item 1"), ITEM2("item 2"), ITEM3("item 3"); String title; Test(String title) { this.title = title; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }Eğer açılır listede title değerini göstermek istiyorsanız sayfada aşağıdaki gibi değişiklik yapabilirsiniz:
<h:selectOneMenu value="#{enumBean.selected}"> <f:selectItems value="#{enumBean.enums}" var="t" itemLabel="#{t.title}" itemValue="#{t}"></f:selectItems> </h:selectOneMenu>
<dependency> <groupId>java.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.0</version> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.faces</artifactId> <version>2.3.9</version> </dependency> <dependency> <groupId>javax.faces</groupId> <artifactId>javax.faces-api</artifactId> <version>2.3</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.enterprise</groupId> <artifactId>cdi-api</artifactId> <version>1.2<version> </dependency> <dependency> <groupId>org.jboss.weld.servlet</groupId> <artifactId>weld-servlet</artifactId> <version>2.2.9.Final</version> </dependency> <dependency> <groupId>javax.json</groupId> <artifactId>javax.json-api</artifactId> <version>1.1.4</version> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.json</artifactId> <version>1.1.4</version> </dependency>java.lang.ClassNotFoundException: javax.json.Json
import java.io.Serializable; import javax.faces.push.Push; import javax.faces.push.PushContext; import javax.faces.view.ViewScoped; import javax.inject.Inject; import javax.inject.Named; @Named @ViewScoped public class MessageBean implements Serializable { @Inject @Push private PushContext mypush; private String message; public void sendMessage() { mypush.send(message); } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }mypush, push enpoint'idir. sendMessage() yöntemi çağrıldığında gelen mesaj diğerler sayfalara gönderilir.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html> <html xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <h:head> <title>Socket</title> </h:head> <h:body> <h:form> <script> function myMessageListener(message) { alert(message); } </script> <f:websocket channel="mypush" onmessage="myMessageListener"/> <h:inputText id="pushMessage" value="#{messageBean.message}"/> <br/> <h:commandButton action="#{messageBean.sendMessage}" value="Send Message"/> </h:form> </h:body> </html>Yazı alanına mesajı yazıp Send Message düğmesine basılınca MessageBean'in sendMessage yöntemi çağrılır. Bu yöntemde socket açmış tüm sayfalara mesajı iletir.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html> <html xmlns:h="http://java.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <h:head> <title>Socket</title> </h:head> <h:body> <h:form> <script> function myMessageListener(message) { alert(message); } </script> <f:websocket channel="mypush" onmessage="myMessageListener"/> </h:form> </h:body> </html>
JSF'de "One or more resources have the target of 'head', but no 'head' component has been defined within the view" gibi bir hata alırsanız view içinde head etiketini h:head olarak değiştirmeniz gerekir.
Bir onay kutusuna tıklandığında sunucuya gidilmesi isteniyorsa aşağıdaki gibi yapılmalıdır :
<h:selectbooleancheckbox id=“approveId" value="#{XBean.xvalue}" onclick="submit();" immediate="true"
valueChangeListener="#{XBean.xValueChangeListener}"/>
Görüldüğü gibi click'leme işleminde form sunucuya gönderilmektedir. Validasyon'a takılmaması içinde immediate özelliği true yapılmıştır.
Sunuc tarafındaki xValueChangeListener fonksiyonu aşağıdaki gibidir :
public void checkedClicked(ValueChangeEvent event) {
// kod
}
<ui:repeat value="#{testBean.list}" var="item" varStatus="myVarStatus"> İndex Sayısı : #{myVarStatus.index} </ui:repeat>
import javax.faces.application.*; public class DomainResouceHandler extends ResourceHandlerWrapper { private ResourceHandler wrapped; public DomainResouceHandler(ResourceHandler wrapped) { this.wrapped = wrapped; } @Override public Resource createResource(final String resourceName, final String libraryName) { final Resource resource = super.createResource(resourceName, libraryName); return new ResourceWrapper() { @Override public String getRequestPath() { return "http://example.com/"+resource.getRequestPath(); } @Override public Resource getWrapped() { return resource; } }; } @Override public ResourceHandler getWrapped() { return wrapped; } }DomainResouceHandler sınıfı ResourceHandlerWrapper'dan extend edilmiş ve createResource method'u override edilmiştir.
<application> <resource-handler>com.done.rabbit.support.resource.DomainResouceHandler</resource-handler> </application>
package com.fibiler.test; import javax.faces.application.*; import javax.faces.context.*; import javax.servlet.http.*; public class CustomViewHandler extends ViewHandlerWrapper{ private ViewHandler wrappped; public CustomViewHandler(ViewHandler wrappped) { super(); this.wrappped = wrappped; } @Override public ViewHandler getWrapped() { return wrappped; } @Override public String getActionURL(FacesContext context, String viewId) { HttpServletRequest request=(HttpServletRequest)FacesContext. getCurrentInstance().getExternalContext().getRequest(); String url=request.getRequestURL().toString(); if(url==null){ return super.getActionURL(context, viewId); } return "http://www.example.com"+super.getActionURL(context, viewId); } }Yukarıdaki kodda getActionURL method'u override edilmiş ve action URL'inin başına http://www.example.com eklenmiştir.
<application> <view-handler>com.fibiler.test.CustomViewHandler</view-handler> </application>Bu işlemleri yaptıktan sonra /kayit/index.jsf sayfasına girip form elementinin action değerini kontrol ettiğinizde http://www.example.com//kayit/index.jsf değerini görmeniz gerekir.
<h:outputText value="#{testBean.date}" > <f:convertDateTime pattern="dd.MM.yyyy HH:mm" timeZone="Turkey" locale="tr_TR"/> </h:outputText>testBean'deki date alanı, Türkiye saatine göre dd.MM.yyyy HH:mm şeklinde formatlı gözükür.
protected ResourceBundle getBundle() { if (bundle == null) { FacesContext context = FacesContext.getCurrentInstance(); bundle = context.getApplication().getResourceBundle(context, "msg"); } return bundle; } protected String getMessage(String key, String defaultValue) { String result = null; try { result = getBundle().getString(key); } catch (MissingResourceException e) { return defaultValue; } return result; }gertMessage metoduna key ile resources dosyasından desteklenen Local'e göre bir değer alınabilir.
protected String getMessage(String key, String defaultValue, String... parameters) { String result = null; try { result = getBundle().getString(key); if(result!=null){ return MessageFormat.format(result, parameters); }else{ return result; } } catch (MissingResourceException e) { return defaultValue; } }
<input type="text" id="inputJson" value="" style="display:none"/> <button type="button" class="button" id="copy-button" data-clipboard-target="#inputJson">Copy To Clipboard</button> <br/> <h:outputText id="inputTextPretty" value="#{inventoryBean.pretty}" style="white-space: pre-wrap;"></h:outputText> <h:outputScript name="clipboard.min.js" library="js"></h:outputScript> <script> var clipboard = new ClipboardJS('.button', { text: function() { return JSON.stringify(#{testBean.json}); } }); </script>
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.0</version> </dependency> <dependency> <groupId>javax.faces</groupId> <artifactId>javax.faces-api</artifactId> <version>2.3</version> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.faces</artifactId> <version>2.3.9</version> </dependency> <dependency> <groupId>javax.enterprise</groupId> <artifactId>cdi-api</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.jboss.weld.servlet</groupId> <artifactId>weld-servlet</artifactId> <version>2.4.8.Final</version> </dependency>Ardından CDI için WEB-INF için beans.xml eklenir :
<?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_2_0.xsd" bean-discovery-mode="all" version="2.0"> </beans>Ardından Tomcat 9 için META-INF altında context.xml eklenir :
<Context> <Resource name="BeanManager" auth="Container" type="javax.enterprise.inject.spi.BeanManager" factory="org.jboss.weld.resources.ManagerObjectFactory"/> </Context>web.xml'e aşağıdaki eklenir :
<listener> <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class> </listener> <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.xml'in son hali şu şekilde olmalı :
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0"> <display-name>JSF2_3Test</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.xhtml</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping> <listener> <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class> </listener> <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>Artık ortam hazır demektir. En basit olarak aşağıdaki gibi bir index.xhtml sayfası yapalım :
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"> <head> <meta charset="ISO-8859-9"/> <title>Merhaba JSF 2.3</title> </head> <body> <h:outputText value="Merhaba JSF 2.3"></h:outputText> </body> </html>Artık bu projeyi Tomcat 9'da çalıştırabiliriz. Bu projeyi çalıştırdığınızda aşağıdaki gibi hatalar alabilirsiniz :
Caused by: javax.faces.FacesException: Unable to find CDI BeanManager at com.sun.faces.application.ApplicationImpl.isJsf23(ApplicationImpl.java:2714) at com.sun.faces.application.ApplicationImpl.addELResolver(ApplicationImpl.java:549) at javax.faces.application.ApplicationWrapper.addELResolver(ApplicationWrapper.java:611) at org.jboss.weld.environment.servlet.jsf.WeldApplication.Bu durumda aşağıdaki gibi bir bean eklemek gerekir :(WeldApplication.java:72) at org.jboss.weld.environment.servlet.jsf.WeldApplicationFactory.getApplication(WeldApplicationFactory.java:46) at com.sun.faces.application.InjectionApplicationFactory.getApplication(InjectionApplicationFactory.java:88) at com.sun.faces.config.InitFacesContext.getApplication(InitFacesContext.java:153) at com.sun.faces.lifecycle.ClientWindowFactoryImpl. (ClientWindowFactoryImpl.java:63) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at java.lang.Class.newInstance(Class.java:442) at javax.faces.FactoryFinderInstance.getImplGivenPreviousImpl(FactoryFinderInstance.java:391) at javax.faces.FactoryFinderInstance.getImplementationInstance(FactoryFinderInstance.java:255) at javax.faces.FactoryFinderInstance.getFactory(FactoryFinderInstance.java:529) at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:292) at com.sun.faces.config.processor.FactoryConfigProcessor.verifyFactoriesExist(FactoryConfigProcessor.java:354) ... 33 more java.lang.IllegalStateException: Could not find backup for factory javax.faces.application.ApplicationFactory. at javax.faces.FactoryFinderInstance.getFactory(FactoryFinderInstance.java:541) at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:292) at com.sun.faces.config.InitFacesContext.getApplication(InitFacesContext.java:152) at com.sun.faces.config.ConfigureListener.contextDestroyed(ConfigureListener.java:367) at org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:4722) at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5395) at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:187) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1384) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1374) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:909) at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:841) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1384) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1374) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:909) at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.StandardService.startInternal(StandardService.java:421) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:930) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.startup.Catalina.start(Catalina.java:738) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:342) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:473)
package com.fibiler.jsf2_3.hello; import javax.faces.annotation.FacesConfig; import javax.faces.annotation.FacesConfig.Version; @FacesConfig(version = Version.JSF_2_3) public class ConfigurationBean { }Bunu eklendikten sonra tomcat 9'u çalıştırırsanız hata gelmeyecektir. Hatanız sebebi projenizde bir bean olmamasıdır. Yukarıdaki ConfigurationBean'i eklemek yerine aşağıdaki gibi bir bean yapıp onu kullanalım:
import javax.inject.Named; @Named public class HelloBean { private String message="Merhaba JSF 2.3"; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }Sayfa şu şekilde olacak :
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"> <head> <meta charset="ISO-8859-9"/> <title>Merhaba JSF 2.3</title> </head> <body> <h:outputText value="#{helloBean.message}"></h:outputText> </body> </html>Artık proje hata vermeyecektir.
<dependency> <groupId>jakarta.faces</groupId> <artifactId>jakarta.faces-api</artifactId> <version>3.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>jakarta.faces</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>5.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>jakarta.servlet.jsp</groupId> <artifactId>jakarta.servlet.jsp-api</artifactId> <version>3.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>jakarta.el</groupId> <artifactId>jakarta.el-api</artifactId> <version>4.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.jboss.weld.servlet</groupId> <artifactId>weld-servlet-shaded</artifactId> <version>4.0.0.Final</version> </dependency>Tomcat 9, Jakarta EE 9'u desteklemektedir. Bu nedenle Jakarta kullanılmaktadır. Weld kütüphanesi CDI için eklenmektedir. CDI için META-INF klasörü altında context.xml eklenir:
<Context> <Resource name="BeanManager" auth="Container" type="jakarta.enterprise.inject.spi.BeanManager" factory="org.jboss.weld.resources.ManagerObjectFactory" /> </Context>Ardından WEB-INF altına boş bir beans.xml dosyası konulur:
<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_3_0.xsd" bean-discovery-mode="all"> </beans>Web.xml aşağıdaki gibi olsun :
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0"> <display-name>web</display-name> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>jakarta.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping> </web-app>faces-config.xml ise aşağıdaki gibidir :
<?xml version="1.0" encoding="UTF-8"?> <faces-config 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/web-facesconfig_3_0.xsd" version="3.0"> </faces-config>Artık bir Bean yaratabiliriz :
package com.test; import jakarta.inject.Named; @Named public class HelloBean { private String message="Merhaba JSF 3.0"; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }Bu bean'i kullanan bir sayfa yapalım :
<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"> <h:head> <title>Hello JSF 3.0</title> </h:head> <h:body> <h1>#{helloBean.message}</h1> </h:body> </html>