FreeMarker编码混淆

10
当我使用FreeMarker阅读UTF-8编码的模板时,在浏览器中特殊字符可以正确呈现,但freeMarkerConfig.getDefaultEncoding()返回“Cp1252”。如果我设置freeMarkerConfig.setDefaultEncoding(“UTF-8”),则在浏览器中只看到问号,尽管模板文件的实际编码是“UTF-8”。在每种情况下,都会发送http头“Content-Type:text / html; charset = UTF-8”。
有什么想法是出了什么问题?
4个回答

5

将内容类型属性设置为FreeMarkerViewResolver。

Spring 4.2示例

@Bean
public FreeMarkerViewResolver freemarkerViewResolver() {
    FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
    resolver.setContentType("text/html; charset=utf-8");
    resolver.setCache(true);
    resolver.setPrefix("");
    resolver.setSuffix(".ftl.html");
    resolver.setRequestContextAttribute("rc");
    return resolver;
}

3

如果您正在使用Spring框架和MimeMessage发送电子邮件,请尝试按照以下方式通过MimeMessagePreparator设置内容(我跳过了MimeMessagePreparator方法getMessagePreparator,因为重要的是如何设置内容):

// Create the message helper from the received mimemessage on the preparator
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
// ... include the from, to, subject, freemarker html generation here... text is the String variable with generated html
// Set the content as follows instead of helper.setText(text, true);
helper.getMimeMessage().setContent(text, "text/html;charset=utf-8");

这对我很有帮助,当发送电子邮件时,浏览器正确显示字符。

隐式类为:

import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
import javax.mail.internet.MimeMessage;

如果你使用的是Eclipse IDE,请确保你的工作空间在模板文件上具有UTF-8的默认编码,可以通过右键单击文件并查看属性来进行设置。

希望这能对你有所帮助。


两年后,当前版本和我遇到了同样的问题。我没有使用Spring,只是用Freemarker生成输出。将模板编码设置为utf-8,将默认编码设置为utf-8,将输出编码设置为utf-8都没有帮助。有什么想法吗? - Christian13467
你检查了模板文件的编码吗?我的意思是,如果你在像Notepad++这样的文本编辑器中打开模板并将编码设置为UTF-8,你能看到正确的字符吗?如果不能,那么问题与创建模板时使用的字符集有关。 - Francisco Valle
模板的编码是utf-8。所有设置(模板编码,输出编码)也都是utf-8。但处理结果总是使用-Dfile.encoding=xxx指定的编码,这在Windows系统上默认为Cp1252。 我的应用程序正在wildfly 10中运行。我正在使用freemarker 2.3.28。这可能很有趣。 - Christian13467
1
我找到了错误。我使用了一个OutputStreamWriter来包装传入的OutputStream,但没有设置编码为freemarker的输出编码。默认编码是Cp1252或者我用-Dfile.encoding设置的任何编码。这不是freemarker的问题!! - Christian13467
即使这与本帖中的问题无关,强制将UTF-8作为IDE中默认文件编码以避免此类错误是一个好习惯,这样您就可以看到文件是否正确编码。 - Francisco Valle

0

输出编码是由您的Java机器决定的。如果您使用UTF-FOO创建一个输出文件,并将此输出文件传递给Freemarker生成,则输出编码将为UTF-FOO。

请参见字符集问题

例如,使用以下代码:

  Template templévénmts;
  BufferedWriter writ;
  OutputStreamWriter encodé;

  encodé = new OutputStreamWriter(
   new FileOutputStream(new File(f_dirDestination, résultat)), "UTF-8");
  writ = new BufferedWriter(
   encodé);
  templévénmts = f_freemarker.getTemplate(modèle);
  templévénmts.process(f_rootDatas, writ);
  writ.close();

你也可以在 commons io 中使用 FileWriterWithEncoding


1
setDefaultEncoding 是关于输入编码的设置。http://freemarker.org/docs/api/freemarker/template/Configuration.html#setDefaultEncoding%28java.lang.String%29输入是UTF-8编码的,我告诉FreeMarker它也是UTF-8编码的,但只有在使用Cp1252编码读取输入时才能正常工作。 - deamon
你使用的Freemarker版本是什么,以及在什么上下文中使用它? - Istao
我正在使用FreeMarker 2.3.16与JAX-RS(实现:Jersey)以及最终的Servlets。 - deamon
如果将所有输入方式设置为UTF-8,并使用UTF-8设置在本地系统中处理模板文件,那么生成的文件是否正确? - Istao
我做了这件事。我将所有输出和默认字符集设置为utf-8。我使用utf-8读取模板。我将输出处理为utf-8。将结果写入磁盘后,在Windows系统上得到了cp1252编码。当我设置-Dfile.encoding=utf-8时,一切都很好。在freemarker实现中,file.encoding从哪里获取? - Christian13467

0

嗯,看起来无论你认为你的输入是UTF-8编码还是别的编码,实际上它确实是Cp1252编码。你能再检查一下吗?建议你试着将模板文件处理成本地文件并检查结果,我同意Istao的观点。


我已经使用非常好的处理编码的jEdit检查了编码。有趣的是,即使在默认编码为UTF-8的系统上使用相同的模板文件,它也可以正常工作。因此,FreeMarker应该使用UTF-8来读取输入文件。 - deamon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接