sping boot ,时间转换出现问题,竟然是因为HashMap

原文链接:http://www.imwinlion.com/archives/56



一、问题描述

同样的产品代码同样的数据库,在查询业务中,本地测试环境没问题,到了linux系统服务器出现问题

系统请求参数如下

isValid=1&corpId=53&pagesize=20&pagefrom=1&type=YS&datefrom=2017-12-07+00%3A00%3A01&dateto=2017-12-07+23%3A59%3A59&version=v2

二、问题分析及解决方法

在application-prod.properties开启应用 debug 级别日志配置

logging.config=classpath:logback-spring.xml
logging.level.root=DEBUG

分析日志发现如下

select
count(table000001_.id) as col_0_0_
from
partner_account table000001_
where
table000001_.bill_type=?
and table000001_.create_at>=?
and table000001_.create_at<=?
and table000001_.corp_id=53
[nio-8088-exec-8] druid.sql.Statement : {conn-10004, pstmt-20033} created. select count(table000001_.id) as col_0_0_ from partner_account table000001_ where table000001_.bill_type=? and table000001_.create_at>=? and table000001_.create_at<=? and table000001_.corp_id=53

[nio-8088-exec-8] druid.sql.Statement : {conn-10004, pstmt-20033} Parameters : [YS, 2017-12-07 00:00:00.0, 2017-12-07 00:00:00.0]
[nio-8088-exec-8] druid.sql.Statement : {conn-10004, pstmt-20033} Types : [VARCHAR, TIMESTAMP, TIMESTAMP]

其中的时间参数 2017-12-07 00:00:00.0 引起了我们的注意,这是string 类型转时间出现了问题

进一步分析发现问题出在Application.class

其中有行代码

private final  static Map<String,String> surports=new HashMap<String,String>();

static {

surports.put("yyyy-MM-dd HH:mm:ss","\\d{4}(\\-|/)\\d{2}(\\-|/)\\d{2}\\s\\d{2}:\\d{2}:\\d{2}");

surports.put("yyyy-MM-dd","\\d{4}(\\-|/)\\d{2}(\\-|/)\\d{2}");

}

这是 surports是一个hashmap

在做格式转换时,

我们需要对这个map。keyset进行轮询

@Override@Override public Date convert(String source) {

Date date = null;

for (String k:surports.keySet() ) {

if(RegExUtil.ereg(surports.get(k),source)){

SimpleDateFormat sdf  = new SimpleDateFormat(k);

source = source.replace('/','-');

try {

date = sdf.parse(source);

logger.debug("string=>time"+source +" match "+ k +" result ==>"+date.toString()); break;

} catch (ParseException e) {

logger.error(e.getStackTrace().toString());

}
}

}

return date;

}

我们理所当然地以为k 会依次从"yyyy-MM-dd HH:mm:ss" 到 "yyyy-MM-dd"

而实际上,在win系统上多次是这样的,但是在linux 上几乎全是反了的,那么问题找到了

怎么解决呢?就在于如下一行代码,将HashMap修改为LinkedHashMap即可

private final  static Map<String,String> surports=new LinkedHashMap<String,String>();

为什么呢,因为LinkedHashMap 是顺序的,HashMap是乱序的

3、扩展阅读

当我们查询出一个集合数据,往map里塞数据的时候,想要按照自己查询时的数据顺序进行排序。那么我们我们需要用LinkedHashMap

LinkedHashMap<String , Integer> map = new LinkedHashMap<String, Integer>();

map.put("d", 2);
map.put("c", 1);
map.put("b", 1);
map.put("a", 3);

System.out.println(map.keySet());

Map<String, Integer> map1 = new HashMap<String, Integer>();

map1.put("d", 2);
map1.put("c", 1);
map1.put("b", 1);
map1.put("a", 3);

System.out.println(map1.keySet())

输出结果:
[d, c, b, a]
[d, b, c, a]

以上可以看出,LinkedHashMap排序是有序的,而hashmap是无序的。

实际上我们可以使用如下代码进行全部map顺序测试

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class Test2 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        
        /////////////////////////////////////////////////////////////
        // TEST
        /////////////////////////////////////////////////////////////
        System.out.println("##  Hashtable  ##");
        Hashtable<String , String> ht = new Hashtable<String , String>();
        ht.put("1", "OOO");
        ht.put("3", "OOO");
        ht.put("2", "OOO");
        ht.put("5", "OOO");
        ht.put("4", "OOO");
        
        Iterator<String> it =  ht.keySet().iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
        
        /////////////////////////////////////////////////////////////
        // TEST
        /////////////////////////////////////////////////////////////
        System.out.println("##  TreeMap  ##");
        TreeMap<String , String> tm = new TreeMap<String , String>();
        tm.put("1", "OOO");
        tm.put("3", "OOO");
        tm.put("2", "OOO");
        tm.put("5", "OOO");
        tm.put("4", "OOO");

        Iterator<String> it2 =  tm.keySet().iterator();


        while (it2.hasNext()) {
            System.out.println(it2.next());
        }
        
        /////////////////////////////////////////////////////////////
        // TEST
        /////////////////////////////////////////////////////////////
        System.out.println("##  HashMap  ##");
        Map<String , String> hm = new HashMap<String , String>();
        hm.put("1", "OOO");
        hm.put("3", "OOO");
        hm.put("2", "OOO");
        hm.put("5", "OOO");
        hm.put("4", "OOO");

        Iterator<String> it3 =  hm.keySet().iterator();

        while (it3.hasNext()) {
            System.out.println(it3.next());
        }
        
        /////////////////////////////////////////////////////////////
        // TEST
        /////////////////////////////////////////////////////////////
        System.out.println("##  LinkedHashMap  ##");
        LinkedHashMap<String, String> lhm = new LinkedHashMap<String , String>();
        lhm.put("1", "OOO");
        lhm.put("3", "OOO");
        lhm.put("2", "OOO");
        lhm.put("5", "OOO");
        lhm.put("4", "OOO");

        Iterator<String> it4 =  lhm.keySet().iterator();

        while (it4.hasNext()) {
            System.out.println(it4.next());
        }
    }

}

该函数在linux上运行结果如下
[root@iZ94necw21cZ winlion]# 
[root@iZ94necw21cZ winlion]# 
[root@iZ94necw21cZ winlion]# javac TestMap.java 
[root@iZ94necw21cZ winlion]# ls -l
total 8
-rw-r--r-- 1 root root 1652 Dec 7 00:43 TestMap.class
-rw-r--r-- 1 root root 2648 Dec 7 00:38 TestMap.java
[root@iZ94necw21cZ winlion]# java TestMap
## Hashtable ##
5
4
3
2
1
## TreeMap ##
1
2
3
4
5
## HashMap ##
3
2
1
5
4
## LinkedHashMap ##
1
3
2
5
4
[root@iZ94necw21cZ winlion]# 
在windows 上运行结果如下
## Hashtable ##
5
4
3
2
1
## TreeMap ##
1
2
3
4
5
## HashMap ##
1
2
3
4
5
## LinkedHashMap ##
1
3
2
5
4

由此可见,大致上如下

Hashtable.keySet() 降序

TreeMap.keySet() 升序

HashMap.keySet() 乱序

LinkedHashMap.keySet() 原序

除了TreeMap.keySet(), JavaDoc中对keySet()返回值的顺序没有明确说明,

实际应用中,如果对顺序有明确要求,最好能明确的对其顺序进行整理。

展开阅读全文

sping配置在WEBLOGIC上实现出现问题

12-06

配置applicationContext.xml文件,将我的DAO类配置到里面rnrn[code=java]1. rn2. rn7. rn8. rn9. rn11. rn13. rn14. rn16. rn17. rn18. rn19. rn20. rn22. rn23. rn24. rn25. rn26. rn27. rn28. org.hibernate.dialect.Oracle9Dialect rn29. rn30. rn31. rn32. rn33. rn34. pojo/Bbsblock.hbm.xml rn35. rn36. rn37. rn38. rn40. rn41. rn42. rn43. rn[/code]rnrnrnrnrn设计的JSP界面[code=html]1.<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> rn2.<%@ page import="pojo.Bbsblock"%> rn3.<%@page import="dao.BlockDao"%> rn4.<%@page rn5. import="org.springframework.web.context.support.WebApplicationContextUtils"%> rn6. rn7. rn8. rn9. 查询 rn10. rn11. rn12. rn13. rn43. rn44. rn45. rn46. rn47. 全部客户 rn48. rn49. rn50. rn53. rn54. rn55. rn56. rn57. rn58. rn59. rn60. rn61. rn62. rn63. 姓名 rn64. rn65. rn66. 用户代码 rn67. rn68. rn69. 版块名称 rn70. rn71. rn72. 注册时间 rn73. rn74. rn75. 删除 rn76. rn77. rn78. <% rn79. request.setCharacterEncoding("utf-8"); rn80. response.setCharacterEncoding("utf-8"); rn81. String stemp = request.getParameter("temp"); rn82. String userName = request.getParameter("userName"); rn83. int temp = 0; rn84. if(stemp != null) rn85. temp = Integer.parseInt(stemp); rn86. rn87. //List allStudent = new ArrayList(); rn88. String pageNumber = request.getParameter("pageNumber"); rn89. int pageInt = 1; rn90. if(pageNumber == null || "".equals(pageNumber.trim())) rn91. pageInt = 1; rn92. else rn93. try rn94. pageInt = Integer.parseInt(pageNumber); rn95. catch(Exception e) rn96. pageInt = 1; rn97. rn98. rn99. if(pageInt < 1) rn100. pageInt = 1; rn101. rn102. rn103. int pageSize = 5;//定义一页的显示数 rn104. int stuAmount = 0;//定义总记录数 rn105. BlockDao blockDao = (BlockDao)WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()).getBean("blockDao"); rn106. if(temp == 0) rn107. stuAmount = blockDao.blockAmount();//获取总记录数 rn108. else rn109. stuAmount = blockDao.blockByNameAmount(userName); rn110. rn111. rn112. int totalPage = 1;//定义总页数totalPage rn113. totalPage = (stuAmount%pageSize==0)?(stuAmount/pageSize):((stuAmount/pageSize)+1); rn114. //如果要查询的page值大于totalPage,就将page值设置为totalPage rn115. if(pageInt > totalPage) rn116. pageInt = totalPage; rn117. rn118. rn119. rn120. try rn121. List list = new ArrayList(); rn122. if(temp == 0) rn123. //list = BlockDao.allBlock(); rn124. list = BlockDao.allBlocks(pageInt,pageSize); rn125. else rn126. //list = BlockDao.queryBlockByName(blockName); rn127. list = BlockDao.queryBlockByName(pageInt,pageSize,userName); rn128. rn129. rn130. Iterator iter = list.iterator(); rn131. Bbsblock block = null; rn132. while(iter.hasNext()) rn133. block = new Bbsblock(); rn134. block =(Bbsblock) iter.next(); rn135. %> rn[/code]rnrn在weblogic上配置好之后运行就报错rn[code=java]weblogic.servlet.jsp.CompilationException: Failed to compile JSP /theBlock.jsprntheBlock.jsp:47:35: No match was found for method getBean(java.lang.String) in type .rn BlockDao blockDao = (BlockDao)WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()).getBean("blockDao");rn ^-----------------------------------------------------------------------------------------------^rntheBlock.jsp:47:87: No match was found for method getServletContext() in type jsp_servlet.__theblock.rn BlockDao blockDao = (BlockDao)WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()).getBean("blockDao");rn ^----------------------^rntheBlock.jsp:51:77: This method cannot be accessed from a static context.rn rn[/code]rnrn这个到底是什么问题,纠结了一天了,求高手们帮助解决一下啊 论坛

没有更多推荐了,返回首页