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
原因:项目使用的是hibernate 4的jar包,而配置文件中仍然使用hibernate3:
<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> </property> </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) 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 POST method"); out.println(" </BODY>"); out.println("</HTML>"); out.flush(); out.close(); } }
里面有一个成员变量count,初始值是0,每次使用浏览器访问(Get方法)时会递增1,会打印count的值。
运行结果如下:
count:1
count:2
count:3
count:4
count:5
。。。
注意:在不同的电脑上访问,也是递增一,而不是重新从0开始计数,即使用的同一份count。
总结:尽管每次请求使用的是不同的线程(一般情况下)来处理,但是这些线程使用的都是同一个servlet对象,所以servlet中的成员变量不是线程安全的。如果非要在servlet中使用成员变量应该怎么办呢?
像struts2 一样使用ThreadLocal ,参考http://blog.csdn.net/cselmu9/article/details/9128397
(4)spring aop没有拦截我要拦截的方法
在做一个商品管理系统的时候,我有一个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继承的。
参考:http://hw1287789687.iteye.com/blog/1882540
修改方法:
方式一:把父类也包含进去
<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> |
或者:
方式二:直接匹配父类,因为方法就在父类中
<aop:pointcut id="userServicePointcut" expression="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> |
(5)struts2 的form标签,会自动把当前的路径附加到表单提交的action的前面
商品管理系统有商品管理和超市管理,若没有登录直接进入就会跳转到登录页面。
比如直接在浏览器中输入http://localhost:8084/shop_goods/supermarket/viewSupermarket.action ,会自动跳转到登录页面。但是登录时报错,而直接进入登录页面登录就没有问题。这个问题折磨了一天半。
后来我直接看页面源码才发现问题。
浏览器中的源码是:
怎么凭空多出了上述红框中的内容?
<form id="user_login" name="user_login" action="/shop_goods/supermarket/user/login.action" method="post">
本来登录要提交到 http://localhost:8084/shop_goods/user/login.action
结果它给我提交到了http://localhost:8084/shop_goods/supermarket/user/login.action
结论就是:使用<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