阿帕奇»»

  茧2.2主页

茧2.2

如何在Cocoon中配置一致编码

最适合国际化,即支持umlauts、special字符,非英语语言,是用UTF-8处理一切,因为这可能是目前最智能的编码方式。

注:如果需要另一种编码,只需替换所有出现的UTF-8,但请注意,本指南仅使用UTF-8测试,其他并非所有地方都支持编码。

以下操作方法涵盖了实现一致性的典型步骤在Cocoon应用程序中进行编码。一些背景信息可以在本页末尾找到。

1.以UTF-8格式发送所有页面

您需要将Cocoon的序列化程序配置为UTF-8。XML序列化程序(<serialize type=“xml”/>)和HTML序列化程序(<serialize type=“html”/>)需要配置。支持所有浏览器中,必须声明要用于正文的编码,还必须包含html中的meta标记:<meta http-equiv=“Content-Type”Content=“text/html;charset=UTF-8”>.这一点非常重要,因为浏览器随后将发送编码的表单请求在UTF-8中(浏览器通常不会在请求中提及编码,所以您必须假设他们做得对)。以下是的配置网站地图的序列化程序组件将完成以下操作:

<serializer name=“xml”mime-type=“text/xml”src=“org.apache.cocoon.serialization.XMLSerializer”><encoding>UTF-8</encoding></serializer><serializer name=“html”mime-type=“text/html;charset=UTF-8”src=“org.apache.cocoon.serialization.HTMLSerializer”><encoding>UTF-8</encoding><!-- 以下通用doctype只是为了完整性而包含的,它对编码没有影响--><doctype public>-//W3C//DTD HTML 4.01过渡//EN</dotype public><文档类型-系统>http://www.w3.org/TR/html4/loose.dtd</doctype-system></serializer>

2.使用CForms/Dojo的AJAX请求

如果使用启用了ajax的CForms,Cocoon将使用dojo.io.bind()它创建XMLHttpRequests,将表单数据POST到服务器。这里Dojo默认决定编码,这与浏览器使用META标记中定义的字符集的行为。但你可以轻松告诉Dojo所有Dojo.io.bind()调用使用哪种格式,只需在包含dojo.js之前,将其包含在HTML页面的顶部:

<script>djConfig={bindEncoding:“utf-8”}</脚本>

您可能已经有了其他djConfig选项,然后只需添加bind编码属性设置为哈希映射。

3.解码传入请求:Servlet容器

当浏览器向服务器发送数据时ServletRequest(Servlet请求)将由您的servlet容器创建,它需要将参数正确解码为Java字符串。如果有编码在HTTP请求头中指定,他将使用它,但不幸的是通常情况并非如此。当浏览器发送表单帖子时,他只会说应用程序/x-www-form-urlencoded在页眉中。所以你必须假设这里的编码,正确的假设是您的页面的编码最初发送到浏览器。

servlet标准规定传入请求的默认编码应为ISO-8859-1(码头不符合此处的标准,假设默认为UTF-8)。因此,为了确保UTF-8用于参数解码,您需要必须明确地告诉servlet该编码。这是通过致电Servlet请求.setCharacterEncoding().为了你的一切请求时,可以使用如下servlet过滤器:SetCharacterEncodingFilter(设置字符编码筛选器).把这个放在你的茧块下面src/main/java/my/package/filters/SetCharacterEncodingFilter因此班级将被放在一个罐子里WEB-INF/库因此可在web.xml配置中使用。

然后将过滤器添加到web.xml:

<过滤器><filter-name>设置字符编码<filter-class>my.package.filters。SetCharacterEncodingFilter</filter-class><init-param>编码<param-value>UTF-8</param-value></init-param></过滤器><!-- 映射到URL模式--><过滤器映射><filter-name>设置字符编码<url-pattern>/*</过滤器映射><!-- 或映射到Cocoon servlet(servlet-name可能不同)--><过滤器映射><filter-name>SetCharacterEncoding(设置字符编码)CocoonBlocksDispatcherServlet</过滤器映射>

由于过滤器元素是在servlet2.3规范中添加的,您需要web.xml中至少有2.3个版本,但使用当前的2.4版本更好Cocoon网络应用程序的标准。对于2.4,您使用XSD模式:

<web-app版本=“2.4”xmlns=“http://java.sun.com/xml/ns/j2ee"xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation=“http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

对于2.3,您需要修改web.xml中的DOCTYPE声明:

<!DOCTYPE网络应用程序PUBLIC“-//Sun Microsystems,Inc.//DTD Web Application 2.3//EN”"http://java.sun.com/dtd/web-app_2_3.dtd">

4.设置Cocoon的编码(尤其是CForms)

要告诉Cocoon在内部使用UTF-8,您必须设置2个属性:

org.apache.cocoon.containerencoding=utf-8org.apache.cocoon.formencoding=utf-8

他们需要一些*.属性文件位于META-INF/茧/属性在你的一个街区。请注意containerencoding必须与您在SetCharacterEncodingFilter(设置字符编码过滤器)。但在这里,我们到处都在使用UTF-8。

5.XML文件

这通常不是问题,因为XML文件的标准编码是UTF-8。然而,他们应该始终从以下指令开始应该强制XML编辑器以UTF-8格式保存它们(看起来像大多数这样做,这里应该不会有问题)。

<?xml version=“1.0”encoding=“UTF-8”?>

6.专用变压器

标准XSLT变形金刚和其他人正在处理SAX事件没有序列化,因此编码没有问题。但是有一些特别的将内容传递给另一个库的变形金刚,其中包括序列化,可能需要提示才能使用正确的编码。一个问题是例如,NekoHTMLTransformer:https://issues.apache.org/jira/browse/COCOON-2063.

如果你认为可能有一个变压器在你的管道,添加T形变压器在每个步骤之间,输出XML在转换为temp1.xml、temp2.xml等的转换器之间查找你的变音和特殊字符被弄乱的地方。

7.您自己的XML序列化源

如果您有自己的需要序列化XML的Source实现,请使当然,UTF-8也能做到这一点。一个好主意是使用Cocoon的XML序列化程序,因为我们已经将其配置为上面的UTF-8。示例代码这样做就在这里:使用CoconXMLSerializerCode

更多信息

浏览器编码基础知识

获取页面

如果Cocoon应用程序需要读取请求参数包含特殊的字符,即前128个字符之外的字符ASCII字符,您需要注意所使用的编码。

通常,浏览器将使用与相同的编码向服务器发送数据包含提交表单(或其他内容)的页面。所以如果页面是使用UTF-8序列化后,浏览器将使用UTF-9提交表单数据。用户可以更改编码,但假设他/她不会这样做是很安全的(你做过吗?)。

浏览器将从<meta>标记中读取编码在HTML中<head>:

<meta http-equiv=“Content-Type”Content=“text/html;charset=UTF-8”>

或从HTTP标头内容类型:

内容类型:text/html;字符集=UTF-8

为了支持所有浏览器,必须同时包含这两者。这将由如果使用参数mime-type和encoding配置HTML序列化程序,如上所述。

发送表单数据

默认情况下,如果浏览器没有明确提及编码servlet容器将使用ISO-8859-1编码解码请求参数(独立于运行容器的平台)。所以在上面如果在序列化时使用UTF-8,我们将面临问题。异常,这可能会隐藏问题,并且在使用handy mvn jetty:运行Cocoon应用程序,jetty是否使用UTF-8违约。它不符合这里的servlet容器标准。

您要么必须使用默认编码配置您的容器如果可能的话,或者您必须使用servlet-filter过滤器解决方案,如设置字符编码筛选器.使用servlet过滤器还有一个优点,即它适用于任何servlet。假设您的webapp由多个servlet组成,Cocoon只是其中之一他们。有时,处理可以在另一个servlet中启动(它设置字符编码正确),然后转发给Cocoon,而其他时间处理可以在Cocoon servlet中立即开始。那就会是在Cocoon中无法知道请求参数编码是否需要是否纠正(见下文)。

Cocoon中的请求参数解码

修复错误的servlet容器

如果无法将servlet容器的默认编码设置为根据您的实际需要,可以将Cocoon配置为重新解码参数正确。假设servlet容器具有ISO-8859-1默认值编码集,但来自浏览器的请求实际上是用UTF-8编码的。然后可以使用以下属性配置Cocoon:

org.apache.cocoon.containerencoding=iso-8859-1org.apache.cocoon.formencoding=utf-8

对于Java内部人士:Cocoon实际上在内部做的是应用以下技巧可以正确解码参数:假设“value”是包含请求参数的字符串,则Cocoon将执行以下操作:

value=新字符串(value.getBytes(“ISO-8859-1”),“UTF-8”);

因此,它将错误解码的字符串重新编码为字节并对其进行解码使用正确的编码。第一个(示例中的ISO-8859-1)是包含编码,第二个是formencoding。

这不仅适用于Cocoon的核心概念,例如网站地图、CForms和其他人访问请求参数。还有其他组件,例如JSPGenerator,它访问原始HttpServletRequest对象,因此不会获取正确的重新编码的参数值(即,如果JSP页面本身将读取请求参数)。唯一可行的解决方案似乎是这里是servlet-filter。

本地覆盖表单编码

Cocoon非常适合发布到不同类型的设备很可能对于某些设备,需要使用不同的编码。在这种情况下,您可以为特定的使用SetCharacterEncodingAction的管道。

要使用它,首先要确保在map:actions中声明操作站点地图的元素:

<map:action name=“set-encoding”src=“org.apache.cocoon.acting.SetCharacterEncodingAction”/>

然后在所需位置调用操作,如下所示:

<map:act type=“set-encoding”><map:parameter name=“form-encoding”value=“some-other-encoding/></map:act>

操作系统准备

不影响请求参数解码,但有时操作系统中的文本文件、数据库通信等问题语言设置。使用非英语字符可能会带来问题,因为JVM似乎检测到了系统语言。例如,如果德语变音应为在Linux上用Cocoon正确处理,需要设置LANG环境变量如下所示:

export LANG=de

这是设置JVM语言环境的几种方法之一,另请参阅设置JvmLocale.

更多读数