如何在表单提交上提供文件下载后清除验证错误?

时间:2011-11-15 13:37:39

标签: validation jsf download

我有一个页面,其中有一个输入字段和一个按钮。单击该按钮可根据输入字段中输入的值生成PDF报告。我的问题在于输入字段需要一些特殊的格式,并且如果不存在所需的格式,我会有一个验证器。

假设我在字段中输入了无效值,然后单击按钮。由于验证,将不会生成PDF报告,并且字段会变为红色,如预期的那样。但后来我输入了一个正确的值(字段仍为红色)并按下按钮。生成报告但该字段仍为红色。那是因为我在PDF生成之后使用了FacesContext.getCurrentInstance()。responseComplete(),因此绕过了正常的Faces生命周期,并且不再触发此请求的验证错误清除。

如何生成PDF报告,但仍强制Faces确定应清除验证错误?谢谢!

1 个答案:

答案 0 :(得分:1)

这不能在一个HTTP响应中完成。您需要让客户端发送两个请求,以便您可以返回两个响应;一个清除错误,另一个返回PDF。你只需要在bean的action方法中做一些返工,并且可能添加一个服务于servlet的文件。

基本上,您需要将PDF存储在本地(临时)磁盘位置或内存中,并让JSF有条件地呈现一些JavaScript,然后再下载PDF。 PDF可以通过servlet或指向本地磁盘位置的其他webapp上下文下载。

E.g。

<h:form>
    ...
    <h:commandButton value="Download" action="#{bean.submit}" />
    <h:panelGroup rendered="#{not empty bean.pdfURL}">
        <script>window.location = '#{bean.pdfURL}';</script>
    </h:panelGroup>
</h:form>

public void submit() {
    // Create PDF and store as byte[] in memory, or as File on disk.
    // Then create an unique URL to the PDF.
    pdfURL = externalContext.getRequestContextPath() + "/pdf/" + pdfID;
}

应该在成功的表单提交上生成以下内容(这也应该清除验证错误!)

<script>window.location = '/contextname/pdf/uniquefilename.pdf';</script> 

如果您已在服务器配置中将/some/path/to/pdf注册为另一个webapp上下文,那么您只需将File存储在那里即可下载。但是如果你不能,因为你无法控制服务器配置,那么你需要创建一个映射到/pdf/*的URL模式的servlet,并在doGet()中执行以下操作:方法:

String filename = request.getPathInfo().substring(1);
File pdf = new File("/some/path/to/pdf", filename);

response.setHeader("Content-Type", "application/pdf");
response.setHeader("Content-Length", String.valueOf(file.length()));

InputStream input = new FileInputStream(pdf);
OutputStream output = response.getOutputStream();
// Now just write input to output.