天天看點

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