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

简介:

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

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

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

Java代码   收藏代码
  1. @Test  
  2.     public void test_integer(){  
  3.         Integer a=new Integer(2);  
  4.         Integer b=new Integer(2);  
  5.         System.out.println(a==b);  
  6.         System.out.println(a==(int)b);  
  7.         System.out.println(a.intValue()==b.intValue());  
  8.     }  

 运行结果:

 注意下面的结果:

 

 

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

原因:项目使用的是hibernate 4的jar包,而配置文件中仍然使用hibernate3

Xml代码   收藏代码
  1. <bean id="sessionFactory"  
  2.         class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
  3.         <property name="dataSource" ref="dataSource" />  
  4.         <property name="packagesToScan">  
  5.             <list>  
  6.                 <value>com.kingbase.domain</value>  
  7.   
  8.             </list>  
  9.         </property>  
  10.         <property name="hibernateProperties">  
  11.             <props>  
  12.             <prop key="hibernate.dialect">  
  13.                     org.hibernate.dialect.MySQLDialect  
  14.                 </prop>  
  15.                 <!-- <prop key="hibernate.dialect">  
  16.                     org.hibernate.dialect.PostgreSQLDialect  
  17.                 </prop> -->  
  18.                 <!--<prop key="hibernate.max_fetch_depth">0</prop> 
  19.                 -->  
  20.                 <prop key="hibernate.show_sql">true</prop>  
  21.                 <prop key="hibernate.format_sql">true</prop>  
  22.                 <prop key="hibernate.hbm2ddl.auto">update</prop>  
  23.                 <prop key="current_session_context_class">thread</prop>  
  24.             </props>  
  25.         </property>  
  26.     </bean>  

 

 

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

以下是一个普通的servlet:

Java代码   收藏代码
  1. package com.shop.jn.web.servlet;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5.   
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServlet;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10.   
  11. public class TestServlet extends HttpServlet {  
  12.   
  13.     private static final long serialVersionUID = 3853433476973310016L;  
  14.     private int count=0;  
  15.   
  16.     /** 
  17.      * Constructor of the object. 
  18.      */  
  19.     public TestServlet() {  
  20.         super();  
  21.     }  
  22.   
  23.     /** 
  24.      * Destruction of the servlet. <br> 
  25.      */  
  26.     public void destroy() {  
  27.         super.destroy(); // Just puts "destroy" string in log  
  28.     }  
  29.   
  30.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  31.             throws ServletException, IOException {  
  32.   
  33.         response.setContentType("text/html");  
  34.         PrintWriter out = response.getWriter();  
  35.         out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");  
  36.         out.println("<HTML>");  
  37.         out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");  
  38.         out.println("  <BODY>");  
  39.         out.print("    This is ");  
  40.         out.print(this.getClass());  
  41.         out.println(", using the GET method");  
  42.         out.println("  </BODY>");  
  43.         out.println("</HTML>");  
  44.         out.flush();  
  45.         out.close();  
  46.         count++;  
  47.         System.out.println("count:"+count);  
  48.     }  
  49.   
  50.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  51.             throws ServletException, IOException {  
  52.   
  53.         response.setContentType("text/html");  
  54.         PrintWriter out = response.getWriter();  
  55.         out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");  
  56.         out.println("<HTML>");  
  57.         out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");  
  58.         out.println("  <BODY>");  
  59.         out.print("    This is ");  
  60.         out.print(this.getClass());  
  61.         out.println(", using the POST method");  
  62.         out.println("  </BODY>");  
  63.         out.println("</HTML>");  
  64.         out.flush();  
  65.         out.close();  
  66.     }  
  67.   
  68. }  

 里面有一个成员变量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配置如下:

Xml代码   收藏代码
  1. <aop:config>  
  2.   
  3.         <aop:pointcut id="userServicePointcut"  
  4.             expression="execution(* com.shop.jn.service.UserService.login(..)) and args(..,user2)" />  
  5.         <aop:aspect id="myAspect" ref="loginTimesAop">  
  6.               
  7.             <aop:around pointcut-ref="userServicePointcut" method="around"  
  8.                 arg-names="school,user2" />  
  9.         </aop:aspect>  
  10. </aop:config>  

 

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

Java代码   收藏代码
  1. @Override  
  2.     /**** 
  3.      * Not allowed to be rewritten 
  4.      * @return : [state,user object] 
  5.      */  
  6.     public Object[] login(final ActionContext actionContext,  
  7.             final GenericUser user) throws UnsupportedEncodingException,  
  8.             Exception {  
  9.         // logger.info("login(ActionContext actionContext,User user)");  
  10.         Object[] results = new Object[2];  
  11.         if (user == null) {  
  12.             results[0] = LoginUtil.LOGIN_RESULT_USERNAME_NULL;  
  13.             return results;  
  14.         } else {  
  15.             return login(user.getUsername(), user.getPassword());  
  16.         }  
  17.     }  

 上述方法是在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 ,会自动跳转到登录页面。但是登录时报错,而直接进入登录页面登录就没有问题。这个问题折磨了一天半。

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

浏览器中的源码是:

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

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

 

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

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

Html代码   收藏代码
  1. <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表单:

Html代码   收藏代码
  1. <form action="<%=basePath%>user/login" method="post" >  
  2.    <table>  
  3.    <tr><td>username:</td> <td><s:textfield name="user.username" value="admin" ></s:textfield> </td></tr>  
  4.    <tr><td>password:</td> <td><s:textfield name="user.password" value="admin2" ></s:textfield> </td></tr>  
  5.    <tr> <td colspan="2"><s:submit value="login" ></s:submit> </td></tr>  
  6.      
  7.    </table>  
  8.    <form>  

 

方式二:

使用s:url 标签,例如:

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

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

相关文章
|
10月前
|
开发者
思考你的工作
为什么你明明每天工作很努力,但依然感觉自己的技术进步很慢?
47 0
|
缓存 安全 Java
分享几个工作中实用的代码优化技巧!
前言之前分享一篇代码优化的文章:条件语句的多层嵌套问题优化,助你写出不让同事吐槽的代码!今天再次分享一些我日常工作中常用的代码优化技巧,希望对大家有帮助!文章首发在公众号(月伴飞鱼),之后同步到个人网站:xiaoflyfish.cn/觉得有收获,希望帮忙点赞,转发下哈,谢谢,谢谢正文类成员与方法的可见性最小化举例:如果是一个private的方法,想删除就删除如果一个public的service方法,或者一个public的成员变量,删除一下,不得思考很多。使用位移操作替代乘除法计算机是使用二进制表的位移操作会极大地提高性能。&lt;&lt; 左移相当于乘以 2;&gt;&gt; 右移相当于除以2,但它会忽略符号位,空位
|
IDE JavaScript 定位技术
2021年,工作发生了动荡.....
你能相信在过去的两年里,我们的工作方式发生了动荡吗? 开始的时候很艰难,但现在,2021年的结束就在眼前,我们已经习惯了远程办公、在线办公,并期望市场能赶上新常态。 对远程办公团队(尤其是开发团队)的创新和协作的要求,可能是我们目前可以观察到的行业中最强烈的趋势之一。
2021年,工作发生了动荡.....
|
前端开发
2020.07 G2 工作小结
? 修复的一些问题 修复 interval 下 shape='line' 设置 lineCap: 'round' 样式失效 Tip: 可用于进度条的绘制,相比于市面上现有的前端进度条组件,可以做到大小的自适应。 chart .interval() .position('const*value') .shape('line') .style({
|
Web App开发 移动开发 前端开发
工作中的一些知识总结
跳转 跳转登陆页 if(HybridMethod.isApp()) { RainbowBridge.callMethod('JsInvokeAppScope', 'goLogin'); } else { var _index = window.
1975 0
|
Web App开发 消息中间件 NoSQL