Showing posts with label jsf. Show all posts
Showing posts with label jsf. Show all posts

Monday, December 11, 2017

ERROR: java.lang.IllegalStateException: getOutputStream() has already been called for this response

最近遇到一個問題超難搞的,就是這個︰
SEVERE: Servlet.service() for servlet [jsp] in context with path ... threw exception [java.lang.IllegalStateException: getOutputStream() has already been called for this response] with root cause
at org.apache.catalina.connector.Response.getWriter(Response.java:678)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:213)
at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:194)
at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:126)
at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:80)

就是用JSP直接打開一個系統存在的PDF文件這麼簡單,但卻弄了很久也沒解決。
打開PDF的方法可參考這個︰Displaying pdf in jsp

其實JSP是打開了PDF文件,但同時JSF請求了getWriter,而getOutputStream被JSP用了,所以JSF無法使用getWriter而報錯。

暫時方法找不到,先不管了。

Friday, July 22, 2016

JSF, AJAX: 在遞交ajax到後台處理, 再返回參數到javascript

在新增一個ajax的event後想要在後台處理一些邏輯,但是後台的變量並沒有在ajax完全執行後才回傳,導致無法馬上彈出提示信息。

問題︰我想要做的是下拉式選單的項目選擇後,到後台執行selectResult,其中會改變一個變量叫isSameResult,在oncomplete時把參量放到checkSameService的javascript函數中再做處理。

//-----**index.jsf**-----
<p:autoComplete ...>
 <p:ajax event="itemSelect" listener="#{bean.selectResult}" update="..." oncomplete="checkSameService(#{bean.isSameResult});"/>
</p:autoComplete>

<script>
function checkSameService(result) {
 alert(result);
}
</script>

//-----**Bean.java**-----
public void selectSerResult(SelectEvent event) {
 isSameResult = true;
}

雖然selectResult是處理完,變量也更新了(isSameResult由false變為true),但傳到javascript時卻未更新(仍然是false)。

解決方案︰上網找了一陣子發現可以從後台把參數放入javascript︰

//-----**index.jsf**-----
<p:autoComplete ...>
 <p:ajax event="itemSelect" listener="#{bean.selectResult}" update="..." oncomplete="checkSameService(xhr, status, args);"/>
</p:autoComplete>

<script>
function checkSameService(xhr, status, args) {
 alert(args.isSame);
}
</script>

//-----**Bean.java**-----
public void selectSerResult(SelectEvent event) {
 isSameResult = true;
 RequestContext context = RequestContext.getCurrentInstance();
        context.addCallbackParam("isSame", isSameResult );
}

然後就可以成功在完成處理後把結果寄回到javascript了。