如何解决这两个问题呢?
我们可以发现平时人工使用键盘输入密码的时候是没有这些问题的,那么我们是否可以模拟人工操作时的键盘输入方式呢?答案是肯定的,使用操作系统的API,模拟键盘发送消息事件给操作系统,可以避免所有浏览器等差异和安全性带来的问题。
我个人建议使用JNA(https://github.com/twall/jna),JNA是一种和JNI类似的技术,但是相对JNI来说更加易用。 JNA共有jna.jar和platform.jar两个依赖库,都需要引入,我们需要用到的在platform.jar中。从包结构可以看出,JNA中包含了mac、unix、win32等各类操作系统的系统API映射。如下图:
系统API映射关系在JNA的文章中有描述,如下:
数据类型的映射参见:https://github.com/twall/jna/blob/master/www/Mappings.md
本文中以windows为例演示下如何在支付宝的密码安全控件中输入密码。
JNA中关于windows平台的是com.sun.jna.platform.win32包中User32这个接口。这里映射了很多windows系统API可以使用。但是我们需要用到的SendMessage却没有。所以需要新建一个接口,映射SendMessage函数。代码如下:
1.import com.sun.jna.Native; 2.import com.sun.jna.platform.win32.User32; 3.import com.sun.jna.win32.W32APIOptions; 4. 5.public interface User32Ext extends User32 { 6. 7. User32Ext USER32EXT = (User32Ext) Native.loadLibrary("user32", User32Ext.class, W32APIOptions.DEFAULT_OPTIONS); 8. 9. /** 10. * 查找窗口 11. * @param lpParent 需要查找窗口的父窗口 12. * @param lpChild 需要查找窗口的子窗口 13. * @param lpClassName 类名 14. * @param lpWindowName 窗口名 15. * @return 找到的窗口的句柄 16. */ 17. HWND FindWindowEx(HWND lpParent, HWND lpChild, String lpClassName, String lpWindowName); 18. 19. /** 20. * 获取桌面窗口,可以理解为所有窗口的root 21. * @return 获取的窗口的句柄 22. */ 23. HWND GetDesktopWindow(); 24. 25. /** 26. * 发送事件消息 27. * @param hWnd 控件的句柄 28. * @param dwFlags 事件类型 29. * @param bVk 虚拟按键码 30. * @param dwExtraInfo 扩展信息,传0即可 31. * @return 32. */ 33. int SendMessage(HWND hWnd, int dwFlags, byte bVk, int dwExtraInfo); 34. 35. /** 36. * 发送事件消息 37. * @param hWnd 控件的句柄 38. * @param Msg 事件类型 39. * @param wParam 传0即可 40. * @param lParam 需要发送的消息,如果是点击操作传null 41. * @return 42. */ 43. int SendMessage(HWND hWnd, int Msg, int wParam, String lParam); 44. 45. /** 46. * 发送键盘事件 47. * @param bVk 虚拟按键码 48. * @param bScan 传 ((byte)0) 即可 49. * @param dwFlags 键盘事件类型 50. * @param dwExtraInfo 传0即可 51. */ 52. void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo); 53. 54. /** 55. * 激活指定窗口(将鼠标焦点定位于指定窗口) 56. * @param hWnd 需激活的窗口的句柄 57. * @param fAltTab 是否将最小化窗口还原 58. */ 59. void SwitchToThisWindow(HWND hWnd, boolean fAltTab); 60. 61.} |