0

当我将非 ascii 字母放入 .tag 文件时,这些字母未正确编码。

我的应用程序在码头 8.1.4 上运行。

如果 .tag 文件包含é,它将在生成的 HTML 页面中显示为é. 当我将相同的字母放入 JSP 文件时,它会正确显示。如果我将相同的字符作为参数传递给标签,它会正确显示。

文件的编码是 UTF-8。结果页面也以 UTF-8 编码。在 ubuntu 上从 Eclipse 运行应用程序时,或者在 debian 服务器上的 jar 中部署标签时,我遇到了同样的问题。

我检查了jetty生成的java文件的标签,并将éget转换为:

out.write('Ã');
out.write('©');

所以标签预编译成java类的时候编码是错误的。

我可以在这一步控制编码,还是在 .tag 文件中指定编码?


这里有更多细节。

标记文件只包含一个字符:é。它被编码为C3 A9以十六进制查看(正确的 UTF-8 编码)。java文件如下:

package org.apache.jsp.tag.web.tagLink.layout;

import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*;

public final class test_tag
    extends javax.servlet.jsp.tagext.SimpleTagSupport
    implements org.apache.jasper.runtime.JspSourceDependent {


  private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();

  private static java.util.Vector _jspx_dependants;

  private JspContext jspContext;   private java.io.Writer _jspx_sout;  private org.glassfish.jsp.api.ResourceInjector _jspx_resourceInjector;

  public void setJspContext(JspContext ctx) {
    super.setJspContext(ctx);
    java.util.ArrayList _jspx_nested = null;
    java.util.ArrayList _jspx_at_begin = null;
    java.util.ArrayList _jspx_at_end = null;
    this.jspContext = new org.apache.jasper.runtime.JspContextWrapper(ctx, _jspx_nested,
_jspx_at_begin, _jspx_at_end, null);   }

  public JspContext getJspContext() {
    return this.jspContext;   }

  public Object getDependants() {
    return _jspx_dependants;   }

  public void doTag() throws JspException, java.io.IOException {
    PageContext _jspx_page_context = (PageContext)jspContext;
    HttpServletRequest request = (HttpServletRequest) _jspx_page_context.getRequest();
    HttpServletResponse response = (HttpServletResponse) _jspx_page_context.getResponse();
    HttpSession session = _jspx_page_context.getSession();
    ServletContext application = _jspx_page_context.getServletContext();
    ServletConfig config = _jspx_page_context.getServletConfig();
    JspWriter out = jspContext.getOut();

    try {
      out.write('Ã');
      out.write('©');
    } catch( Throwable t ) {
      if( t instanceof SkipPageException )
          throw (SkipPageException) t;
      if( t instanceof java.io.IOException )
          throw (java.io.IOException) t;
      if( t instanceof IllegalStateException )
          throw (IllegalStateException) t;
      if( t instanceof JspException )
          throw (JspException) t;
      throw new JspException(t);
    } finally {
      ((org.apache.jasper.runtime.JspContextWrapper) jspContext).syncEndTagFile();
    }   } }

查看两个out.write调用的参数时,它们是C3 83C2 A9。其余的只是普通的 ASCII。

我创建了一个仅包含测试标记的 JSP 页面,当从浏览器查看时,我收到 : C3 83 C2 A9。这是使用 Fiddler2 拍摄的图片,浏览器是 IE8 :

从码头服务器接收到的数据.

如果我将é字符直接放在 JSP 页面中,它将被编码为C3 A9在 java 生成的文件中,并在浏览器收到的消息中。

4

2 回答 2

1

如果要生成 HTML,请不要在 JSP 中使用直接的 UTF-8 字节。

快速检查我最喜欢的 UTF-8 实用程序表明您的角色是:

http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=C3+A9&mode=bytes

因此,请改用以下方法之一。

  • é(数字 UTF-8 序列,在大多数浏览器中得到最佳支持)
  • é (十六进制 UTF-8 序列,适用于大多数浏览器)

这是一个 HTML 示例:

<html>
  <body>
    Example (numeric UTF-8): &#233; <br/>
    Example (hex UTF-8); &#x00E9; <br/>
  </body>
</html>
于 2013-02-08T13:03:14.457 回答
1

Jan 给出了正确的答案。

在标记文件中添加以下行将更正此问题:

<%@tag pageEncoding="UTF-8"%>
于 2013-08-02T15:53:47.787 回答