Motivation
通过近期收到的反馈和自己的经历,我觉得有必要写这么一篇博文,记录一些由服务器和PC之间的差异引起的不好判断的问题、其原因及其解决方法。
问题1:访问Servlet报错404,排除了各种错误的可能,仍不能正确访问
安全组策略
简单地说就相当于一道防火墙,我们可以自己设定过滤规则。还可以进一步的理解为一套黑白名单系统。
之所以提到安全组策略,是因为,我们遇上这个问题的一个可能就是,云服务器的安全组策略中没有允许80端口或者8080端口访问。
以阿里云服务器为例,以下是操作步骤:
①登录阿里云官方网站,点击右上角的控制台
②点击左侧“云服务器ECS”选项卡
③点击下方自己的云服务器实例
④点击右侧“管理”
⑤点击左侧二级菜单中的“本实例安全组”
⑥点击右侧“配置规则”
⑦在此时弹出的页面中,选择左上方“入方向”选项卡
在列表中的第三行,看是否开放了80或8080端口,如果没有开放,至少可以说明你服务器连接不通的原因之一就在这了。否则,回去继续检查代码的问题。
⑧如果上一步你没有看到80或8080端口,点击页面右上方“添加安全组规则”按钮
⑨按照下图配置即可,之后按右下角“确定”按钮
到这里,安全规则就添加完了,你也可以照猫画虎开放其他必要的端口,然后再测试一下,可能就通了,或者变了其他的报错信息,再具体排除。
问题2:用自己实现的MD5加密算法对用户密码进行加密,发现相同的密码明文在PC(开发用的电脑)上和服务器端得到的密文(即散列值)不同
加密函数代码如下:
public static String getCiphertext(String password) {
try {
byte[] btPassword = password.getBytes();
// 获得MD5摘要算法的 MessageDigest 对象
MessageDigest md5 = MessageDigest.getInstance("MD5");
// 使用指定的字节更新摘要
md5.update(btPassword);
// 获得密文
byte[] binaryCiphertext = md5.digest();
// 把密文转换成十六进制的字符串形式
return toString(binaryCiphertext);
} catch (NoSuchAlgorithmException e) {
return null;
}
}
当执行以下代码时:
String palinText = "1234567890";
String cipherText = getCiphertext(palinText);
System.out.println(cipherText);
在服务器端得到的输出结果是:
28C2596CF7EFD7548B02854ABC210650
而PC上得到的输出结果是:
F54F990C541048704B7EB806A703DE04
这就很困惑了,在没写注册功能的时候,单独测试登录功能就比较麻烦,因为手动给数据库里填的值时机登录的时候验证通不过,暂时留着个已知Bug不管也很是不爽。
经过一番搜索,终于在一篇问答帖中找到了来自大神的答案:
关键在于
byte[] btPassword = password.getBytes();
getBytes()这个方法应该传入一个指定的字符集,如"UTF-8",否则会根据当前应用环境上下文中的字符集来编码,造成差异。
将这行代码改为:
byte[] btPassword = password.getBytes("UTF-8");
就可以发现,无论在什么环境下,相同明文经过MD5之后得到的散列值是一致的。
后记
这篇博文主要想说一些平常在开发过程中不会遇到,而在往服务端部署时会遇到的问题及其解决方法,目前收集的问题还比较少,根据以后我自己的开法经历和大家的反馈会不断添加新的东西上去。鼓励大家把自己在开发过程中遇到的,各种各样的问题及其解决方案共享出来,创造更加绿色、开放、共享的开发交流环境。