当前位置: 首页 > 知识库问答 >
问题:

热部署HTML模板在中文字符的位置生成问号--仅在CentOS上

萧晓博
2023-03-14

我目前正在测试一个Java web项目,使用Freemarker模板显示中文字符。我的开发环境是Ubuntu14.4,当前的项目部署在JBoss4应用服务器上。在所有模板中,都设置了HTTP头“content-type:text/html;charset=utf8”。

在我的开发人员环境中,热部署HTML或自由标记模板不会在重音字符的位置生成问号,也不需要在server.xml中显式指定编码。

临时服务器使用Centos6.3,应用程序服务器是JBoss4。首先,为了只正确地显示中文字符,需要在server.xml中添加一个与编码相关的条目,这在开发环境中是不需要的(例如,uriencoding=“UTF-8”)

此外,如果将HTML或Freemarker模板热部署到staging服务器中,它会在模板中显示的汉字位置生成问号。为了克服这种情况,在删除JBoss Deploy中的work和tmp文件夹后,需要重新启动服务器。

什么会导致这种尴尬的行为只在CentOS?我未能在Ubuntu测试环境中生成此场景,但它可以在staging server中轻松生成。在CentOS中是否有任何关于字符编码的附加配置我可能忽略了?

我确实提到了许多类似的问题,但决定发表这篇文章,因为其中任何一篇都没有提供足够的洞察力来解决手头的问题。

引用的堆栈溢出资源

Freemarker编码-用问号代替重音字符

FreeMarker无法显示汉字

字符集问题

基于建议的更改和注释的更新我对代码做了一些更改

为了显式设置编码详细信息

Set Encoding in .bashrc, set the following: export LC_ALL=en_US.UTF-8
Set in Run.sh JAVA_OPTS section : JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8"
System.out.println("Init file.encoding= " +  System.getProperty("file.encoding"));
System.out.println("Init Default Charset=" + Charset.defaultCharset());
System.out.println("Init Default Charset in Use=" + getDefaultCharSet());
/*Encoding properties Check - Using getEncoding()*/
Locale locale = cfg.getLocale();
String encodingWithLocale = cfg.getEncoding(locale);
cfg.setDefaultEncoding("UTF-8");
/*Specific Encoding Properties*/
  Locale locale = cfg.getLocale();
  cfg.setEncoding(locale, "UTF-8");
cfg.setOutputEncoding("UTF-8");
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8"/>

但是在我的程序中使用Freemarker时,我有一个关于输出流编码的问题。

根据FreeMarker支持文档。

用于输出流的字符集不是由FreeMarker决定的,而是由您在创建传递给模板的process方法的编写器时决定的。

请注意,模板的字符集独立于模板生成的输出的字符集(除非附带的软件故意将输出字符集设置为与模板字符集相同)。

我使用了StringWriter功能,它提供了所需的writer功能,但指定编码似乎是个问题。

StringWriter sw = new StringWriter();
Template tmpl = cfg_components.getTemplate(template,"utf-8");
cfg_components.setOutputEncoding("UTF-8");
rootMap.put("content_cdn_path", getContent_cdn_path());
...
tmpl.process(rootMap, sw);
return sw.getBuffer();
@Override
protected void process(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {

request.setCharacterEncoding("UTF8");
response.setCharacterEncoding("UTF8");

关于如何指定输出流编码或StringWriter的替代方案,有什么建议吗?

共有1个答案

班景龙
2023-03-14

什么会导致这种尴尬的行为只在CentOS?

您的代码可能依赖于UTF-8的默认字符编码。如果CentOS系统上的默认字符编码是(例如)LATIN-1而不是UTF-8,那么任何中文字符都将被替换为问号。

如果这是问题所在,那么解决方案是在适当的地方使用显式字符编码方案。

如果没有看到代码的相关部分,就很难预测错误发生在哪里。然而,字符被问号替换是一个可靠的迹象,表明在某处使用了不正确的编码。

实际上,有一种简单的方法可以证实这一理论:查看启动JBoss时生效的区域环境变量。例如,运行locale命令。对我来说,它说:

$ locale
LANG=en_US.utf8
LC_CTYPE="en_US.utf8"
LC_NUMERIC="en_US.utf8"
LC_TIME="en_US.utf8"
LC_COLLATE="en_US.utf8"
LC_MONETARY="en_US.utf8"
LC_MESSAGES="en_US.utf8"
LC_PAPER="en_US.utf8"
LC_NAME="en_US.utf8"
LC_ADDRESS="en_US.utf8"
LC_TELEPHONE="en_US.utf8"
LC_MEASUREMENT="en_US.utf8"
LC_IDENTIFICATION="en_US.utf8"
LC_ALL=

如果您的区域设置不正确,请尝试在启动JBoss之前更改它们(针对当前shell)。

更新-查看代码片段,您似乎对StreamWriter有误解。StringWriter将Java字符累加为字符。它不会对它们进行编码。那么当你这样做的时候:

    tmpl.process(rootMap, sw);
    return sw.getBuffer();

返回的是StringBuffer,其中包含一系列Java字符。同样,这些字符还没有编码。

将字符编码为字节(显然使用了错误的编码方案)发生的时间比这晚;也就是说,可以在将StringBuffer内容转换为字节的代码中,也可以在servlet基础结构本身中。

 类似资料:
  • 本文向大家介绍在ASP中不用模板生成HTML静态页直接生成.html页面,包括了在ASP中不用模板生成HTML静态页直接生成.html页面的使用技巧和注意事项,需要的朋友参考一下 我们一般生成HTML静态页时,常常会事先做好一个模板,然后生成时调用模板文件。那么有没有办法不用模板,如一个正常的htmer.asp页面,直接生成为htmer.html页面呢?当然是可以的,而且非常简单,今天就教大家在A

  • 如何在Thymeleaf中显示包含HTML标记的字符串? 所以这段代码: 在这行代码中,它会在浏览器上生成以下内容: 但是我想在浏览器上显示这个: 测试

  • 有人知道在IntelliJ 14.0.2下为Spring Boot应用程序进行资源和模板热部署的机制吗。 我知道完全的Spring Boot支持计划在14.1,但我有一个项目,我从一个标准的WAR项目转换到Spring Boot项目,我真的很想念热部署。 目前,我必须手动构建资源所在的项目,以获得热部署,即使这样,有时也有点不稳定。我更愿意只保存一个模板或javascript/css文件,然后像我

  • 本文档最初是基于kubenetes1.6版本编写的,对于kuberentes1.8及以上版本同样适用,只是个别位置有稍许变动,变动的地方我将特别注明版本要求。 本系列文档介绍使用二进制部署 kubernetes 集群的所有步骤,而不是使用 kubeadm 等自动化方式来部署集群,同时开启了集群的TLS安全认证,该安装步骤适用于所有bare metal环境、on-premise环境和公有云环境。 如

  • 我有一个非常特殊的例子,我需要在一个模板文本中使用一个模板文本,但是我做不到。 代码如下所示: 然而,我必须将其包装在函数中,同时保持变量的值,这会导致错误发生。无论我是否逃脱了滴答声。 使用转义滴答,我收到以下错误消息: 错误:预期的某个链接但未提供 没有,我得到: 意外标记,预期“”,” 我该怎么处理这件事? 编辑:可能应该注意的是,中传递的代码将被渲染并且需要使用它。它最终将通过传递给另一个

  • 我正在为我的后端java项目使用PostgreSql和Jooq。Postgre字符集UTF-8排序规则WIN1254土耳其语。样本表 品牌表 < li>Id < li >名称 模型表 Id 名称 品牌ID “我”字是大“我”。它不是土耳其语字母中的“ı”。 Jooq以'brandi̇d'和“getBrand”的身份生成模型。不允许在html中使用“getBrand”。Spring给出了这种用法的错