`
chinajavawolf
  • 浏览: 116775 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
社区版块
存档分类
最新评论

(1)Tapestry5学习小结:中文问题

阅读更多
(1)    Tapestry中文问题
在目前的Tapestry5.0.5-SNAPSHOT版本中,Tapestry还没有提供对中文的支持。查找了Tapestry的邮件列表,看到如下的解决办法。
首先,可以写一个UTF8properties的java文件。该文件可以到w3c的网站上找到,代码如下: 
  1. public class Utf8Properties extends Properties {   
  2.        
  3.     /**  
  4.      * use serialVersionUID from JDK 1.1.X for interoperability  
  5.      */  
  6.     private static final long serialVersionUID = 5907218757225133892L;       
  7.        
  8.     /**  
  9.      * Encoding used to read properties from a file  
  10.      */  
  11.     public static final String ENCODING                    = "UTF-8";   
  12.        
  13.     /**  
  14.      * Characters used to write comment lines in a property file  
  15.      */  
  16.     private static final String COMMENT                    = "#!";   
  17.        
  18.     /**  
  19.      * Possible Separator between key and value of a property in a property  
  20.      * file  
  21.      */  
  22.     private static final String keyValueSeparators       = "=: \t\r\n\f";       
  23.        
  24.     /**  
  25.      * Creates an empty property list with no default values.  
  26.      *   
  27.      * @see java.util.Properties#Properties()  
  28.      */  
  29.     public Utf8Properties() {   
  30.       this(null);   
  31.     }   
  32.        
  33.     /**  
  34.      * Creates an empty property list with the specified defaults.  
  35.      *  
  36.      * @param   defaults   the defaults.  
  37.      * @see java.util.Properties#Properties(java.util.Properties)  
  38.      */  
  39.     public Utf8Properties(Properties defaults) {   
  40.       this.defaults = defaults;   
  41.     }      
  42.        
  43.     /**  
  44.      * Reads a property list (key and element pairs) from the input  
  45.      * stream. The stream is assumed to be using the UTF-8  
  46.      * character encoding or compatible.  
  47.      * Characters can be written with their unicode escape sequence.  
  48.      *   
  49.      * @param      inStream   the input stream.  
  50.      * @exception IOException if an error occurred when reading from the  
  51.      *               input stream.  
  52.      * @throws        IllegalArgumentException if the input stream contains a  
  53.      *          malformed Unicode escape sequence.  
  54.      * @see java.util.Properties#load(java.io.InputStream)  
  55.      */  
  56.     public synchronized void load(InputStream inStream) throws IOException {   
  57.       BufferedReader in = new BufferedReader(new InputStreamReader(inStream, ENCODING));   
  58.       String line = in.readLine();   
  59.          
  60.       while(line != null) {          
  61.           line = removeWhiteSpaces(line);   
  62.           if(!line.equals("") && COMMENT.indexOf(line.charAt(0)) == -1) {   
  63.             // Removes the beginning separators   
  64.             String property = line;   
  65.             // Reads the whole property if it is on multiple lines   
  66.             while(continueLine(line)) {   
  67.                 property = property.substring(0, property.length() - 1);   
  68.                 line = in.readLine();   
  69.                 property += line;   
  70.             }   
  71.             //property = new String(property.getBytes(ENCODING), ENCODING);   
  72.                
  73.             if(!property.equals("")) {                  
  74.                 int endOfKey = 0;   
  75.                 // calculates the ending index of the key   
  76.                 while(endOfKey < property.length() &&   
  77.                    (keyValueSeparators.indexOf(property.charAt(endOfKey)) == -1)) {   
  78.                   endOfKey++;   
  79.                 }                  
  80.                 String key   = property.substring(0, endOfKey);   
  81.                 String value = property.substring(endOfKey + 1, property.length());   
  82.                    
  83.                 key   = loadConversion(key);                   
  84.                 value = loadConversion(removeWhiteSpaces(value));   
  85.                    
  86.                 put(key, value);   
  87.                 //// For debugging only   
  88.                 //System.out.println("key: " + key);   
  89.                 //System.out.println("value: " + value);   
  90.                 //System.out.println("-----------");                 
  91.             }   
  92.           }   
  93.           line = in.readLine();   
  94.       }   
  95.     }   
  96.        
  97.     /**  
  98.      * A simple method to remove white spaces  
  99.      * at the beginning of a String  
  100.      * @param       line  the String to treat  
  101.      * @return      the same String without white spaces at the beginning  
  102.      */  
  103.     public static String removeWhiteSpaces(String line) {   
  104.       int index = 0;   
  105.       while(index < line.length() && keyValueSeparators.indexOf(line.charAt(index)) != -1) {   
  106.           index++;   
  107.       }        
  108.       return line.substring(index, line.length());   
  109.     }   
  110.        
  111.     /**  
  112.      * Replaces all characters preceded by a '\' with the corresponding special  
  113.      * character and converts unicode escape sequences to their value  
  114.      * @param       line  the String to treat  
  115.      * @return      the converted line  
  116.      */  
  117.     private String loadConversion(String line) {   
  118.       StringBuffer val = new StringBuffer(line.length());    
  119.          
  120.       int index = 0;   
  121.          
  122.       // Replace all the "\." substrings with their corresponding escaped characters    
  123.       for(; index < line.length(); index++) {   
  124.           char currentChar = line.charAt(index);   
  125.           if(currentChar == '\\') {   
  126.             index++;   
  127.             currentChar = line.charAt(index);   
  128.             switch(currentChar) {   
  129.             case 't':   
  130.                 currentChar = '\t';   
  131.                 break;   
  132.             case 'r':   
  133.                 currentChar = '\r';   
  134.                 break;   
  135.             case 'n':   
  136.                 currentChar = '\n';   
  137.                 break;   
  138.             case 'f':   
  139.                 currentChar = '\f';   
  140.                 break;   
  141.             case 'u':   
  142.                 index++;   
  143.                 // Read the xxxx   
  144.                 int value=0;   
  145.                 for (int i=0; i<4; i++) {   
  146.                   currentChar = line.charAt(index++);   
  147.                   //System.out.println(currentChar);   
  148.                   switch (currentChar) {   
  149.                   case '0': case '1': case '2': case '3': case '4':   
  150.                   case '5': case '6': case '7': case '8': case '9':   
  151.                       value = (value << 4) + currentChar - '0';   
  152.                       break;   
  153.                   case 'a': case 'b': case 'c':   
  154.                   case 'd': case 'e': case 'f':   
  155.                       value = (value << 4) + 10 + currentChar - 'a';   
  156.                       break;   
  157.                   case 'A': case 'B': case 'C':   
  158.                   case 'D': case 'E': case 'F':   
  159.                       value = (value << 4) + 10 + currentChar - 'A';   
  160.                       break;   
  161.                   default:   
  162.                       throw new IllegalArgumentException(   
  163.                       "Malformed \\uxxxx encoding.");   
  164.                   }                    
  165.                 }   
  166.                 // index must point on the last character of the escaped   
  167.                 // sequence to avoid missing the next character   
  168.                 index--;   
  169.                 currentChar = (char) value;   
  170.             default:       
  171.                 break;   
  172.             }   
  173.           }   
  174.           val.append(currentChar);   
  175.       }   
  176.          
  177.       return val.toString();   
  178.     }   
  179.        
  180.     /**  
  181.      * Replaces special characters with their '2-chars' representation.<br/>  
  182.      * For example, '\n' becomes '\\' followed by 'n'  
  183.      * @param       line  the String to treat  
  184.      * @return      the resulting String  
  185.      */  
  186.     private String storeConversion(String line) {   
  187.       int length = line.length();   
  188.       StringBuffer outBuffer = new StringBuffer(length*2);   
  189.          
  190.       for(int i = 0; i < length; i++) {   
  191.           char currentChar = line.charAt(i);   
  192.           switch(currentChar) {   
  193.           case '\\':   
  194.             outBuffer.append('\\');   
  195.             outBuffer.append('\\');   
  196.             break;   
  197.           case '\t':   
  198.             outBuffer.append('\\');   
  199.             outBuffer.append('t');   
  200.             break;   
  201.           case '\n':   
  202.             outBuffer.append('\\');   
  203.             outBuffer.append('n');   
  204.             break;   
  205.           case '\r':   
  206.             outBuffer.append('\\');   
  207.             outBuffer.append('r');   
  208.             break;   
  209.           case '\f':   
  210.             outBuffer.append('\\');   
  211.             outBuffer.append('f');   
  212.             break;               
  213.           default:   
  214.             outBuffer.append(currentChar);   
  215.           break;   
  216.           }   
  217.       }       
  218.       return outBuffer.toString();   
  219.     }   
  220.        
  221.     /**  
  222.      * Indicates wether the property continues on the next line or not  
  223.      * @param       line  the beginning of the property that might be continued on the next line  
  224.      * @return      true if the propertiy continues on the following line, false otherwise  
  225.      */  
  226.     private boolean continueLine(String line) {   
  227.       if(line != null && !line.equals("")) {   
  228.           return line.charAt(line.length() - 1) == '\\';   
  229.       }   
  230.       return false;   
  231.     }   
  232.        
  233.     /**  
  234.      * The same method as java.util.Properties.store(...)  
  235.      *   
  236.      * @param out  an output stream  
  237.      * @param header      a description of the property list  
  238.      * @see java.util.Properties#store(java.io.OutputStream, java.lang.String)  
  239.      */  
  240.     public void store(OutputStream out, String header) throws IOException {   
  241.       BufferedWriter output;   
  242.       output = new BufferedWriter(new OutputStreamWriter(out, ENCODING));   
  243.       if (header != null) {   
  244.           output.write("#" + header);   
  245.           output.newLine();   
  246.       }            
  247.       output.write("#" + new Date());   
  248.       output.newLine();   
  249.       // we do not want that a Thread could modify this Utf8Properties   
  250.       // while storing it    
  251.       synchronized (this) {   
  252.           Enumeration e = keys();   
  253.           while(e.hasMoreElements()) {   
  254.             String key = storeConversion((String)e.nextElement());   
  255.             String val = storeConversion((String)get(key));   
  256.                
  257.             output.write(key + "=" + val);   
  258.             output.newLine();   
  259.           }   
  260.       }   
  261.       output.flush();   
  262.     }   
  263. }   
 
然后将该文件编译后放到org\apache\tapestry\util包内。
接下来就可以修改其原文件了。要修改的原文件是org.apache.tapestry.internal.services包下的MessagesSourceImpl类。将该类的readProperties(Resource resource)方法中的java.util.Properties类改为我们编写的Utf8properties类。然后再修改org.apache.tapestry.internal.services包下的RequestImpl和ResponseImpl类文件。
将RequestImpl类文件中的方法改为如下内容:
  1. public String getParameter(String name)   
  2.     {   
  3.         String param = _request.getParameter(name);   
  4.         if(param != null)   
  5.             try  
  6.             {   
  7.                 param = new String(param.getBytes("ISO-8859-1"),"utf-8");   
  8.             }   
  9.             catch (UnsupportedEncodingException ex)   
  10.             {   
  11.                 //won't error   
  12.             }   
  13.         return param;   
  14.     }   
  15.     
  16.     public String[] getParameters(String name)   
  17.     {   
  18.         String[] params = _request.getParameterValues(name);   
  19.         try  
  20.         {   
  21.             for(int i=params.length-1;i>=0;i--){   
  22.                 params[i] = new String(params[i].getBytes("ISO-8859-1"),"utf-8");   
  23.             }   
  24.         }   
  25.         catch (UnsupportedEncodingException ex)   
  26.         {   
  27.             //won't error   
  28.         }   
  29.         return params;   
  30. }   
将ResponseImpl类文件中的方法改为如下内容:
  1. public PrintWriter getPrintWriter(String contentType) throws IOException   
  2.     {   
  3.         notBlank(contentType, "contentType");   
  4.         if(contentType.matches("text/html.*"))   
  5.             _response.setCharacterEncoding("utf-8");   
  6.         _response.setContentType(contentType);   
  7.     
  8.         return _response.getWriter();   
  9.     }   
  10. public OutputStream getOutputStream(String contentType) throws IOException   
  11.     {   
  12.         notBlank(contentType, "contentType");   
  13.         if(contentType.matches("text/html.*"))   
  14.             _response.setCharacterEncoding("utf-8");   
  15.         _response.setContentType(contentType);   
  16.     
  17.         return _response.getOutputStream();   
  18.     }   
最后重新编译打包就可以了。最后要注意的是此时我们所有应用用到的文件都要以utf-8格式进行编码.
 
该问题由LinuxBoy在邮件列表中提出,并得到了解决。
https://issues.apache.org/jira/browse/TAPESTRY-1294
分享到:
评论
4 楼 foxgst 2007-08-30  
5.0.5可以显示中文了。不过对于输入表单的中文没法正常提交,需要追加转换器。
TO KorbenZhang,把所有的页面都定义成了HTML文件,不是个优良解决方法。
3 楼 shiweili 2007-07-17  
我在开发中遇到了中文参数没办法正常工作的情况。
Tapestry4.0.2、JBoss4.0.3
用的组件是:contrib:XTile
Java代码如下:
@SuppressWarnings("deprecation")
public void handleCallback(IRequestCycle cycle) {
Object[] params = cycle.getListenerParameters();//在上里页面传过来如果是中文参数就不会运行下面的代码。
......}
Html:
<span jwcid="@contrib:XTile" listener="ognl:listeners.handleCallback"
sendName="sendValue" receiveName="recvCompletions" />
有谁也遇到类似的问题吗?

2 楼 KorbenZhang 2007-07-16  
不用这么复杂,在appModul中加入:
    public static PageResponseRenderer decoratePageResponseRenderer(
            @InjectService("PageMarkupRenderer")
            final PageMarkupRenderer markupRenderer,
            @InjectService("MarkupWriterFactory")
            final MarkupWriterFactory markupWriterFactory, final Object delegate)
        {

            return new PageResponseRenderer()
            {
                public void renderPageResponse(Page page, Response response) throws IOException
                {
                    MarkupWriter writer = markupWriterFactory.newMarkupWriter();
                    markupRenderer.renderPageMarkup(page, writer);
                    PrintWriter pw = response.getPrintWriter("text/html; charset=UTF-8");
                    writer.toMarkup(pw);
                    pw.flush();
                }
            };
        }

在改改web.xml的filter

	<filter>
		<filter-name>CharacterEncodingFilter</filter-name>
		<filter-class>
			org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	
	<filter-mapping>
		<filter-name>CharacterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

我的没有问题。
http://mp2.crecg.com/tfan-dprhm/


1 楼 Linuxboy 2007-07-09  
貌似5.0.5已经解决……

相关推荐

    tapestry学习入门资料

    "tapestry学习入门资料" Tapestry 是一个开源的基于 servlet 的应用程序框架,它使用组件对象模型来创建动态的、交互的 web 应用。 Tapestry 使得 Java 代码与 HTML 完全分离,利用这个框架开发大型应用变得...

    tapestry4和5学习资料

    1. **Tapestry5最新中文教程.doc**: 这份文档可能是针对Tapestry 5的最新中文教程,旨在为初学者提供一个易懂的入门指南。通常,它会涵盖基本的框架安装、环境配置、组件使用、事件处理、页面和组件生命周期等主题...

    tapestry5中文文档

    Apache Tapestry 5 是一个基于Java的Web应用开发框架,其设计目的是为了简化Web应用程序的构建,提供组件化的页面构建、输入验证...通过学习和实践Tapestry 5,开发者能够更好地理解和掌握现代Web应用开发的最佳实践。

    Tapestry5最新中文入门实例教程

    ### Tapestry5最新中文入门实例教程 #### 一、引言 Tapestry是一个使用Java语言创建Web应用程序的面向组件的开发框架。本教程旨在通过实际案例帮助读者掌握Tapestry 5的基本概念和核心功能,并体验其带来的高效开发...

    Tapestry5最新中文教程

    Apache Tapestry 5 是一个基于Java的开源Web应用程序框架,其设计目标是提供一个面向组件的开发环境,简化Web应用的构建。...通过学习和掌握Tapestry 5,开发者能够构建出更优雅、用户体验更好的Web应用程序。

    Tapestry 5 Building Web Applications.pdf

    本书主要面向希望学习或提高 Tapestry 5 技能的 Java 开发者。无论您是初学者还是有一定经验的开发者,都可以从中获得有价值的见解和实用的技巧。 #### 三、核心内容概览 ##### 1. **基础概念** - **Tapestry 5 ...

    tapestry源码 api等

    1. **Tapestry Core**: 这是Tapestry框架的基础部分,包含了核心组件、服务容器(Tapestry IoC)和页面生命周期管理。通过源码分析,我们可以理解其如何实现页面组件的渲染、事件处理和依赖注入。 2. **Tapestry ...

    Tapestry 学习文档

    Tapestry的错误报告和调试信息非常详细,有助于快速定位和解决问题。它还提供了一种友好的方式来显示用户友好的错误页面,而不是暴露技术堆栈跟踪。 学习Tapestry不仅意味着掌握其基本概念,还需要熟悉如何设计...

    Tapestry 5 電子書

    《Tapestry 5 電子書》是关于Java Web开发框架Tapestry 5的一本详尽指南,由Packt Publishing在2007年出版。这本书旨在帮助开发者深入理解和掌握Tapestry 5的各个方面,从而利用其强大功能构建高效、可维护的Web应用...

    tapestry官方中文文档

    虽然Tapestry 4的中文文档较少,但提供的《Tapestry4 用户指南》和《Tapestry4 快速启动》是宝贵的参考资料。它们将帮助初学者理解Tapestry的基本概念、组件使用、事件处理等方面的知识。 总的来说,Tapestry 4是...

    Tapestry5和jQuery集成tapestry5-jquery.zip

    Tapestry5和jQuery集成.使用jQuery以极少的兼容问题完全替换Prototype 和 Scriptaculous库 标签:tapestry5

    tapestry5以上的帮助事例,帮助文档与spring衔接文档

    Tapestry是一个基于控件的框架以致于用它开发Web应用类似开发传统的GUI应用。你用Tapestry开发Web应用时你无需关注以操作为中心的(Operation-centric) Servlet API.引用Tapestry网站上的一句话:"Tapestry用对象...

    Tapestry5开发文档手册.doc

    Apache Tapestry 5 是一个基于Java的Web应用开发框架,其核心理念是组件化开发,通过构建组件来创建页面。Tapestry 5 提供了一系列的功能,包括输入验证、本地化/国际化、状态管理和URL映射,使得开发者能更高效地...

    tapestry 5 ..........

    ### 关于Tapestry 5的关键知识点 #### 1. 什么是Tapestry? Tapestry是一个开源框架,用于创建动态、稳健且高度可扩展的Java Web应用程序。它补充并建立在标准Java Servlet API之上,因此可以在任何Servlet容器或...

    tapestry官方中文文档及中文字典

    "tapestry中文字典"可能包含对Tapestry框架中的专有名词、API和概念的中文解释,帮助读者更准确地理解和记忆。它可能是以索引形式存在,方便查找和查阅。 通过学习这些文档,开发者可以全面了解Tapestry 4的架构和...

    Tapestry5.1学习全集多本书整合

    是一本由多本Tapestry资料整合而成。包括一些Tapestry的实例。

    Tapestry 5开发指南(英文)

    1. **Tapestry 5基础** - **组件模型**:Tapestry 5的基础是组件,它们是可重用的、自包含的UI元素。组件可以是HTML元素、表单字段,甚至其他更复杂的组件。 - **页面和组件生命周期**:理解页面和组件的创建、...

    自己学习tapestry后做的小例子

    【标题】:“自己学习tapestry后做的小例子” Tapestry是Apache软件基金会的一个开源项目,它是一个基于Java的企业级Web应用框架。这个标题表明,这个压缩包包含了一个作者在学习Tapestry框架后制作的小型示例项目...

    Maven + Tapestry5.3.8 + Spring4.0.5 + Oracle10g

    1)解决了Tapestry5.3.8中文Bug问题 2)Tapestry 各种核心组件的使用 3)自带验证,自定义验证,验证码的生成 4)Tree组件的使用,Grid的各种使用(修改样式,排序,隔行换色等等),Loop组件的使用 5)集合Spring...

Global site tag (gtag.js) - Google Analytics