• 网站异常发送异常代码到邮箱

    为了对用户的请求作统一处理,所以把Struct的Action封装成了一个AbstractAction。

    其中AbstractAction重写了Action类的execute方法,其中一个统一处理就是异常的处理。

    刚好最近想到了代码抛异常时就发邮件通知,这样既能立刻接收到异常的信息,也能对异常归档。

    刚开始打算直接用Exception的getCause()内容作为邮件内容发送,不过只有异常的原因,没有异常

    出现的定位信息:

    e.getCause()
    (java.lang.NullPointerException) java.lang.NullPointerException

    最后用到Exception的printStackTrace(PrintStream s)方法,并且采用了可变尺寸的线程池来发送邮件,主要是在以前构造的线程可用时将重用它们,代码如下:

    try {

    // code

    } catch (Exception e) {

    e.printStackTrace();

    logger.error(e.getCause());

    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    e.printStackTrace(new PrintStream(baos));

    String url = request.getRequestURL().toString() ;

    if(request.getQueryString()!=null){

    url+=”?” + request.getQueryString();

    }

    exception = “请求地址为:”+url+ “<br>” ;

    exception += “请求IP为:”+IPUtil.getIpAddr(request)+ “<br>” ;

    exception += baos.toString();

    //ex为AbstractAction类的属性

    //private ExecutorService ex = Executors.newCachedThreadPool();

    ex.execute(new Runnable() {

    @Override

    public void run() {

    // sendEmail(String addr, String title, String content)

    eMailService.sendEmail(“XXX@gmail.com”, “后台异常”,exception);

    }

    });

    }

    通过获取这些异常信息也可以发现某些对网站的异常访问,例如这次访问产生的异常:(下面代码用*取代了真实IP)

    请求地址为:http://******/front/indexNotLogin.do?action=viewAgreement&id=../../../../../../../../../../../../../sbin/../etc/./rc.d/../rc.d/.././passwd%00.htm 请求IP为:203.130.**.*** java.lang.reflect.InvocationTargetException at sun.reflect.GeneratedMethodAccessor239.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at

    这样就可以把203.130.**.***这个IP添加到黑名单了!

  • 科目二驾考

    今天终于过了科目二,虽然不是满分过,不过也是一次性通过..
    感觉在中国考驾照,弄得像高考一样紧张..
    这次跨省考试的四个小伙伴,只过了两个..上一批四个只过了一个..
    看来抗压能力很重要,所以把之前做的一些笔记写上来,方便要准备考科目二的童鞋参考(每个人的自身条件和车辆条件不一样,请作为模板参考,切勿硬套):

    1. 半坡停车启动:
    (1)上坡:上坡前先校正方向,尽量直行,上坡后车身与右边线间距为发动机盖右角刚好遮住右边线。
    (2)停车:通过左后视镜柄刚好看到中间黄线就停车。
    (3)启动:先松离合器到车身有点抖然后定住,慢慢松脚刹。
    2.侧位停车:
    (1)前进进入侧位停车时调整好与右边线距离,不要距离太大,否则倒车时前轮容易压线。
    (2)倒车时,从右倒视镜看到右后轮刚过侧位车库前横线,将方向盘往右打尽,倒车,直到左后视镜刚好看到后横线右直角,回正方向盘,直到左后轮刚好到左竖线(虚线),将方向盘往左打尽,直到发动机盖左角刚好越过左竖线(虚线)停车。

    3.倒车入库:
    (1)进入倒车库调整好与前横线距离很重要,距离合适倒车时不用修方向,距离为:进去的时候驾驶人对着第二个缺口和虚线第二个小段的交接处。
    (2)右转向入库:倒车到左倒视镜刚好遮住虚黄线时将方向盘往右打尽,慢慢倒车判断右后轮会不会压线,当入库快平衡后,快速回正方向盘,当倒后镜刚好完全挡住黄线就停车。
    (3)左转向出库:玻璃窗按钮到达黄虚线时开始打方向盘一圈+120度,驶出直角后,当倒后镜与虚黄线平衡则停车(发动机盖刚好遮住前面黄线)。
    (4)左转向入库:按左转向出库方向盘不动入库。
    (5)右转向出库:玻璃窗按钮超过黄虚线一点点时将方向盘往右打尽,出库快平衡时快速回正方向盘。
    4.直角转弯:贴近左边线行驶(发动机盖左角刚好有一点遮住左边线),行驶到驾驶室右门手柄刚好到横线位置,将方向盘往右打尽。
    5.连续转弯:
    尽量靠近右边线进入左湾:发动机盖左角刚到右边界,打左一圈加九十度,直到发动机盖左角刚到左边界,回正方向,直走一小段路,到发动机盖右角刚好到左边界,打右一圈加九十度。过程中以发动机盖左角与右边线是否平衡来判断方向打多了还是打小了,适当修正方向。

  • Ibatis列名无效

    最近在用ibatis连接Oracle,出现了几种列名无效的情况:

    — The error occurred in com/kingdee/youshang/basedata/mapper/ProductOnSale.xml.
    — The error occurred while applying a result map.
    — Check the ProductOnSale.ProductOnSaleResult.
    — Check the result mapping for the ‘id’ property.
    — Cause: java.sql.SQLException: 列名无效]; SQL was [] for task [SqlMapClient operation]

    将一些可能的原因列出来:

    一、SQL语句映射文件:

    1.查询语句返回的结果字段集不是所对应resultMap里面映射字段集的父集或相等,例如:

    resultMap 映射为:

    <resultMap class=”ProductOnSale” id=”ProductOnSaleResult”>
    <result column=”FID” javaType=”long” jdbcType=”BIGINT” property=”id”/>
    <result column=”FFUNDNAME” javaType=”string” jdbcType=”VARCHAR” property=”fundname”/>
    </resultMap>

     

    而SQL返回只有FFUNDNAME(没有FID):

    <select id=”findProducts” resultMap=”ProductOnSaleResult”>/*dialect*/
    SELECT FFUNDNAME FROM T_BS_PRODUCT_ON_SALE POS
    </select>

    2.resultMap配置里面的字段名前面加了表名:

    <resultMap id=”ProductOnSaleResult”>
    <result column=”POS.FID” javaType=”long” jdbcType=”BIGINT” property=”id”/>
    <result column=”POS.FFUNDNAME” javaType=”string” jdbcType=”VARCHAR” property=”fundname”/>
    </resultMap>

     

  • 网站开发人员面对的不仅是用户还有黑客

    网站被黑客攻击的很大原因是做的限制不够,但是做的限制过多也会造成用户体验不好。

    以前只是喜欢看黑客攻防的书,想不到这两天实战了。昨晚11点多,老大打电话来说网站短信验证码发送出现异常,问我在更新生产环境的时候有没有异常,让我确认一下是程序的问题还是外部的原因。记得没有修改过那一块的代码,但为了确定原因,马上打开了电脑然后远程控制到公司的办公电脑(出来工作后养成了一个小小的良好习惯就是下班的时候会把公司办公电脑的远程工具打开,这样网站有问题就可以立刻在家里远程操作)。

    首先检查了数据库记录,看到记录短信发送的数据表的数据真的一下子多了很多,仔细分析了表的数据发现不是程序问题,再用Chrome的调试功能发现了原来是一个手机短信验证接口被攻击了。因为短信量非常大,而且晚上基本上没有正常注册的用户,所以采取了暂停短息发送。然后顺便测试了一下一些其他网站,发现有些网站也有这个问题。

    第二天早上回到公司分析了访问日志表,总共有几百个肉鸡IP在攻击,而且一直持续不停。这几百个肉鸡通过攻击接口向不同的手机号码发送验证短信。之前只是做了隔60秒才能发送下一条信息的限制,没有限制一个手机号码一天接收的短信数目是因为短信通道有时候有问题,用户注册的时候需要请求好几次才能收到短信;而没有限制一个IP一天接收的短信数目是因为面向的用户主要是企业客户,一家企业往往只有一个对外的公网IP,而内部员工的数量可能不少。还是那句话“网站被攻击的很大原因是做的限制不够,但是做的限制过多也会造成用户体验不好”。经过讨论,得出几套方案:

    1.添加图片验证码。这个算是最简单和最有效的,不过对于用户体验来说,这个确实不好,因为用户已经习惯了发送手机验证码的时候只需要点击一个按钮。

    2.限制一天内向一个手机号码发送的短信数目。虽然可能会出现用户正常注册的时候需要请求几次才能收到短信,不过这个次数并不高,而且虽然面向的用户是企业用户,但手机号码是个人使用,限制发送的短信数目可行。然后自己赶紧的在后台代码添加了这个限制。

    3.将肉鸡IP拉入黑名单。这个可能会有小问题,因为是根据访问日志中访问接口达到一定数目来判断是否为肉鸡IP,有可能将有很多员工的公司的公网IP误认为是肉鸡IP(公司的IP刚开始就是被误以为是肉鸡IP)。不过把值定得合适,就会很少出现这种误杀,而且也会返回一个提示给用户“你的IP已被限制,请联系我们的客户”,这样即使是误杀,也可以手工处理。自己也赶紧在数据库新建了一张IP黑名单表,在代码里面做了这个黑名单过滤。没有直接使用iptables是因为这样的拦截是在系统级的,如果是误杀就不能将提示反馈给用户,用户可能完全不知道下一步要怎么操作。

    4.请求添加token。这个也能在一定程度上防止攻击,但是通过程序来完成的防御也会被绕过。

    (待续)

     

  • 密码保护:金蝶实习点滴

    这是一篇受密码保护的文章,您需要提供访问密码:

  • MySQL5.6在Windows7安装时停留在Attempting to start service的解决方法

    一.问题描述:

    之前在电脑安装过MySQL5.5,后来卸载了。到安装MySQL5.6就出现了到Configuration时总是停留在Attempting to start service的问题。google和百度和很久也没有解决,问题困扰了有两个月之久。安装出现的问题如下:

    二.尝试过的操作和结果:

    1.默认端口3306被占用?:在cmd下用了端口查看命令netstat -aon|findstr “3306”,没有发现端口被占用。

    2.服务已经存在?:在cmd用命令“sc delete MySQL56”删除了MySQL服务再重装还是不行。

    3.没有清理注册表?:用软件清除过,也手动清除过(运行Regedit,然后到“HKEY_LOCAL_MACHINE/SoftwareMicrosoft/Windows/CurrentVersion/Uninstall ”删除),重装的时候问题还是出现了。

    4.操作系统不能启动MySQL服务?:前段时间刚好安装了wamp,它自带的MySQL服务能启动,所以不是操作系统的问题。

    5.bug?:在MySQL的网站上面提交的bug中有这样的问题描述,不过觉得自己的不是,因为装回之前那个MySQL5.5的msi,也是同样的问题。

    三.解决方法:

    尝试过上面几种方法重装还是不成功后,在准备重装系统前想了下在系统中所有和MySQL有关的东西,最后把”C:\ProgramData“的MySQL文件夹删除了再重装就可以了(注:在windows中”C:\ProgramData“文件夹默认是隐藏的)。

    还有一个办法就是利用MySQL的installer进行卸载,运行installer后会显示三个选项:“Installer Updates”、“Add/Modify Products and Features”和“Remove MySQL Products”,选择“Remove MySQL Products”,这样会彻底卸载,重新安装就不会有问题了。

     

  • 博客之道——开启篇

    很早之前就开始写博客了,不过没有坚持下来,这次用上了WordPress,并且自己的域名还没有过期,会把写博客这项工作坚持下去。因为用文字和图片记录生活上的点点滴滴在自己看来是一种乐趣,所以在微博和微信上经常会刷同学们的屏。半年前用JSP+JavaBean+Servlet+MySQL写的那个博客也彻底弃用了,毕竟WordPress的用户体验很好。当初决定用Java写博客是因为JSP课程要做一个大实验,而自己觉得写一个博客挺有趣,因为可以在代码里面获得到很多有用的信息,例如访客的IP、从哪里转到这个博客、访问的时间、查询的字符串、浏览器类型和最感兴趣的模块等等,而这个JSP博客也实现了这些功能,只是把它部署到SAE上面,JVM的启动慢是一个问题,而且很多细节都没有处理好,所以就直接改用了WordPress。不过之前刚好有同学问到JSP+JavaBean+Servlet的设计流程是怎样的,就不想白白浪费了自己断断续续做了两个月的成果,把这个JSP博客放到了github上面(https://github.com/thatcat/jsp_blog/)。一些代码优化和数据库优化都没有做好优化,放上去只是让有需要的同学看看JSP+JavaBean+Servlet的设计流程是怎样的,不喜勿喷,哈哈。至于为什么不直接在CSDN或51CTO上面写博客,是因为比较喜欢直接操作数据库,特别是MySQL,而SAE提供了这方面的功能。