本周,我正在调试使用JasperReport v5.5完成的一些模板。经过相当长的一段时间与一个奇怪的bug争吵后,我想在(至少)某些情况下,使用直接访问而不是调用适当的getter来访问bean的字段(你写$ F {toto}并且它访问私有字段toto而不是调用getToto())。
模板以这种方式定义字段:
...
<field name="someValue" class="java.lang.String">
<fieldDescription><![CDATA[someValue]]></fieldDescription>
</field>
...
java bean类是一个使用BaseClass的层次结构 - &gt; ConcretClass。它定义了一个标准属性someValue,带有getter和setter。 ConcretClass重写了这个属性来实现一些业务逻辑(我知道这可以称为反模式,但这不是重点 - 传统代码我不想要时间没有重构)。
所以java有这个:
public class BaseClass {
private String someValue;
public String getSomeValue() { return someValue; }
public void setSomeValue(String someValue) { this.someValue = someValue; }
}
public class ConcretClass extends BaseClass {
private String someValue;
@Override public String getSomeValue() {
LOG.info("invoking getter");
// more business logic here
return someValue;
}
@Override public void setSomeValue(String someValue) { this.someValue = someValue; }
}
它已经简化但仍包含这个想法。
文档说明使用getter访问字段: https://community.jaspersoft.com/documentation/tibco-jaspersoft-studio-user-guide/v60/registration-javabean-fields
Jaspersoft Studio parses a description such as address.state (with a period character between the two attributes) as an attribute path. This attribute path is passed to the function getAddress() in order to locate the target attribute, and then to getState() in order to query the status of the attribute.
使用ConcretClass NEVER实例运行我的代码会显示日志“调用getter”。相反,它显示BaseClass#someValue的值(此时为null)。我浪费了至少一天......
我错过了什么?这是一个错误吗?
答案 0 :(得分:0)
好的,正如评论中提到的那样,@ AlexK向我指出了正确的方向。错误的开发人员并不在Jasper的团队中,而是在我的团队中。总有一天,有人认为在任何地方使用反射(几乎)是个好主意,而他所做的一个地方就是我们自定义JRDataSource的public Object getFieldValue(JRField jrField) throws JRException
的实现。
显然是一个坏主意(在处理反思时几乎总是这样)......
道德:为您的流程添加代码评论:)