最近要用到iText來(lái)處理PDF來(lái)提供User與服務(wù)器交互的途徑, 所以從Google和Baidu上翻了翻,學(xué)到了一點(diǎn)東西, 想Mark下來(lái)以后參考,同時(shí)也可以和大家交流一下.
Project最主要是要解決三個(gè)方面的問(wèn)題:
1.用什么Software來(lái)生成可交互的Form?
2.用什么Open source tools來(lái)Pre-fill Form?
3.在User填完Data后,又以什么方式Submit 到Server處理?
對(duì)于第一個(gè)問(wèn)題,自然是用Adobe 的Software啦,但是用Acrobat Pro還是用Lifecycle Designer, 卻讓我費(fèi)了不少勁.為什么咧?因?yàn)锳crobat Pro和Lifecycle Designer 處理的Form的格式是不一樣的. Acrobat Pro里面用的是AcroForm,是Acrobat3.0開始用的格式,而Lifecycle Designer里面用的是Xfa Form,是基于XML的, 兩者的不同請(qǐng)參考以下的摘錄:
Acroforms and XFA forms are different technologies
The interactive forms that you create in LiveCycle Designer are different than the interactive forms that you create in Adobe Acrobat. If you create an interactive form in Acrobat, your form is based on Adobe’s Acroform technology. This technology dates back to Acrobat version 3, and Adobe provides the “Acrobat Forms API Reference” to provide the technical details for this technology. I would not recommend using Acroform technology because XFA is the better technology.
If you are moving from Acroforms to XFA forms, you need to know a couple of important facts about these two technologies:
1.LiveCycle Designer can edit a PDF form created in Acrobat, but Acrobat cannot edit a PDF form created in Designer.
2.JavaScript works differently in these two technologies. Some of the JavaScript routines that work in Acroforms will not work in XFA forms. Adobe has documented these differences in a 43 page online PDF called, “Converting Acrobat JavaScript for Use in LiveCycle Designer Forms.” Designer is a much more robust tool for using JavaScript in your forms, so I recommend that you learn how to script with the XFA object model. See Chapter 4, “Form Scripting,” for more information.
PS: you can find more in the below link : More info about XFA
Lifecycle designer 是后來(lái)才有的東西,自然是比Acrobat Pro更先進(jìn)也更適合用于交互,但我的項(xiàng)目最終還是選了Acrobat Pro,因?yàn)槲业牡诙€(gè)問(wèn)題的答案是iText. iText可以用來(lái)Pre-fill XFA格式的Form,但是不知道為什么用iText Create的submit button不能submit XFA form(按了Button后沒(méi)有反應(yīng)),后來(lái)上網(wǎng)查到原來(lái)iText不支持XFA Form, 所以也只能用Acrobat啦.
而且用Acrobat Pro創(chuàng)建的Form有兩個(gè)我自己覺(jué)得不錯(cuò)的優(yōu)點(diǎn)(以TextFeild類型為例子):
1. Acrobat Pro創(chuàng)建的AcroForm是沒(méi)有層次結(jié)構(gòu)的,而LifeCycle Desinger創(chuàng)建的Form是有層次的.什么意思咧?舉個(gè)例子,同樣是Add一個(gè)TextFeild, 把它命名為CustomerName,在AcroForm里面的名字就是CustomerName啦,而在XFA Form里面就成了topmostSubForm[0].Page1[0].CustomerName[0],咋一看,還真是煩.而且你的PDF一改的話,那你的Feild name也相應(yīng)改了,這樣Program也要改了....
2. Acrobat Pro創(chuàng)建的AcroForm的TextFeild可以自適應(yīng)大小,一個(gè)TextFeild總是有一定的長(zhǎng)度,但要填的Value就不知有多長(zhǎng)啦,有可能有個(gè)CustomerName真的很長(zhǎng)咧,這在XFA Form里面就會(huì)有些Value Show不出來(lái),但Acrobat Pro創(chuàng)建的AcroForm的TextFeild就可以根據(jù)Value的大小而改變字體的大小來(lái)適應(yīng)TextFeild的長(zhǎng)度.
以上兩點(diǎn)是我自己的認(rèn)識(shí),也許Lifecycle Designer也可以做到以上的效果,但目前我是不會(huì),因?yàn)榻佑|Lifecycle Designer比較少,如果有大蝦知道的話請(qǐng)多多指教.
今天碰到了個(gè)比較奇怪的問(wèn)題,居然是因?yàn)镴SP太大導(dǎo)致文件編譯不了,上網(wǎng)查了一下,把解決方法貼下來(lái),以供以后參考:
The problem is that there is a limit on the size of a compiled method in a
Java class file, and that limit is what we're running up against. Recall
that a JSP page is compiled into a servlet, and into essentially only one
method in that servlet. Hence, if your page contains many, many tags, that
method becomes too big, and up comes the exception that you're seeing.
There are a couple of (partial) solutions.
1) Break your giant page up into multiple smaller pages and bring them
together at run time using <jsp:include>. Note that <%@include> won't work,
because that's a compile-time include, which will get you straight back to
the original problem.
2) Look for places to save on tags. For example, the <html:option> tag was
recently extended to allow the specification of the text to display, so
that you can replace this:
<html:option ... ><bean:message key="foo"/></html:option>
with this:
<html:option ... key="foo"/>
More info pls access this link: Solution
我就是用了第一種方法解決的,之前include JSP的時(shí)候用了%@include , 后來(lái)用了<jsp:include>就不會(huì)用問(wèn)題了.順便貼一下兩者的區(qū)別:
@include & jsp:include的區(qū)別
引用:http://www.ibm.com/developerworks/cn/java/j-jsp04293/
本文是 Java Brett McLaughlin 繼第一篇 JSP 最佳實(shí)踐文章后的后續(xù)文章,在文中,作者向您演示了如何擴(kuò)展 JSP 技術(shù)中用于動(dòng)態(tài)內(nèi)容的包含功能。了解靜態(tài) include 偽指令和動(dòng)態(tài) jsp:include 元素之間的差異,搞清楚如何混合搭配這二者以獲取最優(yōu)性能。
在新的 JSP 最佳實(shí)踐系列的前一篇文章中,您了解了如何使用 JSP include 偽指令將諸如頁(yè)眉、頁(yè)腳和導(dǎo)航組件之類的靜態(tài)內(nèi)容包含到 Web 頁(yè)面中。和服務(wù)器端包含一樣,JSP include 偽指令允許某個(gè)頁(yè)面從另一個(gè)頁(yè)面提取內(nèi)容或數(shù)據(jù)。
清單 1. JSP include 偽指令
<%@ page language="java" contentType="text/html" %>
<html>
<head>
<title>newInstance.com</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1" />
<link href="/styles/default.css"
rel="stylesheet" type="text/css" />
</head>
<body>
<%@ include file="header.jsp" %>
<%@ include file="navigation.jsp" %>
<%@ include file="bookshelf.jsp" %>
<%@ include file="/mt-blogs/index.jsp" %>
<%@ include file="footer.jsp" %>
</body>
</html>
雖然 include 非常適于將靜態(tài)內(nèi)容并入 Web 頁(yè)面,但對(duì)于動(dòng)態(tài)內(nèi)容卻不盡如人意。我們?cè)谇耙黄恼轮性谠噲D重新裝入高速緩存文件時(shí)發(fā)現(xiàn)了這一問(wèn)題。與大多數(shù)頁(yè)眉文件及頁(yè)腳文件不同,動(dòng)態(tài)內(nèi)容變化頻繁,必須時(shí)刻更新。我們將首先扼要地重述一下 include 偽指令的局限性,然后我將向您演示如何用 jsp:include 標(biāo)記來(lái)擴(kuò)展 JSP 的包含能力。
高速緩存問(wèn)題
JSP include 偽指令的不足之處有一個(gè)是:它會(huì)導(dǎo)致 Web 瀏覽器高速緩存所有頁(yè)面。在處理諸如頁(yè)腳、版權(quán)聲明或一組靜態(tài)鏈接之類的靜態(tài)組件時(shí),這是有意義的。這些文件不會(huì)改變,因此沒(méi)有理由讓 JSP 解釋器不斷地重新輪詢其中的數(shù)據(jù)。凡是可能的地方,都應(yīng)該實(shí)現(xiàn)高速緩存,因?yàn)樗纳屏藨?yīng)用程序的性能。
但是,有時(shí)侯,進(jìn)行高速緩存會(huì)得不償失。如果提入的內(nèi)容來(lái)自使用動(dòng)態(tài)數(shù)據(jù)(如 Weblog 或數(shù)據(jù)庫(kù)驅(qū)動(dòng)的 JSP 文件)的程序,甚至如果所包含的內(nèi)容是經(jīng)常變化的 HTML(如時(shí)間戳記),那么每當(dāng)裝入 Web 頁(yè)面時(shí),都需要顯示這些文件或程序的最新版本。遺憾的是,JSP include 偽指令并不具備這一功能。在測(cè)試和開發(fā)周期中,在瀏覽器中禁用高速緩存通常能夠解決這一問(wèn)題。但是,對(duì)于實(shí)際使用的應(yīng)用程序而言,性能是任何設(shè)計(jì)決策過(guò)程中的一項(xiàng)重要因素,禁用高速緩存并不是一種可行的長(zhǎng)遠(yuǎn)之計(jì)。更好的解決方案是使用 jsp:include 標(biāo)記。
jsp:include 標(biāo)記
jsp:include 只不過(guò)是一個(gè)不同于 include 的偽指令而已。 jsp:include 的優(yōu)點(diǎn)在于:它 總是會(huì)檢查所含文件中的變化。過(guò)一會(huì)兒我們將研究這一新標(biāo)記的工作方式。但首先看一下兩種 include 各自的代碼,以便能夠看到二者之間的異同。
清單 2 顯示了一個(gè)簡(jiǎn)單頁(yè)面,它使用了原始的 JSP include 偽指令。
清單 2. JSP include 偽指令
<%@ page language="java" contentType="text/html" %>
<html>
<head>
<title>JSP include element test</title>
</head>
<body>
This content is statically in the main JSP file.<br />
<%@ include file="included.html" %>
</body>
</html>
清單 3 是同一個(gè)頁(yè)面,只不過(guò)這里轉(zhuǎn)成使用 jsp:include 標(biāo)記。
清單 3. 轉(zhuǎn)成使用 jsp:include
<%@ page language="java" contentType="text/html" %>
<html>
<head>
<title>JSP include element test</title>
</head>
<body>
This content is statically in the main JSP file.<br />
<jsp:include page="included.html" flush="true" />
</body>
</html>
您應(yīng)該注意這兩種代碼類型之間的兩大區(qū)別。首先, jsp:include 元素不使用屬于 include 偽指令的 %@ 語(yǔ)法。實(shí)際上, jsp 前綴讓 JSP 編譯器知道:它應(yīng)該尋找標(biāo)準(zhǔn) JSP 標(biāo)記集中的元素。其次,指定要包含的文件的屬性從 file 變成了 page 。
flush 屬性
您可能已注意到 jsp:include 代碼示例中的 flush 屬性。顧名思義, flush 指示在讀入包含內(nèi)容之前是否清空任何現(xiàn)有的緩沖區(qū)。JSP 1.1 中需要 flush 屬性,因此,如果代碼中不用它,會(huì)得到一個(gè)錯(cuò)誤。但是,在 JSP 1.2 中, flush 屬性缺省為 false。由于清空大多數(shù)時(shí)候不是一個(gè)重要的問(wèn)題,因此,我的建議是:對(duì)于 JSP 1.1,將 flush 設(shè)置為 true;而對(duì)于 JSP 1.2 及更高版本,將其設(shè)置為關(guān)閉。
jsp:include 是如何工作的
如果您有點(diǎn)愛(ài)刨根問(wèn)底,那么可能十分想知道 jsp:include 標(biāo)記的行為為什么與 include 偽指令不同。道理其實(shí)十分簡(jiǎn)單: jsp:include 包含的是所包含 URI 的 響應(yīng),而不是 URI 本身。這意味著:對(duì)所指出的 URI 進(jìn)行 解釋,因而包含的是 生成的響應(yīng)。如果頁(yè)面是 HTML,那么將得到一點(diǎn)也沒(méi)有變化的 HTML。但是,如果是 Perl 腳本、Java servlet 或者 CGI 程序,那么得到的將是從該程序解釋而得的結(jié)果。雖然頁(yè)面通常就是 HTML,但實(shí)際程序恰好是達(dá)到目的的手段。而且,由于每次請(qǐng)求頁(yè)面的時(shí)候都會(huì)進(jìn)行解釋,因此從來(lái)不會(huì)象使用 include 偽指令時(shí)那樣高速緩存結(jié)果。雖然這只是很小的變動(dòng),但它卻導(dǎo)致了您所見到的行為中的全部差異。
一種混合搭配的解決方案
include 偽指令在某些網(wǎng)站上有其用武之地。例如,如果站點(diǎn)包含一些(如果有變化,也很少)幾乎沒(méi)有變化的頁(yè)眉、頁(yè)腳和導(dǎo)航文件,那么基本的 include 偽指令是這些組件的最佳選項(xiàng)。由于 include 偽指令采用了高速緩存,因此只需放入包含文件一次,其內(nèi)容就會(huì)被高速緩存,其結(jié)果會(huì)是極大地提高了站點(diǎn)的性能。
然而,對(duì)于現(xiàn)在許多 Web 應(yīng)用程序或站點(diǎn)而言,地毯式的高速緩存并不能解決問(wèn)題。雖然頁(yè)眉和頁(yè)腳可能是靜態(tài)的,但是不可能整個(gè)站點(diǎn)都是靜態(tài)的。例如,從數(shù)據(jù)庫(kù)提取導(dǎo)航鏈接是很常見的,并且許多基于 JSP 技術(shù)的站點(diǎn)還從其它站點(diǎn)或應(yīng)用程序上的動(dòng)態(tài) JSP 頁(yè)面提取內(nèi)容。如果正在處理動(dòng)態(tài)內(nèi)容,那么需要采用 jsp:include 來(lái)處理該內(nèi)容。
當(dāng)然,最好的解決方案是經(jīng)常把這兩種方法混合搭配使用,將每種構(gòu)造用到最恰當(dāng)?shù)牡胤健G鍐?4 是混合搭配包含解決方案的一個(gè)示例。
清單 4. 混合搭配解決方案
<%@ page language="java" contentType="text/html" %>
<html>
<head>
<title>newInstance.com</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<link href="/styles/default.css" rel="stylesheet" type="text/css" />
</head>
<body>
<jsp:include page="header.jsp" flush="true">
<jsp:param name="pageTitle" value="newInstance.com"/>
<jsp:param name="pageSlogan" value=" " />
</jsp:include>
<%@ include file="/navigation.jsp" %>
<jsp:include page="bookshelf.jsp" flush="true" />
<jsp:include page="/mt-blogs/index.jsp" flush="true" />
<%@ include file="/footer.jsp" %>
</body>
</html>
上面的代碼顯示了前一篇文章中的示例索引頁(yè)面。導(dǎo)航鏈接和頁(yè)腳是靜態(tài)內(nèi)容,一年最多更改一次。對(duì)于這些文件,我使用了 include 偽指令。內(nèi)容窗格包含 Weblog 和“bookshelf”組件,它們是動(dòng)態(tài)生成的。這兩個(gè)組件需要一直更新,因此對(duì)它們,我使用了 jsp:include 標(biāo)記。 header.jsp 文件有點(diǎn)奇怪。這個(gè)組件是從另一個(gè)本質(zhì)上是靜態(tài)的 JSP 頁(yè)面提取的。但是,正如您將注意到的那樣,它從包含頁(yè)提取頁(yè)“標(biāo)語(yǔ)”,然后將它顯示出來(lái)。要處理這一共享信息,我們必須向頁(yè)眉文件傳入?yún)?shù)。而要處理那些參數(shù),就必須使用 jsp:include 元素。
后記:網(wǎng)上還有一種Solution:
try giving this in the deployment descriptor.
< jsp - param >
< param - name > noTryBlocks </ param - name >
< param - value > true </ param - value >
</ jsp - param >
本人沒(méi)有試過(guò), 不知好不好用....