天天看点

2013年工作中一些问题回顾和总结

2013年马上就要过去了,总结一些近期工作中出现的一些问题

(1)int的包装类型比较时始终不相等

项目中比较id时,始终都不相等,预期是相等的,当时快搞疯了,搞了半天才明白:id的类型是interger,而integer是对象,不能直接使用==来比较

2013年工作中一些问题回顾和总结

@test  

    public void test_integer(){  

        integer a=new integer(2);  

        integer b=new integer(2);  

        system.out.println(a==b);  

        system.out.println(a==(int)b);  

        system.out.println(a.intvalue()==b.intvalue());  

    }  

 运行结果:

2013年工作中一些问题回顾和总结

 注意下面的结果:

2013年工作中一些问题回顾和总结

(2)启动web项目时报错:找不到缓存类ecache

2013年工作中一些问题回顾和总结

<bean id="sessionfactory"  

        class="org.springframework.orm.hibernate3.localsessionfactorybean">  

        <property name="datasource" ref="datasource" />  

        <property name="packagestoscan">  

            <list>  

                <value>com.kingbase.domain</value>  

            </list>  

        </property>  

        <property name="hibernateproperties">  

            <props>  

            <prop key="hibernate.dialect">  

                    org.hibernate.dialect.mysqldialect  

                </prop>  

                <!-- <prop key="hibernate.dialect">  

                    org.hibernate.dialect.postgresqldialect  

                </prop> -->  

                <!--<prop key="hibernate.max_fetch_depth">0</prop> 

                -->  

                <prop key="hibernate.show_sql">true</prop>  

                <prop key="hibernate.format_sql">true</prop>  

                <prop key="hibernate.hbm2ddl.auto">update</prop>  

                <prop key="current_session_context_class">thread</prop>  

            </props>  

    </bean>  

(3)servlet中的成员变量是所有请求共用的

以下是一个普通的servlet:

2013年工作中一些问题回顾和总结

package com.shop.jn.web.servlet;  

import java.io.ioexception;  

import java.io.printwriter;  

import javax.servlet.servletexception;  

import javax.servlet.http.httpservlet;  

import javax.servlet.http.httpservletrequest;  

import javax.servlet.http.httpservletresponse;  

public class testservlet extends httpservlet {  

    private static final long serialversionuid = 3853433476973310016l;  

    private int count=0;  

    /** 

     * constructor of the object. 

     */  

    public testservlet() {  

        super();  

     * destruction of the servlet. <br> 

    public void destroy() {  

        super.destroy(); // just puts "destroy" string in log  

    public void doget(httpservletrequest request, httpservletresponse response)  

            throws servletexception, ioexception {  

        response.setcontenttype("text/html");  

        printwriter out = response.getwriter();  

        out.println("<!doctype html public \"-//w3c//dtd html 4.01 transitional//en\">");  

        out.println("<html>");  

        out.println("  <head><title>a servlet</title></head>");  

        out.println("  <body>");  

        out.print("    this is ");  

        out.print(this.getclass());  

        out.println(", using the get method");  

        out.println("  </body>");  

        out.println("</html>");  

        out.flush();  

        out.close();  

        count++;  

        system.out.println("count:"+count);  

    public void dopost(httpservletrequest request, httpservletresponse response)  

        out.println(", using the post method");  

}  

 里面有一个成员变量count,初始值是0,每次使用浏览器访问(get方法)时会递增1,会打印count的值。

运行结果如下:

count:1

count:2

count:3

count:4

count:5

。。。

 注意:在不同的电脑上访问,也是递增一,而不是重新从0开始计数,即使用的同一份count。

总结:尽管每次请求使用的是不同的线程(一般情况下)来处理,但是这些线程使用的都是同一个servlet对象,所以servlet中的成员变量不是线程安全的。如果非要在servlet中使用成员变量应该怎么办呢?

在做一个商品管理系统的时候,我有一个aop 类logintimesaop,需要拦截userservice 中的一个方法,目的是记录用户连续登录失败的次数,若连续登录失败3次,则锁定不允许再登录。

aop配置如下:

2013年工作中一些问题回顾和总结

<aop:config>  

        <aop:pointcut id="userservicepointcut"  

            expression="execution(* com.shop.jn.service.userservice.login(..)) and args(..,user2)" />  

        <aop:aspect id="myaspect" ref="logintimesaop">  

            <aop:around pointcut-ref="userservicepointcut" method="around"  

                arg-names="school,user2" />  

        </aop:aspect>  

</aop:config>  

但是始终没有像预期的那样拦截,要拦截的方法如下:

2013年工作中一些问题回顾和总结

@override  

    /**** 

     * not allowed to be rewritten 

     * @return : [state,user object] 

    public object[] login(final actioncontext actioncontext,  

            final genericuser user) throws unsupportedencodingexception,  

            exception {  

        // logger.info("login(actioncontext actioncontext,user user)");  

        object[] results = new object[2];  

        if (user == null) {  

            results[0] = loginutil.login_result_username_null;  

            return results;  

        } else {  

            return login(user.getusername(), user.getpassword());  

        }  

 上述方法是在com.shop.jn.service.userservice的父类suserservice中。

最终找到了原因:因为我要拦截的方法不在userservice中,尽管是可以从父类suserservice继承的。

修改方法:

方式一:把父类也包含进去

<aop:pointcut id="userservicepointcut"

         expression="(execution(* com.shop.jn.service.userservice.login(..))  or

          execution( * com.common.service.impl.suserservice.login(..)) ) and args(..,user2)" />

      <aop:aspect id="myaspect" ref="logintimesaop">

         <!--<aop:before method="before3" arg-names="user2"pointcut-ref="userservicepointcut"

            /> -->

         <aop:around pointcut-ref="userservicepointcut"method="around"

            arg-names="user2" />

      </aop:aspect>

或者:

方式二:直接匹配父类,因为方法就在父类中

         expression="execution(*com.common.service.impl.suserservice.login(..)) and args(..,user2)" />

(5)struts2 的form标签,会自动把当前的路径附加到表单提交的action的前面

商品管理系统有商品管理和超市管理,若没有登录直接进入就会跳转到登录页面。

后来我直接看页面源码才发现问题。

浏览器中的源码是:

2013年工作中一些问题回顾和总结

怎么凭空多出了上述红框中的内容? 

但是登录页面jsp源码如下:

2013年工作中一些问题回顾和总结

如果我把登录jsp源码改为: 

2013年工作中一些问题回顾和总结

 在浏览器中查看源码就是:

2013年工作中一些问题回顾和总结

<form id="user_login" name="user_login" action="/shop_goods/supermarket/user/login.action" method="post">  

结论就是:使用<s:form标签时,会自动把当前的路径附加到表单提交的action的前面

解决方法:

方式一:使用原生的form表单:

2013年工作中一些问题回顾和总结

<form action="<%=basepath%>user/login" method="post" >  

   <table>  

   <tr><td>username:</td> <td><s:textfield name="user.username" value="admin" ></s:textfield> </td></tr>  

   <tr><td>password:</td> <td><s:textfield name="user.password" value="admin2" ></s:textfield> </td></tr>  

   <tr> <td colspan="2"><s:submit value="login" ></s:submit> </td></tr>  

   </table>  

   <form>  

方式二:

使用s:url 标签,例如:

action='<s:url action="login" />'

欢迎访问 http://hw1287789687.iteye.com/blog/2053907