为什么在Java 6和Java 7中获取字符®(U + 00AE)是不同的?

时间:2019-01-29 11:35:16

标签: java unicode encoding jdk1.6 jdk1.7

这是我第一次在StackOverFlow上提问。 我英语说的不好。请原谅。

我的应用程序返回一个奇怪的字符时遇到问题。

  

PlayStation \ ufffd \ ufffd4 Pro

必须是这样的:

  

PlayStation®4Pro

我认为'\ ufffd'字符代表this, 'REPLACE CHARACTER'.

我的应用程序正在使用jdk 1.6。

我发现,当我将应用程序的jdk更改为1.7时,它会正确打印字符。

  

PlayStation®4Pro

更多信息

我的应用程序使用ibatis,并且问题发生在queryForObject之后。

public class A {
    private String content;
    public String getContent() {
        return content;
    }
}
A a = (A)queryForObject("mapper.getSomething", params);
return a;
// jdk1.6 - a.getContent() : PlayStation\ufffd\ufffd4 Pro
// jdk1.7 - a.getContent() : PlayStation®4 Pro

JDBC连接属性是这样的。

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://{IPADDRESS}/{DBNAME}?Unicode=true&characterEncoding=MS949&zeroDateTimeBehavior=convertToNull&socketTimeout=500000&connectTimeout=500000

更多信息2

  • 我没有ibatis和其他人进行测试。直接使用jdbc连接,但结果相同。
public class CharacterEncodeTest {
    // JDBC driver name and database URL
    static final String DB_URL = "jdbc:mysql://{IPADDRESS}/{DBTNAME}}?Unicode=true&characterEncoding=MS949&zeroDateTimeBehavior=convertToNull&socketTimeout=500000&connectTimeout=500000";

    //  Database credentials
    static final String USER = "{USER}";
    static final String PASS = "{PASSWORD}";

    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        try {
            //STEP 2: Register JDBC driver
            Class.forName("com.mysql.jdbc.Driver");

            //STEP 3: Open a connection
            System.out.println("Connecting to a selected database...");
            conn = DriverManager.getConnection(DB_URL, USER, PASS);
            System.out.println("Connected database successfully...");

            //STEP 4: Execute a query
            System.out.println("Creating statement...");
            stmt = conn.createStatement();

            String sql = "SELECT * from TABLE";
            ResultSet rs = stmt.executeQuery(sql);
            //STEP 5: Extract data from result set
            while (rs.next()) {
                //Retrieve by column name
                String content = rs.getString("content");

                //Display values
                System.out.print("content: " + content);
                // jdk1.6 : PlayStation\ufffd\ufffd4 Pro
                // jdk1.7 : PlayStation®4 Pro
            }
            rs.close();
        } catch (SQLException se) {
            // something
        } finally {
            // something
        }//end try
    }
}

问题

唯一的区别是仅更改jdk版本

  1. jdk 1.6和1.7关于此问题有什么区别?

  2. 在jdk 1.6中是否有解决此问题的解决方案?

4 个答案:

答案 0 :(得分:1)

不知道\ ufffd是什么,但是®符号是\ u00ae:https://www.fileformat.info/info/unicode/char/00ae/index.htm

答案 1 :(得分:1)

如果看到一个特殊字符有两个替换字符(?或?),则将UTF-8二进制数据转换为两字节序列,每个字节> 127,并且不能以单字节编码转换为字符只知道256个字符。

因此将字符串(Unicode)转换为UTF-8字节,然后将那些字节转换为某种单字节编码。

这可能是一个编码为UTF-8的URL参数,已被ISO-8859-1接收。或其他干预。网址。 URL解码/编码有一个encoding参数。尽管环境也很可能发生变化。如果在Java代码中使用®,则编辑器必须与javac编译器具有相同的编码,并且能够表示符号(请改为使用\u00AE进行检查)。

搜索默认编码用法:

  • string.getBytes()
  • new String(bytes)
  • URLDecoder.decode(string)
  • URLEncoder.encode(string)
  • FileReader/FileWriter
  • InputStreamReader(inputStream)
  • OutputStreamWriter(outputStream)

zip处理也获得了对文件名的Unicode支持。

反模式:

  • new String(string.getBytes(...), ...)

答案 2 :(得分:0)

不知道,但是我认为jdk 1.6和jdk 1.7使用不同类型的字符编码。请访问以下链接:

Does Java 1.7 use a different character encoding?

Why is my String returning "\ufffd\ufffdN a m e"

答案 3 :(得分:0)

最初有两个问号字符。看起来好像只有一个UTF8字符,但是您的代码无法读取4字节的序列,因此显示了2个问号-每个问号代表一个未知的2字节字符。您确定在代码永远无法处理UTF8时数据没有更改吗?之前可能是这个4字节字符:https://en.wikipedia.org/wiki/Enclosed_R吗?