这(可怕;不要问;我无法修改数据模型或配置)表达式不起作用:
${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无法选择正确的varargs方法:
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 :(得分:0)
你可以用自己明确的方法将调用包装到library_sample
方法
Files.write()
答案 1 :(得分:0)
我想这将是重载方法选择的一个小故障,它被模拟为100%向后兼容性。因此,您应该将FreeMarker配置的incompatible_improvements
设置增加到至少2.3.21以激活修复(或者如果您没有使用object_wrapper
设置的默认设置,那么类似的设置您正在创建的ObjectWrapper
。但是,你说你无法触及FreeMarker配置......
我在另一个答案中也看到你不能添加自己的静态辅助类......
答案 2 :(得分: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())>