JavaEE项目bug修复记——一场由特殊空字符(160号ASCII码)引发的血案

在维护JavaEE项目时,遇到批量导入Excel用户时因特殊空字符(160号ASCII码)导致的登录失败问题。通过对问题的分析,尝试了数据库函数修复失败,最终通过Java代码成功去除空字符。临时解决方案是创建JSP文件自动完成数据库中的用户名归一化。最终解决方案包括严格读取表格数据、忽略非法字符并增强单元测试。
摘要由CSDN通过智能技术生成

我负责维护的一个JavaEE项目中有这样一个功能:可以用poi批量导入Excel表中的学号并在该系统中创建对应的用户。上周三中午,接到用户反馈,将Excel导入系统后用其中的用户名出现了无法登陆提示用户名或密码错误的提示。

第一次问题分析:

在测试环境中导入该Excel表格后,发现数据库用户表中确实出现了该用户名,但仔细观察,其前后都有空格。看来问题的故障定位在于从Excel表中按数值型读出数据失败抛出异常后,数据被当做String类型直接写入了数据库。这样,当用户上传的Excel表中用户名字段前后包含空格时,直接被写入了数据库中。而当用户通过页面输入用户名密码登录时,用户名中的空格却被忽略掉了,导致后台按前端传入的用户名查询时数据库返回无此记录从而登录失败。

第一次修复尝试:

既然直到了问题的症结,那修复起来也就清晰了。具体思路就是利用MySQL提供的一些函数完成表中指定字段的空格去除,搜索得知有trim和replace两种方法。首先在导入了存在问题Excel表的测试环境中:

  • 备份数据库:由于要对数据库进行改动,所以在之前一定要进行备份。

    mysqldump -u 用户名 -p 数据库名 > 路径/文件名.sql
  • 尝试去除user表中Login字段的前后空格:

    UPDATE user SET Login=trim(Login);
    UPDATE user SET Login=replace(Login, ' ', '');

    以上两种尝试都以失败告终,最终结果显示:0 rows affected。分析多半出现在正常用户名前后的不是真正的空格,而是一些显示不出的ASCII码,为了方便探查,这里就用JDBC来查询吧。

第二次原因分析

在测试环境中,编写一段JDBC程序对SQL中某行有问题的数据读出,并逐字符转换为ASCII码对应的数字进行检查。在导入了MySQL的JDBC驱动jar包后,相关代码如下:

import java.sql.*;

public class CBugFind {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");

        String dbUrl = "jdbc:mysql://localhost:端口/数据库名?useSSL=true";
        String dbUserName = "root";
        String dbPassword = "这里是密码";
        Connection con = DriverManager.getConnection(dbUrl, dbUserName, dbPassword);

        Statement stat = con.createStatement();

        String sql = "SELECT * FROM user WHERE Id=78";  //78号用户的用户名恰有异常
        ResultSet rs = stat.executeQuery(sql);

        String strLogin = null;
        String strNumber = null;

        while (rs.next()) {
            strLogin = rs.getString("Login");
            for (int i = 0; i < strLogin.length(); i++) {
                System.out.println((int)strLogin.charAt(i));
            }        
        }

        rs.close();
        stat.close(); 
        con.close();

    }
}

运行后,部分结果如下:

160
50
48
49
55
48
48
48
50
48
49
48
49
50
160
32

看到了么,就是这个十进制为160的数在捣鬼,它又是何方神圣呢?其实是故人,就是HTML里常用的空格而已。在明白这一点后,我们就可以尝试将其去掉了。然而很不幸,经过多次尝试,也无法使用trim或replace成功将这个160号空格干掉。索性那就还是用Java吧:

public class CBugFixDemo1 {
    public static void main(String[] args) {
        String strUser = " 2017010801015 ";
        strUser = " 2017000201012  ";
        showAllChar(strUser);


        System.out.println("-------------------------------");
        // This is round fix1
        strUser 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值