Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jsp 在JSF1.2中,从bean定义区域设置会导致getOutputStream中出现IllegalStateException_Jsp_Jsf_Servlets - Fatal编程技术网

Jsp 在JSF1.2中,从bean定义区域设置会导致getOutputStream中出现IllegalStateException

Jsp 在JSF1.2中,从bean定义区域设置会导致getOutputStream中出现IllegalStateException,jsp,jsf,servlets,Jsp,Jsf,Servlets,我试图了解这是如何发生的,以及如何解决它。 我有一个jsf请求bean,带有如下所示的jsp页面:(摘要) 最后,当会话启动时,调用此方法(向客户端发送文件) 我得到一个调用response.getOutputStream() 我不明白的是,如果未定义locale=“#{drcBean.userLocale}”,则不会发生这种情况。(也就是说,我省略了视图的locale标记,问题就消失了) 另一个证据是,我最终收到的文件是提到的JSP页面,我认为这意味着一个新页面以某种方式被发送,并中止了文件

我试图了解这是如何发生的,以及如何解决它。 我有一个jsf请求bean,带有如下所示的jsp页面:(摘要)

最后,当会话启动时,调用此方法(向客户端发送文件)

我得到一个调用
response.getOutputStream()
我不明白的是,如果未定义
locale=“#{drcBean.userLocale}”
,则不会发生这种情况。(也就是说,我省略了视图的
locale
标记,问题就消失了)

  • 另一个证据是,我最终收到的文件是提到的JSP页面,我认为这意味着一个新页面以某种方式被发送,并中止了文件发送。但是这与
    语言环境有什么关系呢

  • 另外,如果我使用
    而不是使用backingbean作为值,它也可以正常工作


如果您正试图将文件下载给用户,为什么还要担心语言环境

不管怎样,我不知道你为什么会得到非法辩论的例外。当您尝试使用已写入的OutputStream时,通常会发生这种情况

如果我使用以下jsp:

<%@ page import="uk.co.farwell.MyBean" %>

<f:view locale="en">
<%
MyBean bean = (DossierBean) pageContext.findAttribute ("bean");

bean.sendFile(response);
%>
</f:view>
我有一个非法的辩论例外。如果这是您遇到的错误,那么请尝试直接使用Servlet

public final class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        byte[] config = "foobar".getBytes();

        resp.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");

        resp.setContentType("application/rtf");
        resp.setContentLength(config.length());
        resp.getOutputStream().write(config.getBytes());
        resp.getOutputStream().flush();
        resp.getOutputStream().close();
    }
}

或类似的。这比使用jsp下载文件更可靠。

这个问题的真正解决方案是在加载jsp页面之前发送文件。 为此,我注册了一个phaselistener,并在JSP页面之前发送了该文件

public class DrcPhaseListener implements PhaseListener {

    @Override
    public void afterPhase(PhaseEvent pe) { 
              ..... send file here ....
        }
问题是,正如我所怀疑的,JSP页面已经开始向响应发送日期,当我试图从bean发送文件时,为时已晚。 上面的修复程序将强制在页面尚未开始加载的阶段发送文件,因此响应中没有写入任何内容。

您需要在操作方法的末尾调用,以防止JSF导航到页面(默认为提交表单的页面)


IllegalStateException的消息是什么?org.apache.myfaces.application.jsp.ViewResponseWrapper.getOutputStream(ViewResponseWrapper.java:115)上的java.lang.IllegalStateException听起来像JSF impl bug(但我从未见过)。您正在使用哪个impl和版本?尝试升级。Mojarra 1.2目前为1.2_15,相当成熟。MyFace 1.2.7。我认为问题源于这样一个事实,即在locale中使用EL表达式会导致它向响应写入一些内容,然后您无法再发送文件。通常,如果在调用getOutputStream()之前已经向响应发送了一些内容,那么您会得到一个IllegalArgumentException,但是有一条消息“getOutputStream已经被调用用于此响应”,但是您根本没有收到任何消息?非常感谢您的回答,但我认为我已经找到了解决此问题的真正答案。下面是详细信息。这气味很重。你到底是怎么要求这份文件的?通过提交表单并在bean的操作方法中调用它,对吗?这个黑客就是说,你在一个附加到JSP的getter方法中做这件事,而这个方法又是错误的。@BalusC实际上,bean是请求作用域,每个请求的“状态”都由URL参数决定。文件传输仅由URL参数的值决定,因此无需加载任何JSP页面。甚至“提交”按钮也会使用新的URL参数创建新请求。更有意义?那么,通过提交表单?好的,我发布了一个答案。问题是,在调用sendFile()之前,页面已经开始向响应发送数据,因此调用
responseComplete()
为时已晚,为什么会发生这种情况?这只有在使用某种getter方法hack而不是commandbutton/link操作调用它时才能解释。这几乎可以肯定是我脸上的一只虫子。
<%@ page import="uk.co.farwell.MyBean" %>

<f:view locale="en">
<%
MyBean bean = (DossierBean) pageContext.findAttribute ("bean");

bean.sendFile(response);
%>
</f:view>
public void sendFile(HttpServletResponse response) throws Exception {
    byte[] config = "foobar".getBytes();
    String clientFileName = "iphone.mobileconfig";

    BufferedInputStream input = null;
    BufferedOutputStream output = null;

    ByteArrayInputStream bais = new ByteArrayInputStream(config);
    input = new BufferedInputStream(bais);

    response.reset();
    response.setContentType("application/x-apple-aspen-config");
    response.setHeader("Content-Disposition", "attachment; filename=\"" + clientFileName + "\"");
    response.setContentLength((int) config.length);

    output = new BufferedOutputStream(response.getOutputStream(), 1024);

    byte[] buffer = new byte[1024];
    int length;
    while ((length = input.read(buffer)) > 0) {
        output.write(buffer, 0, length);
    }

    output.flush();
}
public final class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        byte[] config = "foobar".getBytes();

        resp.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");

        resp.setContentType("application/rtf");
        resp.setContentLength(config.length());
        resp.getOutputStream().write(config.getBytes());
        resp.getOutputStream().flush();
        resp.getOutputStream().close();
    }
}
public class DrcPhaseListener implements PhaseListener {

    @Override
    public void afterPhase(PhaseEvent pe) { 
              ..... send file here ....
        }
public void download() {
    sendFile();
    FacesContext.getCurrentInstance().responseComplete();
}