📄 abstractjasperreportsview.java
字号:
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.view.jasperreports;
import java.io.IOException;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.ResourceBundle;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRDataSourceProvider;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.design.JRCompiler;
import net.sf.jasperreports.engine.design.JRDefaultCompiler;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.engine.xml.JRXmlLoader;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.support.MessageSourceResourceBundle;
import org.springframework.core.io.Resource;
import org.springframework.ui.jasperreports.JasperReportsUtils;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.support.RequestContextUtils;
import org.springframework.web.servlet.view.AbstractUrlBasedView;
/**
* Base class for all JasperReports views. Applies on-the-fly compilation
* of report designs as required and coordinates the rendering process.
* The resource path of the main report needs to be specified as <code>url</code>.
*
* <p>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 <code>reportDataKey</code> first, then falls back to looking
* for a value of type <code>JRDataSource</code>, <code>java.util.Collection</code>,
* object array (in that order).
*
* <p>If no <code>JRDataSource</code> can be found in the model, then reports will
* be filled using the configured <code>javax.sql.DataSource</code> if any. If neither
* a <code>JRDataSource</code> or <code>javax.sql.DataSource</code> is available then
* an <code>IllegalArgumentException</code> is raised.
*
* <p>Provides support for sub-reports through the <code>subReportUrls</code> and
* <code>subReportDataKeys</code> properties.
*
* <p>When using sub-reports, the master report should be configured using the
* <code>url</code> property and the sub-reports files should be configured using
* the <code>subReportUrls</code> property. Each entry in the <code>subReportUrls</code>
* 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
* <code>net.sf.jasperreports.engine.JasperReport</code>,
* and the value of an entry must be the URL for the sub-report file.
*
* <p>For sub-reports that require an instance of <code>JRDataSource</code>, 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
* <code>JRDataSource</code> instances for the sub-report via the
* <code>subReportDataKeys</code> property. When using <code>JRDataSource</code>
* instances for sub-reports, you <i>must</i> specify a value for the
* <code>reportDataKey</code> property, indicating the data to use for the main report.
*
* <p>Allows for exporter parameters to be configured declatively using the
* <code>exporterParameters</code> property. This is a <code>Map</code> typed
* property where the key of an entry corresponds to the fully-qualified name
* of the static field for the <code>JRExporterParameter</code> and the value
* of an entry is the value you want to assign to the exporter parameter.
*
* <p>Response headers can be controlled via the <code>headers</code> property. Spring
* will attempt to set the correct value for the <code>Content-Diposition</code> header
* so that reports render correctly in Internet Explorer. However, you can override this
* setting through the <code>headers</code> property.
*
* @author Rob Harrop
* @author Juergen Hoeller
* @since 1.1.3
* @see #setUrl
* @see #setReportDataKey
* @see #setSubReportUrls
* @see #setSubReportDataKeys
* @see #setHeaders
* @see #setExporterParameters
* @see #setJdbcDataSource
*/
public abstract class AbstractJasperReportsView extends AbstractUrlBasedView {
/**
* Constant that defines "Content-Disposition" header.
*/
protected static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition";
/**
* The default Content-Disposition header. Used to make IE play nice.
*/
protected static final String CONTENT_DISPOSITION_INLINE = "inline";
/**
* A String key used to lookup the <code>JRDataSource</code> in the model.
*/
private String reportDataKey;
/**
* Stores the paths to any sub-report files used by this top-level report,
* along with the keys they are mapped to in the top-level report file.
*/
private Properties subReportUrls;
/**
* Stores the names of any data source objects that need to be converted to
* <code>JRDataSource</code> instances and included in the report parameters
* to be passed on to a sub-report.
*/
private String[] subReportDataKeys;
/**
* Stores the headers to written with each response
*/
private Properties headers;
/**
* Stores the exporter parameters passed in by the user as passed in by the user. May be keyed as
* <code>String</code>s with the fully qualified name of the exporter parameter field.
*/
private Map exporterParameters = new HashMap();
/**
* Stores the converted exporter parameters - keyed by <code>JRExporterParameter</code>.
*/
private Map convertedExporterParameters;
/**
* Stores the <code>DataSource</code>, if any, used as the report data source.
*/
private DataSource jdbcDataSource;
/**
* Holds the JRCompiler implementation to use for compiling reports on-the-fly.
*/
private JRCompiler reportCompiler = JRDefaultCompiler.getInstance();
/**
* The <code>JasperReport</code> that is used to render the view.
*/
private JasperReport report;
/**
* Holds mappings between sub-report keys and <code>JasperReport</code> objects.
*/
private Map subReports;
/**
* Set the name of the model attribute that represents the report data.
* If not specified, the model map will be searched for a matching value type.
* <p>A <code>JRDataSource</code> will be taken as-is. For other types, conversion
* will apply: By default, a <code>java.util.Collection</code> will be converted
* to <code>JRBeanCollectionDataSource</code>, and an object array to
* <code>JRBeanArrayDataSource</code>.
* <p><b>Note:</b> 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.
* @see #convertReportData
* @see net.sf.jasperreports.engine.JRDataSource
* @see net.sf.jasperreports.engine.data.JRBeanCollectionDataSource
* @see net.sf.jasperreports.engine.data.JRBeanArrayDataSource
*/
public void setReportDataKey(String reportDataKey) {
this.reportDataKey = reportDataKey;
}
/**
* Specify resource paths which must be loaded as instances of
* <code>JasperReport</code> and passed to the JasperReports engine for
* rendering as sub-reports, under the same keys as in this mapping.
* @param subReports mapping between model keys and resource paths
* (Spring resource locations)
* @see #setUrl
* @see org.springframework.context.ApplicationContext#getResource
*/
public void setSubReportUrls(Properties subReports) {
this.subReportUrls = subReports;
}
/**
* Set the list of names corresponding to the model parameters that will contain
* data source objects for use in sub-reports. Spring will convert these objects
* to instances of <code>JRDataSource</code> where applicable and will then
* include the resulting <code>JRDataSource</code> in the parameters passed into
* the JasperReports engine.
* <p>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 <code>JRDataSource</code> objects as model attributes,
* specifing this list of keys is not required.
* <p>If you specify a list of sub-report data keys, it is required to also
* specify a <code>reportDataKey</code> for the main report, to avoid confusion
* between the data source objects for the various reports involved.
* @param subReportDataKeys list of names for sub-report data source objects
* @see #setReportDataKey
* @see #convertReportData
* @see net.sf.jasperreports.engine.JRDataSource
* @see net.sf.jasperreports.engine.data.JRBeanCollectionDataSource
* @see net.sf.jasperreports.engine.data.JRBeanArrayDataSource
*/
public void setSubReportDataKeys(String[] subReportDataKeys) {
this.subReportDataKeys = subReportDataKeys;
}
/**
* Specify the set of headers that are included in each of response.
* @param headers the headers to write to each response.
*/
public void setHeaders(Properties headers) {
this.headers = headers;
}
/**
* Set the exporter parameters that should be used when rendering a view.
* @param parameters <code>Map</code> with the fully qualified field name
* of the <code>JRExporterParameter</code> instance as key
* (e.g. "net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IMAGES_URI")
* and the value you wish to assign to the parameter as value
*/
public void setExporterParameters(Map parameters) {
// NOTE: Removed conversion from here since configuration of parameters
// can also happen through access to the underlying Map using
// getExporterParameters(). Conversion now happens in initApplicationContext,
// and subclasses use getConvertedExporterParameters() to access the converted
// parameter Map - robh.
this.exporterParameters = parameters;
}
/**
* Return the exporter parameters that this view uses, if any.
*/
public Map getExporterParameters() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -