2013年馬上就要過去了,總結一些近期工作中出現的一些問題
(1)int的包裝類型比較時始終不相等
項目中比較id時,始終都不相等,預期是相等的,當時快搞瘋了,搞了半天才明白:id的類型是interger,而integer是對象,不能直接使用==來比較

@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());
}
運作結果:
注意下面的結果:
(2)啟動web項目時報錯:找不到緩存類ecache

<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:

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配置如下:

<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>
但是始終沒有像預期的那樣攔截,要攔截的方法如下:

@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的前面
商品管理系統有商品管理和超市管理,若沒有登入直接進入就會跳轉到登入頁面。
後來我直接看頁面源碼才發現問題。
浏覽器中的源碼是:
怎麼憑空多出了上述紅框中的内容?
但是登入頁面jsp源碼如下:
如果我把登入jsp源碼改為:
在浏覽器中檢視源碼就是:

<form id="user_login" name="user_login" action="/shop_goods/supermarket/user/login.action" method="post">
結論就是:使用<s:form标簽時,會自動把目前的路徑附加到表單送出的action的前面
解決方法:
方式一:使用原生的form表單:

<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