2017-04-19 69 views
0

这(可怕;不问;我不能修改数据模型或结构)的表达不工作:Freemarker 2.3.23是否正确处理可变参数?

${statics["java.nio.file.Files"].write(statics["java.nio.file.Paths"].get("/foo/bar.stuff"), statics["java.nio.charset.Charset"].forName("UTF-8").encode(someStringContent).array(), enums["java.nio.file.StandardOpenOption"].WRITE)} 

型号代码:

model.addAttribute("statics", new BeansWrapperBuilder(Configuration.VERSION_2_3_23).build().getStaticModels()); 
    model.addAttribute("enums", new BeansWrapperBuilder(Configuration.VERSION_2_3_23).build().getEnumModels()); 

简而言之,它是采用一些Freemarker字符串内容的(总体)方式,将其变成byte[]阵列,并将其写入Freemarker内部的/foo/bar.stuff路径。

的错误指示的Freemarker不能选择适当的可变参数方法:

Error executing FreeMarker template 
FreeMarker template error: 
When trying to call the non-varargs overloads: 
No compatible overloaded variation was found; can't convert (unwrap) the 3rd argument to the desired Java type. 
The FTL type of the argument values were: extended_hash+string (sun.nio.fs.UnixPath wrapped into f.e.b.StringModel), sequence (byte[] wrapped into f.t.DefaultArrayAdapter$ByteArrayAdapter), extended_hash+string (java.nio.file.StandardOpenOption wrapped into f.e.b.StringModel). 
When trying to call the varargs overloads: 
Multiple compatible overloaded variations were found with the same priority. 
The Java type of the argument values were: sun.nio.fs.UnixPath, byte[], java.nio.file.StandardOpenOption. 
The matching overload was searched among these members: 
    static java.nio.file.Files.write(java.nio.file.Path, Iterable, java.nio.file.OpenOption...), 
    static java.nio.file.Files.write(java.nio.file.Path, Iterable, java.nio.charset.Charset, java.nio.file.OpenOption...), 
    static java.nio.file.Files.write(java.nio.file.Path, byte[], java.nio.file.OpenOption...) 

我试过其他黑客,包括创建使用java.lang.reflect.Array#newInstance(Class, int)正确类型的数组,但这并没有帮助。

我假设这是不可能的?

+0

您是否有权访问定义静态的代码?你能粘贴它吗? – Charlie

+0

如果您不介意,我会粘贴模型代码以获取您看到的错误。如果它与你的不一样,请纠正它。 – Charlie

+0

莱尔德,你的静态BeanWrapper是用EXPOSE_ALL暴露级别构建的吗? – Charlie

回答

0

假设你statics模型场与EXPOSE_ALL建,你可以去深入反思兔子洞:

<#assign class = statics["java.lang.Class"]> 
<#assign openOptionClass = class.forName("java.nio.file.OpenOption")> 
<#assign filesClass = class.forName("java.nio.file.Files")> 
<#assign method = filesClass.getMethod("write", class.forName("java.nio.file.Path"),class.forName("[B"),class.forName("[Ljava.nio.file.OpenOption;"))> 
<#assign path = statics["java.nio.file.Paths"].get("/foo/bar.stuff")> 
<#assign utf8 = statics["java.nio.charset.Charset"].forName("UTF-8")> 
<#assign writeOptions = enums["java.nio.file.StandardOpenOption"].WRITE> 
<#assign writeOptionsArray = statics["java.lang.reflect.Array"].newInstance(openOptionClass,1)> 
<#assign ignoreThisVoid = statics["java.lang.reflect.Array"].set(writeOptionsArray, 0, writeOptions)> 
${method.invoke(null, path, utf8.encode(someStringContent).array(), writeOptionsArray)} 

或者你可以尝试PrintWriter(仍然需要EXPOSE_ALL):

<#assign class = statics["java.lang.Class"]> 
<#assign fileOutputStreamClass = class.forName("java.io.FileOutputStream")> 
<#assign fileOutputStreamConstructor = fileOutputStreamClass.getConstructor(class.forName("java.lang.String"))> 
<#assign fileOutputStream = fileOutputStreamConstructor.newInstance("/foo/bar.stuff")> 
<#assign ignoreThisVoid = fileOutputStream.write(utf8.encode(someStringContent).array())> 
+0

所以我没有这样做_exactly_,但它反映了我做的事情。我发现,无论涉及什么咒语'java.lang.reflect.Array'(以“伪装”vargars) - 我发现没有调用'java.lang。reflect.Array#newInstance(Class,int)'会起作用(Freemarker仍然感到困惑)。 –

+0

啊,但是你使用'getConstructor'是出于任何原因我没有想到的东西!这应该让我摆脱这个兔子洞。 :-) 谢谢。 –

+0

我在本地尝试了这两种方法,他们都为我效劳 – Charlie

0

你,你可以包装在调用Files.write()方法在自己的明确的方法

import java.io.IOException; 
import java.nio.file.Files; 
import java.nio.file.OpenOption; 
import java.nio.file.Path; 

public class UnambiugousMethodWrappers{ 
    public static Path writeBytes (Path path, byte[] bytes, OpenOption... options) throws IOException { 
     return Files.write(path, bytes, options); 
    } 
} 
+0

谢谢;因为在这里并不重要的原因,我所拥有的全部是Freemarker模板本身。 :-( –

0

我想这将是在重载方法选择一个小故障是真实模拟了100%的向后兼容性。所以你应该将你的FreeMarker配置的incompatible_improvements设置为至少2.3.21,以便激活修复(或者如果你没有使用object_wrapper设置的默认设置,那么你创建的ObjectWrapper的设置类似)。但是,你说你不能碰FreeMarker的配置...

我也看到了对方的回答,你不能添加自己的静态辅助类要么...

+0

确实;我有点伤害。:-)感谢您的帮助(以及维护Freemarker!)。它肯定比我用过的其他模板引擎更加灵活。 –

相关问题