(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.
     
  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

你可能感兴趣的:(Tapestry,Tapestry,Apache,F#,Web,HTML)