这个问题使我发疯。我正在尝试在ColdFusion中使用Java创建一个Document对象。当我这样做时:
nd = createObject("java","javax.xml.parsers.DocumentBuilder");
我可以转储nd并查看它正确加载了所有方法:
object of javax.xml.parsers.DocumentBuilder Class Name javax.xml.parsers.DocumentBuilder
Method / Return Type
getDOMImplementation() / org.w3c.dom.DOMImplementation
getSchema() / javax.xml.validation.Schema
isNamespaceAware() / boolean
isValidating() / boolean
isXIncludeAware() / boolean
newDocument() / org.w3c.dom.Document
parse(java.io.File) / org.w3c.dom.Document
parse(java.lang.String) / org.w3c.dom.Document
parse(org.xml.sax.InputSource) / org.w3c.dom.Document
parse(java.io.InputStream, java.lang.String) / org.w3c.dom.Document
parse(java.io.InputStream) / org.w3c.dom.Document
reset() / void
setEntityResolver(org.xml.sax.EntityResolver) / void
setErrorHandler(org.xml.sax.ErrorHandler) / void
我正在尝试调用newDocument()方法。我在cfscript和cfsets中都尝试了以下所有内容:
nd.newDocument();
nd.newDocument(JavaCast("null",""));
nd = createObject("java","javax.xml.parsers.DocumentBuilder").newDocument();
nd = createObject("java","javax.xml.parsers.DocumentBuilder").newDocument(JavaCast("null",""));
但是,无论我尝试哪种方法,都会出现此错误:
没有一种方法具有指定的方法名称和参数类型 或isNamespaceAware方法的参数类型过载 ColdFusion无法可靠地解密。 ColdFusion找到0个与>提供的参数匹配的方法。如果这是Java对象,并且您已验证方法>存在,请使用javacast函数来减少歧义。
我可以看到该方法已加载..该方法未重载..它不需要任何参数..而且,即使我明确告诉CF我要传递null,也找不到方法。
我尝试访问该类中的其他方法-并且也找不到这些方法。.我不确定为什么可以转储该类的内容-并且我可以看到所有方法。。但是,无论如何CF感到困惑,当我尝试调用它们时找不到它们。
任何想法都会很有帮助。
谢谢!
答案 0 :(得分:6)
您必须为documentBuilder工厂创建一个对象。在工厂的帮助下,您可以获得实际的xml信息。在这里,我创建了对象,并使用documentbuilderfactory调用了parse方法。 同样,您必须注入newInstance(),然后才能访问newdocument()方法。 我的Xml内容:testParse.xml
conf/nifi.properties
* CF代码:
<?xml version="1.0"?>
<company>
<staff id="1001">
<firstname>yong</firstname>
<lastname>mook kim</lastname>
<nickname>mkyong</nickname>
<salary>100000</salary>
</staff>
<staff id="2001">
<firstname>low</firstname>
<lastname>yin fong</lastname>
<nickname>fong fong</nickname>
<salary>200000</salary>
</staff>
</company>
我希望它将对您有所帮助。谢谢。
答案 1 :(得分:0)
我尝试访问该类中的其他方法-但它无法 找到那些。.我不确定为什么我可以转储其中的内容 类-我可以看到所有方法。 感到困惑,当我尝试给他们打电话时找不到他们。
tldr;
要详细说明“为什么”,这是一条红色鲱鱼。错误的真正原因是DocumentBuilder是abstract
。您不能创建抽象类的实例。如existing answer中所述,您只能通过DocumentBuilderFactory创建一个新实例。
详细信息:
CreateObject实际上实际返回的是java类的代理。尽管它可能看起来像Java类的实例,但并非如此。它只是一个包装。注意手动创建的代理对象看起来与cfdump中的变量相同吗?
nd = createObject("java","javax.xml.parsers.DocumentBuilder");
proxy = createObject("java", "coldfusion.runtime.java.JavaProxy").init(nd.getClass());
writeDump(var=proxy, label="This is the JavaProxy");
writeDump(var=nd, label="This is the Variable 'nd'");
关于CF为什么“找不到方法”的原因,这是令人误解的。错误的实际含义(在此特定情况下)是该方法确实存在,但是..您尚未被访问。
有两种相关的方法:
由于JavaProxy的工作方式,在使用init(..)
创建新实例之前,您只能访问静态方法。
转储中的方法,例如newInstance()
,都是实例方法。由于您的代码没有调用init(...)
,因此CF搜索可用方法时,找不到newInstance()
,这就是为什么您会收到“找不到方法错误”的原因。
第22集:
当然,如果您尝试实例化此特定类:
nd.init();
...它将失败。原因是DocumentBuilder是abstract class,所以您不能实例化它。但是,它至少会产生稍微更准确的错误消息:
找不到类的构造函数 接受类型('')的参数的javax.xml.parsers.DocumentBuilder。
长话短说,错误消息具有误导性。该方法确实存在,因为您没有该类的适当“实例”,所以无法访问该方法。正如existing answer所解释的那样,获取适当实例的唯一方法是通过DocumentBuilderFactory。
答案 2 :(得分:0)
我在Java类上从ColdFusion调用方法时遇到了相同的错误。我试图使用如下所示的setPropertyName方法。
<cfobject action="create" type="java" name="This.txnRequest" class="#AnetAPI#.TransactionRequestType" />
<cfset authTxnType=CreateObject("java", "#AnetAPI#.TransactionTypeEnum") />
<cfset This.txnRequest.setTransactionType(authTxnType.AUTH_CAPTURE_TRANSACTION) />
结果表明,ColdFusion希望您直接访问EJB中的属性。您还需要像这样显式调用EJB构造函数:
<cfset This.txnRequest.init() />
<cfset This.txnRequest.TransactionType=authTxnType.AUTH_CAPTURE_TRANSACTION />
CF如Adobe Docs中所述为您隐式调用set方法。您不能直接调用它。