2012-06-08 19 views
7

tôi đang nhận được lỗi sau trên ứng dụng tải trang khởi động của tôi:không thể tạo phiên sau khi phản ứng đã được cam kết

SEVERE: Error Rendering View[/HomeTemplate/equityVolume.xhtml] 
javax.el.ELException: /HomeTemplate/equityVolume.xhtml @70,78 value="#{equityBean.scripList}": java.lang.IllegalStateException: PWC3999: Cannot create a session after the response has been committed... 

    Caused by: java.lang.IllegalStateException: PWC3999: Cannot create a session after the response has been committed... 

tôi nhận được lỗi này khi tôi áp dụng css để trang chủ của tôi, lỗi biến mất khi tôi loại bỏ template css (nhưng tôi muốn aplly mẫu css) sau đây là đoạn mã đậu gây ra lỗi (tìm thấy bằng cách gỡ lỗi)

public List<MasterScrip> getScripList() { 
    HttpServletRequest req=(HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest(); //error line 
    HttpSession session=req.getSession(); 
    type=(String)session.getAttribute("type");... 

mã xhtml:

<h:body> 
    <ui:composition template="commonClientLayout.xhtml"> 

    <ui:define name="contentFile"> 
      <div id="content"> 
    <h:form id="frm">... 

khi tôi xóa thành phần ui: bố cục và xác định thẻ (ví dụ: nếu tôi không áp dụng css), sau đó tôi không nhận được lỗi này. điều gì có thể gây ra lỗi này và làm cách nào để giải quyết?

chỉnh sửa:

@PostConstruct 
void initialiseSession() { 
    if(type!=null) 
     { 
     if(type.equalsIgnoreCase("losers")) 
     { 
     scripList=new ArrayList<MasterScrip>(); 
     scripList=getScripByPriceLosers(exchange); 
     // return scripList; 
     } 
     else if(type.equalsIgnoreCase("gainers")) 
     { 
     scripList=new ArrayList<MasterScrip>(); 
    scripList=getScripByPriceGainers(exchange); 
     // return scripList; 
     } 
     else 
     { 
      scripList=new ArrayList<MasterScrip>(); 
    scripList=getScripByVolumeType(exchange); 
    // return scripList; 
     } 
     } 
     else 
     { 
      scripList=new ArrayList<MasterScrip>(); 
    scripList=getScripByVolumeType(exchange); 
     } 

} 

    public List<MasterScrip> getScripList() { 
     return scripList; 

    } 

sửa lại:

SEVERE: Error Rendering View[/equityVolume.xhtml] 
java.lang.IllegalStateException 
    at org.apache.catalina.connector.ResponseFacade.setBufferSize(ResponseFacade.java:275)... 

chỉnh sửa: web.xml

<?xml version="1.0" encoding="UTF-8"?> 
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> 
    <context-param> 
     <param-name>javax.faces.PROJECT_STAGE</param-name> 
     <param-value>Production</param-value> 
    </context-param> 
    <context-param> 
     <param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name> 
     <param-value>65535</param-value> 
    </context-param> 

    <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> 
    <session-config> 
     <session-timeout> 
      30 
     </session-timeout> 

    </session-config> 
    <welcome-file-list> 
     <welcome-file>equityVolume.xhtml</welcome-file> 
    </welcome-file-list> 
    <security-constraint> 
     <display-name>Constraint1</display-name> 
     <web-resource-collection> 
      <web-resource-name>AdminTemplate</web-resource-name> 
      <description/> 
      <url-pattern>/AdminTemplate/*</url-pattern> 
     </web-resource-collection> 
     <auth-constraint> 
      <description/> 
      <role-name>admin</role-name> 
     </auth-constraint> 
    </security-constraint> 
    <security-constraint> 
     <display-name>Constraint2</display-name> 
     <web-resource-collection> 
      <web-resource-name>ClientTemplate</web-resource-name> 
      <description/> 
      <url-pattern>/ClientTemplate/*</url-pattern> 
     </web-resource-collection> 
     <auth-constraint> 
      <description/> 
      <role-name>client</role-name> 
     </auth-constraint> 
    </security-constraint> 
    <login-config> 
     <auth-method>FORM</auth-method> 
     <realm-name>DataRealm</realm-name> 
     <form-login-config> 
      <form-login-page>/equityVolume.xhtml</form-login-page> 
      <form-error-page>/errorpage.xhtml</form-error-page> 
     </form-login-config> 
    </login-config> 
    <security-role> 
     <description/> 
     <role-name>admin</role-name> 
    </security-role> 
    <security-role> 
     <description/> 
     <role-name>client</role-name> 
    </security-role> 
</web-app> 

Trả lời

6

Bạn không nên làm công việc kinh doanh trong getters. Làm điều đó trong bean (post) constructor để thay thế.

Vấn đề cụ thể của bạn là do bạn đang yêu cầu một trang tương đối lớn trên phiên trình duyệt mới, mà máy chủ HttpSession chưa được tạo và biểu thức EL #{equityBean.scripList} được tham chiếu tương đối muộn trong trang.

Bộ đệm phản hồi theo mặc định là 2KB và khi bộ đệm bị tràn do phản hồi lớn, thì nó sẽ được cam kết. Điều này có nghĩa là tất cả các tiêu đề phản hồi sẽ được gửi và đầu tiên ~ 2KB đầu ra HTML sẽ được gửi. Sau đó, sau thời điểm đó, biểu thức EL #{equityBean.scripList} sẽ được giải quyết trong đó bạn đang cố gắng để có được phiên. Nếu máy chủ HttpSession chưa được tạo tại thời điểm đó, thì máy chủ cần để đặt cookie trong tiêu đề phản hồi để duy trì cookie cho các yêu cầu tiếp theo. Nhưng đó là tất nhiên không thể nếu phản ứng đã được cam kết. Do đó ngoại lệ này.

Như đã nói, chỉ cần thực hiện công việc trong hàm tạo (đăng) của bean. Hoặc chỉ cần tiêm nó như là tài sản được quản lý.

@ManagedProperty("#{type}") 
private String type; 

Nếu ngoại lệ vẫn xảy ra, có lẽ bạn đang sử dụng một phiên bản cũ của cá móm mà bị lỗi như mô tả trong các vấn đề 22152277 mà là do trì hoãn quá cực của phiên "không cần thiết" sự sáng tạo. Điều này đã được sửa từ Mojarra 2.1.8. Vì vậy, nâng cấp lên nó hoặc mới hơn (hiện tại là 2.1.9) nên làm điều đó.


Không liên quan cho vấn đề cụ thể, logic getScripList() là bằng cách mùi. Nhưng đó là chủ đề cho một vấn đề/câu hỏi khác. Bạn có biết rằng bạn chỉ có thể truy cập thuộc tính phiên có tên "loại" trong EL là #{type} không? Bạn có biết rằng việc nhập khẩu javax.servlet.* thô trong lớp bean sao lưu JSF thường xuyên hơn cho thấy rằng bạn có thể làm việc sai và có thể có nhiều cách "JSF-ish" hơn để đạt được yêu cầu chức năng cụ thể không?

+0

cảm ơn vì đã giải thích. I đặt logic nghiệp vụ trong phương thức postConstruct, tôi vẫn gặp lỗi tương tự (xem câu hỏi đã chỉnh sửa). Tôi không thể có thêm bất kỳ thứ gì trong ứng dụng của mình nữa, tôi nên làm gì ?:( – z22

+0

Vì vậy, bean đơn giản là không được tham chiếu ở bất kỳ đâu trong trang? JSF impl/version nào bạn đang sử dụng? Một vấn đề tương tự đã được sửa trong Mojarra 2.1.8. Hoặc bạn có thể thay đổi và tăng kích thước bộ đệm phản hồi mặc định – BalusC

+0

có nó được tham chiếu trước đó trong trang xhtml – z22

3

Tôi không biết khung công tác web này (là JSF?) Nhưng đây là những gì sẽ xảy ra. XHTML của bạn bắt đầu hiển thị đầu ra và một vài ký tự đã được gửi đến trình duyệt. Điều này ngụ ý rằng toàn bộ tiêu đề đã được gửi là tốt.

Một nơi nào đó ở giữa mẫu của bạn bạn đang gọi #{equityBean.scripList} (BTW typo) mà biến cuộc gọi:

HttpSession session=req.getSession(); 

Phương pháp này sẽ tạo ra phiên HTTP nếu không tồn tại. ID phiên phải được gửi cùng với phản hồi (sử dụng cookie hoặc viết lại URL) trở lại máy khách để xác định lại phiên trên các yêu cầu tiếp theo. Tuy nhiên, vì các tiêu đề phản hồi đã được gửi đi, nên thùng chứa servlet không có khả năng gửi lại session id - và ném một ngoại lệ tránh các vấn đề lớn hơn.

Làm cách nào bạn có thể giải quyết vấn đề này? Có vẻ như bạn đang hiển thị trang lần đầu tiên khi hoàn toàn không có phiên nào được liên kết với yêu cầu. Bạn có thể tránh tạo phiên:

HttpSession session=req.getSession(false); //false here! 
if(session != null) { 
    type=(String)session.getAttribute("type"); 
} 
//handle the case when session or type attribute weren't there 

Cách tiếp cận khác là chủ động tạo phiên trước khi bạn chuyển quyền kiểm soát cho chế độ xem. Tuy nhiên, bạn vẫn phải kiểm tra thuộc tính type cho null.

+0

đã dùng thử, tôi vẫn gặp lỗi ... tôi không thể áp dụng css: ( – z22

Các vấn đề liên quan