最近公司的一个需求是在输入邮箱地址需要输入中文域名。之前的代码是我同事写的,然后叫我去看看代码哪里有了出问题,也就是说叫我去调试程序,IDE环境是在XP下的而服务器是部署在Unix下的,也就是说既要在本地测试通过了再部署到Unix下服务器上,感觉是繁琐了些,但是也是第一次亲密接触在Unix下部署web服务器。感觉是学到了许多。下面就具体问题具体问题具体分析:
首先我列出我的出现问题的代码如下:
Action中的代码:
/** * 设置邮件转发地址 * * @struts.action path="/mailbox/controller/addr_forward/action" * * */ public ActionForward modifyPrefForwardAddr(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { ActionForward actionForward = super.getCommSucc(mapping); ActionForward failForward = super.getCommFail(mapping); ActionMessages errorMsg = new ActionMessages(); ForwardAddrForm forwardForm = (ForwardAddrForm) form; String forward_add = forwardForm.getForwardAdd(); String mailboxid = forwardForm.getMailboxId(); String hideForwardAddStr = forwardForm.getHideForwardAdd(); String tid = forwardForm.getTid(); int hideForwardAddSumNumber = 3;// default value if (StringUtils.isNotBlank(hideForwardAdd_sum)) { try { hideForwardAddSumNumber = Integer.parseInt(hideForwardAdd_sum); } catch (NumberFormatException e) { e.printStackTrace(); } } String[] hideForwardAddrArrays = new String[hideForwardAddSumNumber]; String[] tmpHideForwardAddr = null; if (StringUtils.isNotBlank(hideForwardAddStr)) { //log.warn(hideForwardAddStr); hideForwardAddStr = hideForwardAddStr.trim(); tmpHideForwardAddr = hideForwardAddStr.split(","); } if (tmpHideForwardAddr != null) { int count = 0; for (String addr : tmpHideForwardAddr) { //.warn("HideForwardAddress: " + addr); if (StringUtils.isNotBlank(addr) && KennyUtil.isValidatorEmail(addr)) { //log.warn("Pass"); hideForwardAddrArrays[count] = addr; count++; if (count == hideForwardAddSumNumber) break; } else { // do nothing //log.warn("Ban"); } } } if (StringUtils.isBlank(tid) || StringUtils.isBlank(mailboxid)) { return null; } Mailbox mailbox = new Mailbox(); mailbox.setId(mailboxid); mailbox.setMailboxTmailId(tid); if (!KennyUtil.isValidatorEmail(forward_add)) { forward_add = null; } try { AccBus.modifyAccountMailForwardingAddress(mailbox, hideForwardAddrArrays, forward_add); // AccBus.modifyMailboxPrefForwardAdd(mailbox, forward_add); } catch (ServiceException e) { // e.printStackTrace(); TreeExceptionFactory.serviceErrorReturn(failForward, errorMsg, e); addMessages(request, errorMsg); return failForward; } return actionForward; }
校验中文字符代码:
/** * 检查是否含有中文字符 * * @param str * @return */ public static boolean isValidatorChinese(String str) { // boolean flag = str.length() != str.getBytes().length; // return flag; boolean flag = false; if (str != null) { char[] strCharArray = str.toCharArray(); log.warn("strCharArray"); for (int i = 0, l = strCharArray.length; i != l; ++i) { log.warn("for begin"); if (java.lang.Character.toString(strCharArray[i]).matches( "[ \\u4E00-\\u9FA5]+")) { flag = true; break; } } } return flag; }
校验邮箱地势是否合法代码:
/** * 检查邮件地址是否合法 * * @param emailAddress * @return */ public static boolean isValidatorEmail(String emailAddress) { boolean flag = GenericValidator.isEmail(emailAddress); log.warn("before==>" + flag); if (!flag && isValidatorChinese(emailAddress)) { // 邮件地址中含有中文,姑且暂时算有效。 log.warn("inner==>" + flag); int dian = emailAddress.indexOf('.'); int at = emailAddress.indexOf('@'); if (dian > 0 && at > 0) { flag = true; } } log.warn("after==>" + flag); return flag; }
问题1:同样的Web包,在不同服务器下运行出现的结果不同的。在我公司201服务器运行就可以添加中文域名邮箱转发地址,而在用虚拟机安装的217和210服务器上就不能。
尝试办法1:我针对这种情况就用日志在Action中的进行了跟踪,然后在unix下查看是否是乱码。我就用locale和env发现201的是UTF-8,217的也是UTF-8,而210的则是C(我也不懂这是什么编码),但是无论在哪个服务器上测试都是乱码,但是这就奇怪了,所以这种查看系统编码不是问题的解决办法。虽然会在某些会起作用,至少现在对于我来说不能。
尝试 办法2:于是继续进行下一步的判断,页面的判断,于是我再建立另外的一个页面进行替换,结果还是不行,而且页面是现实正常的,确定于页面无关。
尝试办法3:进行JS的检查,不断地alert(),结果那些被调用的JS都是正常的,这种方法又被排除。
尝试办法4:我查看了我们的数据库编码,但是都是GBK。想想,这与数据库编码没得多大影响吧,因为在其他的页面都可以正常显示。这种方法又排除了。
尝试办法5:最后我就再次仔细地进行JAVA后台代码的调试。结果发现在Acion中的调用校验的方法里有问题,就顺着去查看,发现这段代码的运行结果怎么都是false。
public static boolean isValidatorEmail(String emailAddress) { boolean flag = GenericValidator.isEmail(emailAddress); log.warn("before==>" + flag); if (!flag && isValidatorChinese(emailAddress)) { // 邮件地址中含有中文,姑且暂时算有效。 log.warn("inner==>" + flag); int dian = emailAddress.indexOf('.'); int at = emailAddress.indexOf('@'); if (dian > 0 && at > 0) { flag = true; } } log.warn("after==>" + flag); return flag;
于是就找到这个方法
isValidatorChinese
之前的代码是
boolean flag = str.length() != str.getBytes().length; return flag;
改后代码为:
boolean flag = false; if (str != null) { char[] strCharArray = str.toCharArray(); log.warn("strCharArray"); for (int i = 0, l = strCharArray.length; i != l; ++i) { log.warn("for begin"); if (java.lang.Character.toString(strCharArray[i]).matches( "[ \\u4E00-\\u9FA5]+")) { flag = true; break; } } } return flag;
结果就可以运行,试问大家这两段代码在判断中文上为什么运行不同呢?