public abstract class AbstractJasperReportsView extends AbstractUrlBasedView
url
.
This class is responsible for getting report data from the model that has
been provided to the view. The default implementation checks for a model object
under the specified reportDataKey
first, then falls back to looking
for a value of type JRDataSource
, java.util.Collection
,
object array (in that order).
If no JRDataSource
can be found in the model, then reports will
be filled using the configured javax.sql.DataSource
if any. If neither
a JRDataSource
or javax.sql.DataSource
is available then
an IllegalArgumentException
is raised.
Provides support for sub-reports through the subReportUrls
and
subReportDataKeys
properties.
When using sub-reports, the master report should be configured using the
url
property and the sub-reports files should be configured using
the subReportUrls
property. Each entry in the subReportUrls
Map corresponds to an individual sub-report. The key of an entry must match up
to a sub-report parameter in your report file of type
net.sf.jasperreports.engine.JasperReport
,
and the value of an entry must be the URL for the sub-report file.
For sub-reports that require an instance of JRDataSource
, that is,
they don't have a hard-coded query for data retrieval, you can include the
appropriate data in your model as would with the data source for the parent report.
However, you must provide a List of parameter names that need to be converted to
JRDataSource
instances for the sub-report via the
subReportDataKeys
property. When using JRDataSource
instances for sub-reports, you must specify a value for the
reportDataKey
property, indicating the data to use for the main report.
Allows for exporter parameters to be configured declatively using the
exporterParameters
property. This is a Map
typed
property where the key of an entry corresponds to the fully-qualified name
of the static field for the JRExporterParameter
and the value
of an entry is the value you want to assign to the exporter parameter.
Response headers can be controlled via the headers
property. Spring
will attempt to set the correct value for the Content-Diposition
header
so that reports render correctly in Internet Explorer. However, you can override this
setting through the headers
property.
This class is compatible with classic JasperReports releases back until 2.x.
As a consequence, it keeps using the JRExporter
API which got deprecated as of JasperReports 5.5.2 (early 2014).
AbstractUrlBasedView.setUrl(java.lang.String)
,
setReportDataKey(java.lang.String)
,
setSubReportUrls(java.util.Properties)
,
setSubReportDataKeys(java.lang.String...)
,
setHeaders(java.util.Properties)
,
setExporterParameters(java.util.Map<?, ?>)
,
setJdbcDataSource(javax.sql.DataSource)
Modifier and Type | Field and Description |
---|---|
protected static java.lang.String |
CONTENT_DISPOSITION_INLINE
The default Content-Disposition header.
|
protected static java.lang.String |
HEADER_CONTENT_DISPOSITION
Constant that defines "Content-Disposition" header.
|
DEFAULT_CONTENT_TYPE
logger
PATH_VARIABLES, RESPONSE_STATUS_ATTRIBUTE, SELECTED_CONTENT_TYPE
Constructor and Description |
---|
AbstractJasperReportsView() |
Modifier and Type | Method and Description |
---|---|
protected void |
convertExporterParameters()
Converts the exporter parameters passed in by the user which may be keyed
by
String s corresponding to the fully qualified name of the
JRExporterParameter into parameters which are keyed by
JRExporterParameter . |
protected java.lang.Object |
convertParameterValue(net.sf.jasperreports.engine.JRExporterParameter parameter,
java.lang.Object value)
Convert the supplied parameter value into the actual type required by the
corresponding
JRExporterParameter . |
protected net.sf.jasperreports.engine.JRDataSource |
convertReportData(java.lang.Object value)
Convert the given report data value to a
JRDataSource . |
protected net.sf.jasperreports.engine.JRExporterParameter |
convertToExporterParameter(java.lang.String fqFieldName)
Convert the given fully qualified field name to a corresponding
JRExporterParameter instance.
|
protected net.sf.jasperreports.engine.JRDataSource |
createReport(net.sf.jasperreports.engine.JRDataSourceProvider provider)
Create a report using the given provider.
|
protected void |
exposeLocalizationContext(java.util.Map<java.lang.String,java.lang.Object> model,
HttpServletRequest request)
Expose current Spring-managed Locale and MessageSource to JasperReports i18n
($R expressions etc).
|
protected net.sf.jasperreports.engine.JasperPrint |
fillReport(java.util.Map<java.lang.String,java.lang.Object> model)
Create a populated
JasperPrint instance from the configured
JasperReport instance. |
protected java.util.Map<net.sf.jasperreports.engine.JRExporterParameter,java.lang.Object> |
getConvertedExporterParameters()
Allows subclasses to retrieve the converted exporter parameters.
|
protected net.sf.jasperreports.engine.JRExporterParameter |
getExporterParameter(java.lang.Object parameter)
Return a
JRExporterParameter for the given parameter object,
converting it from a String if necessary. |
java.util.Map<?,?> |
getExporterParameters()
Return the exporter parameters that this view uses, if any.
|
protected javax.sql.DataSource |
getJdbcDataSource()
Return the
javax.sql.DataSource that this view uses, if any. |
protected net.sf.jasperreports.engine.JasperReport |
getReport()
Determine the
JasperReport to fill. |
protected net.sf.jasperreports.engine.JRDataSource |
getReportData(java.util.Map<java.lang.String,java.lang.Object> model)
Create an appropriate
JRDataSource for passed-in report data. |
protected java.lang.Class<?>[] |
getReportDataTypes()
Return the value types that can be converted to a
JRDataSource ,
in prioritized order. |
protected void |
initApplicationContext()
Checks to see that a valid report file URL is supplied in the
configuration.
|
protected boolean |
isUrlRequired()
JasperReports views do not strictly required a 'url' value.
|
protected net.sf.jasperreports.engine.JasperReport |
loadReport()
Load the main
JasperReport from the specified Resource . |
protected net.sf.jasperreports.engine.JasperReport |
loadReport(Resource resource)
Loads a
JasperReport from the specified Resource . |
protected void |
onInit()
Subclasses can override this to add some custom initialization logic.
|
protected void |
postProcessReport(net.sf.jasperreports.engine.JasperPrint populatedReport,
java.util.Map<java.lang.String,java.lang.Object> model)
Template method to be overridden for custom post-processing of the
populated report.
|
protected void |
renderMergedOutputModel(java.util.Map<java.lang.String,java.lang.Object> model,
HttpServletRequest request,
HttpServletResponse response)
Finds the report data to use for rendering the report and then invokes the
renderReport(net.sf.jasperreports.engine.JasperPrint, java.util.Map<java.lang.String, java.lang.Object>, javax.servlet.http.HttpServletResponse) method that should be implemented by the subclass. |
protected abstract void |
renderReport(net.sf.jasperreports.engine.JasperPrint populatedReport,
java.util.Map<java.lang.String,java.lang.Object> model,
HttpServletResponse response)
Subclasses should implement this method to perform the actual rendering process.
|
protected void |
setConvertedExporterParameters(java.util.Map<net.sf.jasperreports.engine.JRExporterParameter,java.lang.Object> parameters)
Allows subclasses to populate the converted exporter parameters.
|
void |
setExporterParameters(java.util.Map<?,?> parameters)
Set the exporter parameters that should be used when rendering a view.
|
void |
setHeaders(java.util.Properties headers)
Specify the set of headers that are included in each of response.
|
void |
setJdbcDataSource(javax.sql.DataSource jdbcDataSource)
Specify the
javax.sql.DataSource to use for reports with
embedded SQL statements. |
void |
setReportDataKey(java.lang.String reportDataKey)
Set the name of the model attribute that represents the report data.
|
void |
setSubReportDataKeys(java.lang.String... subReportDataKeys)
Set the list of names corresponding to the model parameters that will contain
data source objects for use in sub-reports.
|
void |
setSubReportUrls(java.util.Properties subReports)
Specify resource paths which must be loaded as instances of
JasperReport and passed to the JasperReports engine for
rendering as sub-reports, under the same keys as in this mapping. |
afterPropertiesSet, checkResource, getUrl, setUrl, toString
addStaticAttribute, createMergedOutputModel, createRequestContext, createTemporaryOutputStream, exposeModelAsRequestAttributes, generatesDownloadContent, getAttributesMap, getBeanName, getContentType, getRequestContextAttribute, getRequestToExpose, getStaticAttributes, isExposePathVariables, prepareResponse, render, setAttributes, setAttributesCSV, setAttributesMap, setBeanName, setContentType, setExposeContextBeansAsAttributes, setExposedContextBeanNames, setExposePathVariables, setRequestContextAttribute, setResponseContentType, writeToResponse
getServletContext, getTempDir, getWebApplicationContext, initApplicationContext, initServletContext, isContextRequired, setServletContext
getApplicationContext, getMessageSourceAccessor, requiredContextClass, setApplicationContext
protected static final java.lang.String HEADER_CONTENT_DISPOSITION
protected static final java.lang.String CONTENT_DISPOSITION_INLINE
public void setReportDataKey(java.lang.String reportDataKey)
A JRDataSource
will be taken as-is. For other types, conversion
will apply: By default, a java.util.Collection
will be converted
to JRBeanCollectionDataSource
, and an object array to
JRBeanArrayDataSource
.
Note: If you pass in a Collection or object array in the model map for use as plain report parameter, rather than as report data to extract fields from, you need to specify the key for the actual report data to use, to avoid mis-detection of report data by type.
convertReportData(java.lang.Object)
,
JRDataSource
,
JRBeanCollectionDataSource
,
JRBeanArrayDataSource
public void setSubReportUrls(java.util.Properties subReports)
JasperReport
and passed to the JasperReports engine for
rendering as sub-reports, under the same keys as in this mapping.subReports
- mapping between model keys and resource paths
(Spring resource locations)AbstractUrlBasedView.setUrl(java.lang.String)
,
ResourceLoader.getResource(java.lang.String)
public void setSubReportDataKeys(java.lang.String... subReportDataKeys)
JRDataSource
where applicable and will then
include the resulting JRDataSource
in the parameters passed into
the JasperReports engine.
The name specified in the list should correspond to an attribute in the
model Map, and to a sub-report data source parameter in your report file.
If you pass in JRDataSource
objects as model attributes,
specifying this list of keys is not required.
If you specify a list of sub-report data keys, it is required to also
specify a reportDataKey
for the main report, to avoid confusion
between the data source objects for the various reports involved.
subReportDataKeys
- list of names for sub-report data source objectssetReportDataKey(java.lang.String)
,
convertReportData(java.lang.Object)
,
JRDataSource
,
JRBeanCollectionDataSource
,
JRBeanArrayDataSource
public void setHeaders(java.util.Properties headers)
headers
- the headers to write to each response.public void setExporterParameters(java.util.Map<?,?> parameters)
parameters
- Map
with the fully qualified field name
of the JRExporterParameter
instance as key
(e.g. "net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IMAGES_URI")
and the value you wish to assign to the parameter as valuepublic java.util.Map<?,?> getExporterParameters()
protected void setConvertedExporterParameters(java.util.Map<net.sf.jasperreports.engine.JRExporterParameter,java.lang.Object> parameters)
protected java.util.Map<net.sf.jasperreports.engine.JRExporterParameter,java.lang.Object> getConvertedExporterParameters()
public void setJdbcDataSource(javax.sql.DataSource jdbcDataSource)
javax.sql.DataSource
to use for reports with
embedded SQL statements.protected javax.sql.DataSource getJdbcDataSource()
javax.sql.DataSource
that this view uses, if any.protected boolean isUrlRequired()
getReport()
template method may be overridden.isUrlRequired
in class AbstractUrlBasedView
protected final void initApplicationContext() throws ApplicationContextException
Subclasses can add custom initialization logic by overriding
the onInit()
method.
initApplicationContext
in class ApplicationObjectSupport
ApplicationContextException
- in case of initialization errorsApplicationObjectSupport.setApplicationContext(org.springframework.context.ApplicationContext)
protected void onInit()
initApplicationContext()
as soon as all standard initialization logic
has finished executing.initApplicationContext()
protected final void convertExporterParameters()
String
s corresponding to the fully qualified name of the
JRExporterParameter
into parameters which are keyed by
JRExporterParameter
.getExporterParameter(Object)
protected java.lang.Object convertParameterValue(net.sf.jasperreports.engine.JRExporterParameter parameter, java.lang.Object value)
JRExporterParameter
.
The default implementation simply converts the String values "true" and
"false" into corresponding Boolean
objects, and tries to convert
String values that start with a digit into Integer
objects
(simply keeping them as String if number conversion fails).
parameter
- the parameter keyvalue
- the parameter valueprotected net.sf.jasperreports.engine.JRExporterParameter getExporterParameter(java.lang.Object parameter)
JRExporterParameter
for the given parameter object,
converting it from a String if necessary.parameter
- the parameter object, either a String or a JRExporterParameterconvertToExporterParameter(String)
protected net.sf.jasperreports.engine.JRExporterParameter convertToExporterParameter(java.lang.String fqFieldName)
fqFieldName
- the fully qualified field name, consisting
of the class name followed by a dot followed by the field name
(e.g. "net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IMAGES_URI")protected net.sf.jasperreports.engine.JasperReport loadReport()
JasperReport
from the specified Resource
.
If the Resource
points to an uncompiled report design file then the
report file is compiled dynamically and loaded into memory.JasperReport
instance, or null
if no main
report has been statically definedprotected final net.sf.jasperreports.engine.JasperReport loadReport(Resource resource)
JasperReport
from the specified Resource
.
If the Resource
points to an uncompiled report design file then
the report file is compiled dynamically and loaded into memory.resource
- the Resource
containing the report definition or designJasperReport
instanceprotected void renderMergedOutputModel(java.util.Map<java.lang.String,java.lang.Object> model, HttpServletRequest request, HttpServletResponse response) throws java.lang.Exception
renderReport(net.sf.jasperreports.engine.JasperPrint, java.util.Map<java.lang.String, java.lang.Object>, javax.servlet.http.HttpServletResponse)
method that should be implemented by the subclass.renderMergedOutputModel
in class AbstractView
model
- the model map, as passed in for view rendering. Must contain
a report data value that can be converted to a JRDataSource
,
according to the rules of the fillReport(java.util.Map<java.lang.String, java.lang.Object>)
method.request
- current HTTP requestresponse
- current HTTP responsejava.lang.Exception
- if rendering failedprotected void exposeLocalizationContext(java.util.Map<java.lang.String,java.lang.Object> model, HttpServletRequest request)
The default implementation exposes the Spring RequestContext Locale and a
MessageSourceResourceBundle adapter for the Spring ApplicationContext,
analogous to the JstlUtils.exposeLocalizationContext
method.
RequestContextUtils.getLocale(javax.servlet.http.HttpServletRequest)
,
MessageSourceResourceBundle
,
ApplicationObjectSupport.getApplicationContext()
,
JRParameter.REPORT_LOCALE
,
JRParameter.REPORT_RESOURCE_BUNDLE
,
JstlUtils.exposeLocalizationContext(javax.servlet.http.HttpServletRequest, org.springframework.context.MessageSource)
protected net.sf.jasperreports.engine.JasperPrint fillReport(java.util.Map<java.lang.String,java.lang.Object> model) throws java.lang.Exception
JasperPrint
instance from the configured
JasperReport
instance.
By default, this method will use any JRDataSource
instance
(or wrappable Object
) that can be located using setReportDataKey(java.lang.String)
,
a lookup for type JRDataSource
in the model Map, or a special value
retrieved via getReportData(java.util.Map<java.lang.String, java.lang.Object>)
.
If no JRDataSource
can be found, this method will use a JDBC
Connection
obtained from the configured javax.sql.DataSource
(or a DataSource attribute in the model). If no JDBC DataSource can be found
either, the JasperReports engine will be invoked with plain model Map,
assuming that the model contains parameters that identify the source
for report data (e.g. Hibernate or JPA queries).
model
- the model for this requestJasperPrint
instancejava.lang.IllegalArgumentException
- if no JRDataSource
can be found
and no javax.sql.DataSource
is suppliedjava.sql.SQLException
- if there is an error when populating the report using
the javax.sql.DataSource
net.sf.jasperreports.engine.JRException
- if there is an error when populating the report using
a JRDataSource
java.lang.Exception
getReportData(java.util.Map<java.lang.String, java.lang.Object>)
,
setJdbcDataSource(javax.sql.DataSource)
protected net.sf.jasperreports.engine.JasperReport getReport()
JasperReport
to fill.
Called by fillReport(java.util.Map<java.lang.String, java.lang.Object>)
.
The default implementation returns the report as statically configured
through the 'url' property (and loaded by loadReport()
).
Can be overridden in subclasses in order to dynamically obtain a
JasperReport
instance. As an alternative, consider
overriding the fillReport(java.util.Map<java.lang.String, java.lang.Object>)
template method itself.
JasperReport
protected net.sf.jasperreports.engine.JRDataSource getReportData(java.util.Map<java.lang.String,java.lang.Object> model)
JRDataSource
for passed-in report data.
Called by fillReport(java.util.Map<java.lang.String, java.lang.Object>)
when its own lookup steps were not successful.
The default implementation looks for a value of type java.util.Collection
or object array (in that order). Can be overridden in subclasses.
model
- the model map, as passed in for view renderingJRDataSource
or null
if the data source is not foundgetReportDataTypes()
,
convertReportData(java.lang.Object)
protected net.sf.jasperreports.engine.JRDataSource convertReportData(java.lang.Object value) throws java.lang.IllegalArgumentException
JRDataSource
.
The default implementation delegates to JasperReportUtils
unless
the report data value is an instance of JRDataSourceProvider
.
A JRDataSource
, JRDataSourceProvider
,
java.util.Collection
or object array is detected.
JRDataSource
s are returned as is, whilst JRDataSourceProvider
s
are used to create an instance of JRDataSource
which is then returned.
The latter two are converted to JRBeanCollectionDataSource
or
JRBeanArrayDataSource
, respectively.
value
- the report data value to convertjava.lang.IllegalArgumentException
- if the value could not be convertedJasperReportsUtils.convertReportData(java.lang.Object)
,
JRDataSource
,
JRDataSourceProvider
,
JRBeanCollectionDataSource
,
JRBeanArrayDataSource
protected net.sf.jasperreports.engine.JRDataSource createReport(net.sf.jasperreports.engine.JRDataSourceProvider provider)
provider
- the JRDataSourceProvider to useprotected java.lang.Class<?>[] getReportDataTypes()
JRDataSource
,
in prioritized order. Should only return types that the
convertReportData(java.lang.Object)
method is actually able to convert.
Default value types are: java.util.Collection
and Object
array.
protected void postProcessReport(net.sf.jasperreports.engine.JasperPrint populatedReport, java.util.Map<java.lang.String,java.lang.Object> model) throws java.lang.Exception
The default implementation is empty.
populatedReport
- the populated JasperPrint
model
- the map containing report parametersjava.lang.Exception
- if post-processing failedprotected abstract void renderReport(net.sf.jasperreports.engine.JasperPrint populatedReport, java.util.Map<java.lang.String,java.lang.Object> model, HttpServletResponse response) throws java.lang.Exception
Note that the content type has not been set yet: Implementers should build
a content type String and set it via response.setContentType
.
If necessary, this can include a charset clause for a specific encoding.
The latter will only be necessary for textual output onto a Writer, and only
in case of the encoding being specified in the JasperReports exporter parameters.
WARNING: Implementers should not use response.setCharacterEncoding
unless they are willing to depend on Servlet API 2.4 or higher. Prefer a
concatenated content type String with a charset clause instead.
populatedReport
- the populated JasperPrint
to rendermodel
- the map containing report parametersresponse
- the HTTP response the report should be rendered tojava.lang.Exception
- if rendering failedAbstractView.getContentType()
,
ServletResponse.setContentType(java.lang.String)
,
ServletResponse.setCharacterEncoding(java.lang.String)