@ -231,7 +231,6 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
@@ -231,7 +231,6 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
<para > Let's assume our <classname > User</classname> has preferences
such as newsletter subscription and a list of hobbies. Below is an
example of the <classname > Preferences</classname> class:</para>
</section>
<programlisting language= "java" > public class Preferences {
@ -297,7 +296,9 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
@@ -297,7 +296,9 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
< /form:form> </programlisting>
<para > There are 3 approaches to the <literal > checkbox</literal> tag
which should meet all your checkbox needs. <itemizedlist >
which should meet all your checkbox needs.</para>
<itemizedlist >
<listitem >
<para > Approach One - When the bound value is of type
<literal > java.lang.Boolean</literal> , the
@ -323,7 +324,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
@@ -323,7 +324,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
configured <literal > setValue(Object)</literal> is equal to the
bound value.</para>
</listitem>
</itemizedlist> </para>
</itemizedlist>
<para > Note that regardless of the approach, the same HTML structure is
generated. Below is an HTML snippet of some checkboxes:</para>
@ -354,6 +355,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
@@ -354,6 +355,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
to which the form data will be bound to reflect the state of the
checkbox no matter what</emphasis>
</quote> .</para>
</section>
<section id= "view-jsp-formtaglib-checkboxestag" >
<title > The <literal > checkboxes</literal> tag</title>
@ -372,7 +374,6 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
@@ -372,7 +374,6 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
"items" property. Typically the bound property is a collection so it
can hold multiple values selected by the user. Below is an example of
the JSP using this tag:</para>
</section>
<programlisting language= "xml" > < form:form>
< table>
@ -393,6 +394,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
@@ -393,6 +394,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
value will be used as the label to be displayed. You can also use a
custom object where you can provide the property names for the value
using "itemValue" and the label using "itemLabel".</para>
</section>
<section id= "view-jsp-formtaglib-radiobuttontag" >
<title > The <literal > radiobutton</literal> tag</title>
@ -1878,8 +1880,7 @@ home.root=words</programlisting>
@@ -1878,8 +1880,7 @@ home.root=words</programlisting>
spreadsheet or PDF viewer application in response.</para>
<para > In order to use Excel views, you need to add the 'poi' library to
your classpath, and for PDF generation, the iText.jar. Both are included
in the main Spring distribution.</para>
your classpath, and for PDF generation, the iText library.</para>
</section>
<section id= "view-document-config" >
@ -1895,17 +1896,21 @@ home.root=words</programlisting>
@@ -1895,17 +1896,21 @@ home.root=words</programlisting>
<section id= "view-document-configviews" >
<title > Document view definitions</title>
<para > Firstly , let's amend the views.properties file (or xml
<para > First, let's amend the views.properties file (or xml
equivalent) and add a simple view definition for both document types.
The entire file now looks like this with the XSLT view shown from
earlier.. <programlisting > home.class=xslt.HomePage
earlier:</para>
<programlisting > home.class=xslt.HomePage
home.stylesheetLocation=/WEB-INF/xsl/home.xslt
home.root=words
xl.class=excel.HomePage
pdf.class=pdf.HomePage</programlisting> <emphasis > If you want to start with a
template spreadsheet to add your model data to, specify the location
pdf.class=pdf.HomePage</programlisting>
<para > <emphasis > If you want to start with a
template spreadsheet or a fillable PDF form to add your model data to, specify the location
as the 'url' property in the view definition</emphasis> </para>
</section>
@ -1928,12 +1933,14 @@ pdf.class=pdf.HomePage</programlisting> <emphasis>If you want to start with a
@@ -1928,12 +1933,14 @@ pdf.class=pdf.HomePage</programlisting> <emphasis>If you want to start with a
<literal > org.springframework.web.servlet.view.document.AbstractExcelView</literal>
(for Excel files generated by POI) or
<literal > org.springframework.web.servlet.view.document.AbstractJExcelView</literal>
(for JExcelApi-generated Excel files). and implementing the
<literal > buildExcelDocument</literal> </para>
(for JExcelApi-generated Excel files) and implementing the
<literal > buildExcelDocument() </literal> method. </para>
<para > Here's the complete listing for our POI Excel view which
displays the word list from the model map in consecutive rows of the
first column of a new spreadsheet.. <programlisting language= "java" > package excel;
first column of a new spreadsheet:</para>
<programlisting language= "java" > package excel;
// imports omitted for brevity
@ -1967,11 +1974,13 @@ public class HomePage extends AbstractExcelView {
@@ -1967,11 +1974,13 @@ public class HomePage extends AbstractExcelView {
}
}
}</programlisting> </para>
}</programlisting>
<para > And the following is a view generating the same Excel file, now using
JExcelApi:</para>
<programlisting language= "java" > package excel;
<para > And this a view generating the same Excel file, now using
JExcelApi: <programlisting language= "java" > package excel;
// imports omitted for brevity
public class HomePage extends AbstractExcelView {
@ -1991,13 +2000,12 @@ public class HomePage extends AbstractExcelView {
@@ -1991,13 +2000,12 @@ public class HomePage extends AbstractExcelView {
sheet.addCell(new Label(2+i, 0, (String)words.get(i));
}
}
}
</programlisting> </para>
}</programlisting>
<para > Note the differences between the APIs. We've found that the
JExcelApi is somewhat more intuitive and furthermore, JExcelApi has a
bit better image-handling capabilities. There have been memory
problems with large Excel file when using JExcelApi however.</para>
JExcelApi is somewhat more intuitive, and furthermore, JExcelApi has
slightly better image-handling capabilities. There have been memory
problems with large Excel files when using JExcelApi however.</para>
<para > If you now amend the controller such that it returns
<literal > xl</literal> as the name of the view (<literal > return new
@ -2013,7 +2021,9 @@ public class HomePage extends AbstractExcelView {
@@ -2013,7 +2021,9 @@ public class HomePage extends AbstractExcelView {
class extends
<literal > org.springframework.web.servlet.view.document.AbstractPdfView</literal>
and implements the <literal > buildPdfDocument()</literal> method as
follows.. <programlisting language= "java" > package pdf;
follows:</para>
<programlisting language= "java" > package pdf;
// imports omitted for brevity
@ -2033,9 +2043,11 @@ public class PDFPage extends AbstractPdfView {
@@ -2033,9 +2043,11 @@ public class PDFPage extends AbstractPdfView {
doc.add( new Paragraph((String) words.get(i)));
}
}</programlisting> Once again, amend the controller to return the
<literal > pdf</literal> view with a <literal > return new
ModelAndView("pdf", map);</literal> and reload the URL in your
}</programlisting>
<para > Once again, amend the controller to return the
<literal > pdf</literal> view with <literal > return new
ModelAndView("pdf", map);</literal> , and reload the URL in your
application. This time a PDF document should appear listing each of
the words in the model map.</para>
</section>
@ -2049,7 +2061,7 @@ public class PDFPage extends AbstractPdfView {
@@ -2049,7 +2061,7 @@ public class PDFPage extends AbstractPdfView {
url="http://jasperreports.sourceforge.net"></ulink> ) is a powerful
open-source reporting engine that supports the creation of report designs
using an easily understood XML file format. JasperReports is capable of
rendering reports output into four different formats: CSV, Excel, HTML and
rendering reports in four different formats: CSV, Excel, HTML and
PDF.</para>
<section id= "view-jasper-reports-dependencies" >
@ -2183,7 +2195,7 @@ public class PDFPage extends AbstractPdfView {
@@ -2183,7 +2195,7 @@ public class PDFPage extends AbstractPdfView {
</table>
<para > Mapping one of these classes to a view name and a report file is
a matter of adding the appropriate entries into the resource bundle
a matter of adding the appropriate entries in the resource bundle
configured in the previous section as shown here:</para>
<programlisting > simpleReport.class=org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView
@ -2211,7 +2223,7 @@ simpleReport.url=/WEB-INF/reports/DataSourceReport.jasper</programlisting>
@@ -2211,7 +2223,7 @@ simpleReport.url=/WEB-INF/reports/DataSourceReport.jasper</programlisting>
compiling the <literal > .jrxml</literal> file on the fly for you. You
should note that after a <literal > .jrxml</literal> file is compiled by
the Spring Framework, the compiled report is cached for the lifetime
of the application. To make changes to the file you will need to
of the application. Thus, t o make changes to the file you will need to
restart your application.</para>
</section>
@ -2220,7 +2232,7 @@ simpleReport.url=/WEB-INF/reports/DataSourceReport.jasper</programlisting>
@@ -2220,7 +2232,7 @@ simpleReport.url=/WEB-INF/reports/DataSourceReport.jasper</programlisting>
<classname > JasperReportsMultiFormatView</classname> </title>
<para > The <classname > JasperReportsMultiFormatView</classname> allows
for report format to be specified at runtime. The actual rendering of
for the report format to be specified at runtime. The actual rendering of
the report is delegated to one of the other JasperReports view classes
- the <classname > JasperReportsMultiFormatView</classname> class simply
adds a wrapper layer that allows for the exact implementation to be
@ -2229,9 +2241,9 @@ simpleReport.url=/WEB-INF/reports/DataSourceReport.jasper</programlisting>
@@ -2229,9 +2241,9 @@ simpleReport.url=/WEB-INF/reports/DataSourceReport.jasper</programlisting>
<para > The <classname > JasperReportsMultiFormatView</classname> class
introduces two concepts: the format key and the discriminator key. The
<classname > JasperReportsMultiFormatView</classname> class uses the
mapping key to lookup the actual view implementation class and uses
mapping key to look up the actual view implementation class, and it uses
the format key to lookup up the mapping key. From a coding perspective
you add an entry to your model with the formay key as the key and the
you add an entry to your model with the format key as the key and the
mapping key as the value, for example:</para>
<programlisting language= "java" > public ModelAndView handleSimpleReportMulti(HttpServletRequest request,
@ -2316,7 +2328,7 @@ HttpServletResponse response) throws Exception {
@@ -2316,7 +2328,7 @@ HttpServletResponse response) throws Exception {
chosen, you must supply Spring with all of the data needed to populate
your report. For JasperReports this means you must pass in all report
parameters along with the report datasource. Report parameters are
simple name/value pairs and can be added be to the
simple name/value pairs and can be added to the
<interfacename > Map</interfacename> for your model as you would add any
name/value pair.</para>
@ -2339,7 +2351,7 @@ HttpServletResponse response) throws Exception {
@@ -2339,7 +2351,7 @@ HttpServletResponse response) throws Exception {
<literal > JRDataSource</literal> or <literal > Collection</literal> under a
specific key and then configure this key using the
<literal > reportDataKey</literal> property of the view class. In both
cases Spring will instances of <literal > Collection</literal> in a
cases Spring will wrap instances of <literal > Collection</literal> in a
<literal > JRBeanCollectionDataSource</literal> instance. For
example:</para>
@ -2364,7 +2376,7 @@ simpleReport.reportDataKey=myBeanData</programlisting>
@@ -2364,7 +2376,7 @@ simpleReport.reportDataKey=myBeanData</programlisting>
first instance of <literal > JRDataSource</literal> or
<literal > Collection</literal> that it encounters. If you need to place
multiple instances of <literal > JRDataSource</literal> or
<literal > Collection</literal> into the model then you need to use the
<literal > Collection</literal> into the model you need to use the
second approach.</para>
</section>
@ -2375,10 +2387,10 @@ simpleReport.reportDataKey=myBeanData</programlisting>
@@ -2375,10 +2387,10 @@ simpleReport.reportDataKey=myBeanData</programlisting>
your master report files. There are a wide variety of mechanisms for
including sub-reports in your report files. The easiest way is to hard
code the report path and the SQL query for the sub report into your
design files. The drawback of this approach is obvious - the values are
design files. The drawback of this approach is obvious: the values are
hard-coded into your report files reducing reusability and making it
harder to modify and update report designs. To overcome this you can
configure sub-reports declaratively and you can include additional data
configure sub-reports declaratively, and you can include additional data
for these sub-reports directly from your controllers.</para>
<section id= "view-jasper-reports-subreports-config-reports" >
@ -2410,7 +2422,7 @@ simpleReport.reportDataKey=myBeanData</programlisting>
@@ -2410,7 +2422,7 @@ simpleReport.reportDataKey=myBeanData</programlisting>
<literal > net.sf.jasperreports.engine.JasperReports</literal> under the
parameter <literal > ProductsSubReport</literal> . When configuring your
Jasper view class, you can instruct Spring to load a report file and
pass into the JasperReports engine as a sub-report using the
pass it i nto the JasperReports engine as a sub-report using the
<literal > subReportUrls</literal> property:</para>
<programlisting language= "xml" > < property name="subReportUrls">
@ -2420,42 +2432,44 @@ simpleReport.reportDataKey=myBeanData</programlisting>
@@ -2420,42 +2432,44 @@ simpleReport.reportDataKey=myBeanData</programlisting>
< /property> </programlisting>
<para > Here, the key of the <interfacename > Map</interfacename>
corresponds to the name of the sub-report parameter in th report
corresponds to the name of the sub-report parameter in the report
design file, and the entry is the URL of the report file. Spring will
load this report file, compiling it if necessary, and will pass into
load this report file, compiling it if necessary, and pass it into
the JasperReports engine under the given key.</para>
</section>
<section id= "view-jasper-reports-subreports-config-datasources" >
<title > Configuring Sub-Report Data Sources</title>
<para > This step is entirely optional when using Spring configure your
<para > This step is entirely optional when using Spring to configure your
sub-reports. If you wish, you can still configure the data source for
your sub-reports using static queries. However, if you want Spring to
convert data returned in your <literal > ModelAndView</literal> into
instances of <literal > JRDataSource</literal> then you need to specify
which of the parameters in your <literal > ModelAndView</literal> Spring
should convert. To do this configure the list of parameter names using
the <literal > subReportDataKeys</literal> property of the your chosen
view class: <programlisting language= "xml" > < property name="subReportDataKeys"
value="SubReportData"/> </programlisting> Here, the key you supply MUST
correspond to both the key used in your
<literal > ModelAndView</literal> and the key used in your report design
file.</para>
should convert. To do this, configure the list of parameter names using
the <literal > subReportDataKeys</literal> property of your chosen
view class:</para>
<programlisting language= "xml" > < property name="subReportDataKeys" value="SubReportData"/> </programlisting>
<para > Here, the key you supply <emphasis role= "bold" > must</emphasis>
correspond to both the key used in your <literal > ModelAndView</literal>
and the key used in your report design file.</para>
</section>
</section>
<section id= "view-jasper-reports-exporter-parameters" >
<title > Configuring Exporter Parameters</title>
<para > If you have special requirements for exporter configuration -
perhaps you want a specific page size for your PDF report, then you can
<para > If you have special requirements for exporter configuration --
perhaps you want a specific page size for your PDF report -- you can
configure these exporter parameters declaratively in your Spring
configuration file using the <literal > exporterParameters</literal>
property of the view class. The <literal > exporterParameters</literal>
property is typed as <interfacename > Map</interfacename> and i n your
property is typed as a <interfacename > Map</interfacename> . I n your
configuration the key of an entry should be the fully-qualified name of
a static field that contains the exporter parameter definition and the
a static field that contains the exporter parameter definition, and the
value of an entry should be the value you want to assign to the
parameter. An example of this is shown below:</para>
@ -2474,7 +2488,7 @@ simpleReport.reportDataKey=myBeanData</programlisting>
@@ -2474,7 +2488,7 @@ simpleReport.reportDataKey=myBeanData</programlisting>
< /bean> </programlisting>
<para > Here you can see that the
<classname > JasperReportsHtmlView</classname> is being configured with an
<classname > JasperReportsHtmlView</classname> is configured with an
exporter parameter for
<literal > net.sf.jasperreports.engine.export.JRHtmlExporterParameter.HTML_FOOTER</literal>
which will output a footer in the resulting HTML.</para>
@ -2493,29 +2507,29 @@ simpleReport.reportDataKey=myBeanData</programlisting>
@@ -2493,29 +2507,29 @@ simpleReport.reportDataKey=myBeanData</programlisting>
<literal > org.springframework.web.servlet.view.feed</literal> .</para>
<para > <classname > AbstractAtomFeedView</classname> requires you to
implement the <methodname > buildFeedEntries</methodname> method and
optionally override the <methodname > buildFeedMetadata</methodname> method
(the default implementation is empty), as shown below</para>
implement the <methodname > buildFeedEntries() </methodname> method and
optionally override the <methodname > buildFeedMetadata() </methodname> method
(the default implementation is empty), as shown below. </para>
<programlisting language= "java" > public class SampleContentAtomView extends AbstractAtomFeedView {
@Override
protected void buildFeedMetadata(Map< String, Object> model, Feed feed,
HttpServletRequest request) {
// implementation omitted
HttpServletRequest request) {
// implementation omitted
}
@Override
protected List< Entry> buildFeedEntries(Map< String, Object> model,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// implementation omitted
// implementation omitted
}
}</programlisting>
<para > Similar requirements apply for implementing
<classname > AbstractRssFeedView</classname> , as shown below</para>
<classname > AbstractRssFeedView</classname> , as shown below. </para>
<programlisting language= "java" > public class SampleContentAtomView extends AbstractRssFeedView {
@ -2527,25 +2541,25 @@ simpleReport.reportDataKey=myBeanData</programlisting>
@@ -2527,25 +2541,25 @@ simpleReport.reportDataKey=myBeanData</programlisting>
@Override
protected List< Item> buildFeedItems(Map< String, Object> model,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// implementation omitted
}
}</programlisting>
<para > The <methodname > buildFeedItems</methodname> and
<methodname > buildFeedEntires</methodname> pass in the HTTP request in case
<para > The <methodname > buildFeedItems() </methodname> and
<methodname > buildFeedEntires() </methodname> methods pass in the HTTP request in case
you need to access the Locale. The HTTP response is passed in only for the
setting of cookies or other HTTP headers. The feed will automatically be
written to the response object after the method returns.</para>
<para > For an example of creating a Atom view please refer to Alef
Arendsen's SpringSource TeamBlog <ulink
<para > For an example of creating an Atom view please refer to Alef
Arendsen's SpringSource Team Blog <ulink
url="http://blog.springsource.com/2009/03/16/adding-an-atom-view-to-an-application-using-springs-rest-support/">entry</ulink> .</para>
</section>
<section >
<section id= "view-xml-marshalling" >
<title > XML Marshalling View</title>
<para > The <classname > MarhsallingView</classname> uses a XML
@ -2561,4 +2575,5 @@ simpleReport.reportDataKey=myBeanData</programlisting>
@@ -2561,4 +2575,5 @@ simpleReport.reportDataKey=myBeanData</programlisting>
chapter <link linkend= "oxm" > Marshalling XML using O/X
Mappers</link> .</para>
</section>
</chapter>