我有一个页面,其中有一个输入字段和一个按钮。单击该按钮可根据输入字段中输入的值生成PDF报告。我的问题在于输入字段需要一些特殊的格式,并且如果不存在所需的格式,我会有一个验证器。
假设我在字段中输入了无效值,然后单击按钮。由于验证,将不会生成PDF报告,并且字段会变为红色,如预期的那样。但后来我输入了一个正确的值(字段仍为红色)并按下按钮。生成报告但该字段仍为红色。那是因为我在PDF生成之后使用了FacesContext.getCurrentInstance()。responseComplete(),因此绕过了正常的Faces生命周期,并且不再触发此请求的验证错误清除。
如何生成PDF报告,但仍强制Faces确定应清除验证错误?谢谢!
答案 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.