Posts Tagged ‘ JSF

Enable Autocomplete JSF 1.2 in eclipse

หลังจากหันเหชีวิตไปจับ Netbeans มาได้หลายเดือนถึงคราวกลับมาใช้ Eclipse เจ้าเก่าแต่ดันเจอปัญหาไม่สามารถใช้ Autocomplete ใน JSF 1.2 (.xhtml) ได้ แต่ถ้าเป็นไฟล์ .jsp สามารถใช้ได้ปกติ เมือเกิดเหตุการณ์เช่นนี้แทบอยากคลานกลับไปหา Netbeans แต่เดียวก่อนครับ ในฐานะโปรแกรมเมอร์ เราไม่ควรยอมแพ้อะไรง่ายๆครับ สู้ๆ ว่าแล้วก็สอบถาม อ.google ก็คำตอบมาว่า ให้ไปที่

Window > Preferences > General > Content Types > Text > JSP > Add (*.xhtml)

แสดงรูปดังต่อไปนี้

จากนั้นทดลองใช้งานดู โอ้ๆ มันยอดมาก

แหล่งข้อมูล
Eclipse autocomplete (content assist) with facelets (jsf) and xhtml
Facelets and XSD-converted TLDs for Eclipse

JSF : java.lang.IllegalStateException: Cannot create a session after the response has been committed

เจอปัญหาในการใช้งาน JSF 2.1 และ RichFace 4.2 แล้วเกิดข้อผิดพลาดดังนี้

Jun 26, 2012 5:25:56 PM com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException
SEVERE: Error Rendering View[/index.xhtml]
java.lang.IllegalStateException: Cannot create a session after the response has been committed
	at org.apache.catalina.connector.Request.doGetSession(Request.java:2754)
	at org.apache.catalina.connector.Request.getSession(Request.java:2264)
	at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:899)
	at com.sun.faces.context.ExternalContextImpl.getSession(ExternalContextImpl.java:155)
	at javax.faces.context.ExternalContextWrapper.getSession(ExternalContextWrapper.java:396)
	at com.sun.faces.renderkit.ServerSideStateHelper.writeState(ServerSideStateHelper.java:175)
	at com.sun.faces.renderkit.ResponseStateManagerImpl.writeState(ResponseStateManagerImpl.java:122)
	at com.sun.faces.application.StateManagerImpl.writeState(StateManagerImpl.java:166)

ซึ่งในหน้า index.xhtml มี code ประมาณนี้

<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:ui="http://java.sun.com/jsf/facelets" 
                xmlns:rich="http://richfaces.org/rich" 
                template="/templates/index.xhtml">
    
    <ui:define name="title">RichFaces Sample</ui:define>
    <ui:define name="body">
        <h:panelGrid columns="1" columnClasses="cols" width="300">
            <h:form>
                <rich:panelMenu style="width:300px;" 
                                groupMode="client"
                                groupExpandedLeftIcon="triangleUp"
                                groupCollapsedLeftIcon="triangleDown" 
                                topGroupExpandedRightIcon="chevronUp"
                                topGroupCollapsedRightIcon="chevronDown" 
                                itemLeftIcon="grid">                    

                    <rich:panelMenuGroup label="Rich In Action">
                        <rich:panelMenuItem label="rich:popupPanel" action="rich/popup"/>
                        <rich:panelMenuItem label="rich:popupPanel [action]" action="rich/popup_action"/>
                        <rich:panelMenuItem label="rich:fileUpload" action="rich/upload"/>                        
                    </rich:panelMenuGroup>
                    <rich:panelMenuGroup label="Full Example">
                        <rich:panelMenuItem label="Full Example" action="rich/full-example"/>
                        <rich:panelMenuItem label="Converter" action="jsf/converter"/>
                        <rich:panelMenuItem label="Order Car" action="jsf/order-car"/>
                    </rich:panelMenuGroup>                      
                </rich:panelMenu>
            </h:form>
        </h:panelGrid>       
    </ui:define>    
</ui:composition>

ตอนแรกสงสัยว่าเกิดจาก ManageBean ไม่ได้ implement Serializable หรือเปล่าลองแก้แล้วก็ไม่หาย ลองลบ ออกแล้วรันใหม่ไม่เกิดข้อผิดพลาด สรุปว่่าปัญหาเกิดจาก จากการสอบถามข้อมูลจาก google ได้ความว่า ถ้ามีการใช้งาน PhaseListener จะเกิดข้อผิดพลาดแบบนี้ตอนเปิดใช้งานครั้งแรก หลังจาก start web server แล้ว วิธีแก้ไขคือ ให้ใส่

FacesContext.getCurrentInstance().getExternalContext().getSession(true);

ใน method public void beforePhase(PhaseEvent event) {} ดังนี้

public class SessionPhaseListener implements PhaseListener {
	public PhaseId getPhaseId() { 
		return PhaseId.RENDER_RESPONSE; 
	}
	public void afterPhase(PhaseEvent event) {
		//Implement
	}
 
	public void beforePhase(PhaseEvent event) {
		// we need to ask for the session early
		FacesContext.getCurrentInstance().getExternalContext().getSession(true);
	}
}

ลอง start server ใหม่อีกครั้งหายเป็นปลิดทิ้งๆๆๆๆๆๆ

แหล่งข้อมูล
[Richfaces 4] rich:panelMenu triggers IllegalStateException: Cannot create a session after the response has been committed

RichFaces : Component ID _viewRoot:status has already been found in the view.

ทดลองใช้ RichFaces แล้วต้องการให้แสดงสถานะแจ้งว่ากำลังทำงานอยู่ (Process Dialog) ซึ่งใน RichFaces นั้นมี Tag

<a4j:status />

ให้ใช้งานอยู่แล้ว เลยทดลองดังนี้

<a4j:status onstart="{Richfaces.showModalPanel('process-wait')};"
    onstop="{Richfaces.hideModalPanel('process-wait')};" />
<rich:modalPanel id="process-wait" width="250" height="100">
	<f:facet name="header">
		<h:outputText value="Processing" />
	</f:facet>
	<div align="center">
		<h:outputText value="Processing please wait..." /> <br>
	</div>
</rich:modalPanel>

พอทดลองรันแล้วเกิด Error ดังนี้

java.lang.IllegalStateException: Component ID _viewRoot:status has already been found in the view.  
	at com.sun.faces.util.Util.checkIdUniqueness(Util.java:724)
	at com.sun.faces.util.Util.checkIdUniqueness(Util.java:708)
	at com.sun.faces.application.StateManagerImpl.saveView(StateManagerImpl.java:129)
	at javax.faces.application.StateManager.saveSerializedView(StateManager.java:183)
	-
	-

Error ที่เกิดขึ้นเนื่องจากในหน้าจอ หรือ page นี้มีการใช้ tag จะไม่สามารถใช้ได้อีก วิธีการแก้ไข
1. ลบ Tag ที่ซ้ำออกแล้วสามารถใช้งานได้เลย
2. manual เปิด dialog เองในปุ่มที่ต้องการให้แสดง เช่น

<a4j:commandButton id="bt-action"
	value="Save" action="#{example.save}"
	onclick="{Richfaces.showModalPanel('process-wait')};"
	oncomplete="{Richfaces.hideModalPanel('process-wait')};" />

Update : 08/05/2012 สามารถใช้ tag หลายๆตัวในหน้าเดียวกันอ้างอิงจาก RichFaces Status โดยระบุ attribute “for” และกำหนด tag ครอบส่วนที่ต้องการให้เรียกใช้ เช่น

<a4j:region id="xx-yy">
     <a4j:commandButton id="bt-action"
	 value="Save" action="#{example.save}" />
</a4j:region>

<a4j:status for="xx-yy" onstart="{Richfaces.showModalPanel('id-here')};"
	onstop="{Richfaces.hideModalPanel('id-here')};" />