2017-04-19 70 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!)。它肯定比我用過的其他模板引擎更加靈活。 –

相關問題