Java中的UTF-8字符在MySQL中变为无效字符

时间:2018-02-17 03:43:14

标签: java mysql spring-jdbc

将来自基于外部REST / JSON的数据源的值作为特殊字符。我使用预先存在的实用程序CharDecoder.java转换它,它保持不变,但是在将它插入MySQL数据库(默认字符集是UTF-8)后,它从ć变为?。

我的程序流程如下:

外部数据源发送JSON - > CharDecoder(在tomcat7中的war文件中,处理特殊字符)然后填充一行 - >在MySQL数据库中。

MySQL数据库中的最终结果是无效字符。

开发环境信息:

  1. 使用的是Java 1.7。

  2. Maven 3.3.3,位于我的pom.xml的<properties>标记内:

    &LT; project.build.sourceEncoding&gt; UTF-8&lt; /project.build.sourceEncoding&gt;

  3. MacOS上的Eclipse Oxygen。

  4. 在macOS上运行Eclipse Oxygen - 在Project的属性视图内(单击项目,⌘I也称为COMMAND + I),它指出文本文件编码为UTF-8。

    当我使用代码库中的实用程序类进行转换时,它可以工作,但是当更新MySQL数据库中的行(该表的默认字符集是UTF-8)时,它将变为无效字符。

    所以,我将这个字符添加到我的字符数组:“ć”(它位于以“î”开头的同一行)。

    public class CharDecoder {
    
        public final static String chars [] = 
        {
            "ö", "ä", "ü", "Ö", "Ä", "Ü", "ß",
            "?", "\\", ",", ":", ";", "#", "+", "~", "!", "\"", "§", "$", "%",
            "&", "(", ")", "=", "<", ">", "{", "[", "]", "}", "/", "â", "ê",
            "î", "ô", "û", "Â", "Ê", "Î", "Ô", "Û", "á","ć", "é", "í", "ó", "ú",
            "Á", "É", "Í", "Ó", "Ú", "à", "è", "ì", "ò", "ó", "ù", "Á", "É", "Í",
            "Ó", "Ú", "°", "³", "²", "€", "|", "^", "`", "´", "'", " ", "@",
            "~", "*"
        };
    
        public final static String charsHtml[] = 
        { 
            "ö", "ä", "ü", "Ö", "Ä", "Ü",
            "ß", "?", "\\", ",", ":", ";", "#", "+", "&tilde;", "!", "\"",
            "&sect;", "$", "%", "&amp;", "(", ")", "=", "&lt;", "&gt;", "{",
            "[", "]", "}", "/", "&acirc;", "&ecirc;", "&icirc;", "&ocirc;",
            "&ucirc;", "&Acirc;", "&Ecirc;", "&Icirc;", "&Ocirc;", "&Ucirc;",
            "&aacute;", "&eacute;", "&iacute;", "&oacute;", "&uacute;",
            "&Aacute;", "&Eacute;", "&Iacute;", "&Oacute;", "&Uacute;",
            "&agrave;", "&egrave;", "&igrave;", "&ograve;", "&Ugrave;",
            "&Agrave;", "&Egrave;", "&Igrave;", "&Ograve;", "&Ugrave;",
            "&deg;", "&sup3;", "&sup2;", "&euro;", "|", "&circ;", "`",
            "&acute;", "'", " ", "@", "~", "*"
        };
    
        public final static String entities[] = { 
            "F6", "E4", "FC", "D6", "C4",
            "DC", "DF", "3F", "5C", "2C", "3A", "3B", "23", "2B", "7E", "21",
            "22", "A7", "24", "25", "26", "28", "29", "3D", "3C", "3E", "7B",
            "5B", "5D", "7D", "2F", "E2", "EA", "EE", "F4", "FB", "C2", "CA",
            "CE", "D4", "DB", "E1", "E9", "ED", "F3", "FA", "C1", "C9", "CD",
            "D3", "DA", "E0", "E8", "EC", "F2", "F9", "C1", "C9", "CD", "D3",
            "DA", "B0", "B3", "B2", "80", "7C", "5E", "60", "B4", "27", "20",
            "40", "98", "2A"
        };
    
        public static String inputToChar(String input) {
            return (inputTo(input, chars));
        }
    
        public static String inputTo(String input, String[] tc) {
            StringBuilder sb = new StringBuilder();
            boolean entity = false;
            input = input.replace ('+', ' ');
            String tokens = tc == charsHtml ? "%<>" : "%";
            for (StringTokenizer st = new StringTokenizer (input, tokens, true); st.hasMoreTokens(); ) {
            String token = st.nextToken();
            if (entity) {
                boolean replaced = false;
                for (int i = 0; i < entities.length; i++) {
                    if (token.startsWith (entities[i])) {
                        sb.append (tc[i]);
                        sb.append (token.substring (2));
                        replaced = true;
                        break;
                    }
                }
                if (!replaced) {
                    sb.append (token);
                }
                entity = false;
             } 
             else if (token.equals ("%")) {
                entity = true;
                continue;
             } 
             else if (token.equals ("<")) {
                sb.append ("&lt;");
             } 
             else if (token.equals (">")) {
                sb.append ("&gt;");
             } 
             else {
                sb.append (token);
             }
          }
          return (sb.toString ());
       }
    
       public static void main(String [] args) {
            String person1 = CharDecoder.inputToChar("Lukić");
            System.out.println(person1);
       }
    }
    

    为了使这个问题更加简单,我删除了刚刚创建了main()方法的JDBC代码(一个简单的JDBC Update Query)。当我运行这个main()方法时,输出是:

    Lukić
    

    这很好,我想要的。但是,当我使用Spring JDBC更新它时,在MySQL数据库(该表的默认字符集是UTF-8)中它变为:

    Luki?
    

    这肯定发生在数据库方面,我应该更改它(表的默认字符集为LATIN1)?​​

    我是否必须将整个数据库的默认字符集更改为LATIN1?我只是在那里抛出想法......

    有没有办法在不更改默认字符集的情况下修复此问题(不想破坏任何现有数据)......

2 个答案:

答案 0 :(得分:1)

<强>了useUnicode = YES&安培;的characterEncoding = UTF-8

将此信息添加到您的数据库网址

答案 1 :(得分:0)

如果你想获得全面的Unicode支持,你也可以全力以赴:

character_set_server=utf8mb4

请参阅:What is the difference between utf8mb4 and utf8 charsets in mysql?