apache commons 小览

也许大家知道apache可能是从:apache httpd,tomcat,struts,ant,log4j,dom4j,...还有许多作为java程序员都知道的框架.ASF(Apache Software Foundation)对java 程序员来说真的挺重要的,至少从现在的b/s来看是这样的.可能有好多人和我一样都是这样认识ASF的.

 

今年在写一个java项目,在项目中有一个读取xml文件并解析其内容转换成项目菜单的小应用.由于以前习惯(或是熟悉)用DOM解析。而且在java的api也有这个包.马上动手用了一会就搞定,这鼓吹一下"规范"的好处.只要你在asp,php中学会了DOM.当你用在java上基本没有难度.回到正题!写完后,代码大体如下:

import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class ReadXMLMenu { private static ReadXMLMenu xmlMenu=null; private Document doc=null; private List<SystemMenu> parentMenu=new ArrayList<SystemMenu>(); private Map<Integer,List<SystemMenu>> childMenu=new HashMap<Integer,List<SystemMenu>>(); private ReadXMLMenu(String xmlfile)throws Exception { DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance(); dbf.setIgnoringElementContentWhitespace(true); DocumentBuilder db=dbf.newDocumentBuilder(); doc=db.parse(new File(xmlfile)); readMainMenu(); } public static synchronized ReadXMLMenu getInstance(String xmlfile)throws Exception{ if(xmlMenu==null){ xmlMenu=new ReadXMLMenu(xmlfile); } return xmlMenu; } private void readMainMenu(){ NodeList maincols=doc.getElementsByTagName("main"); for(int i=0;i<maincols.getLength();i++){ Element tmpEle=(Element)maincols.item(i); String mainlab=tmpEle.getAttribute("lab"); String mainanchor=tmpEle.getAttribute("default"); SystemMenu tmpMenu=new SystemMenu(mainlab,mainanchor); this.getParentMenu().add(tmpMenu); if(tmpEle.hasChildNodes()){ readChildMenu(i); } } } private void readChildMenu(int parentIndex){ List<SystemMenu> localChildList=new ArrayList<SystemMenu>(); Element childNodeCols=(Element)doc.getElementsByTagName("main").item(parentIndex); NodeList childCols=childNodeCols.getElementsByTagName("child"); for(int j=0;j<childCols.getLength();j++){ Element tmpChildEle=(Element)childCols.item(j); //anchor Node anchorNode=tmpChildEle.getElementsByTagName("anchor").item(0); String childlab=anchorNode.getFirstChild().getNodeValue(); StringBuffer childanchor=new StringBuffer(); Node tmpNode=anchorNode.getNextSibling(); if(tmpNode.getNodeType()==Node.TEXT_NODE){ tmpNode=anchorNode.getNextSibling().getNextSibling(); } //link String childlink=tmpNode.getFirstChild().getNodeValue(); childanchor.append(childlink); if(tmpChildEle.getChildNodes().getLength()>2){ Node childanchorparam=tmpChildEle.getLastChild(); if(childanchorparam.getNodeType()==Node.TEXT_NODE){ childanchorparam=childanchorparam.getPreviousSibling(); } //param value String childlinkparam=childanchorparam.getFirstChild().getNodeValue(); if(childanchorparam.getNodeName().equals("param") && childanchor.length()>0){ if(childlink.indexOf("?")!=-1){ childanchor.append("&"); }else{childanchor.append("?");} childanchor.append(childlinkparam+"=|"); } } SystemMenu tmpChildMenu=new SystemMenu(childlab,childanchor.toString()); localChildList.add(tmpChildMenu); } this.getChildMenu().put(parentIndex, localChildList); } public List<SystemMenu> getParentMenu() { return parentMenu; } public Map<Integer, List<SystemMenu>> getChildMenu() { return childMenu; } public List<SystemMenu> getSpecialChildMenu(int parentID){ List<SystemMenu> localChildList=new ArrayList<SystemMenu>(); Object ob=this.getChildMenu().get(parentID); if(ob!=null){ localChildList=(List<SystemMenu>)ob; } return localChildList; } }

 

除了在whitespace上费了点时间.其它基本上不费事.写完后不久看到一篇文章讲用Digester来解析XML,你注意到了么在struts 1.29或1.38中都有引用这个jar文件.不信你找到struts-1.3.8/apps/struts-blank-1.3.8.war 在eclipse中导入一下就会看到这个jar.从哪后我知道了ASF有一个commons project.项目的url:http://commons.apache.org/

 

你发现了吧,该项目下有好多子项目都在别的框架中用到.所以开始时我说了这句:"对java 程序员来说真的挺重要的".再没过多久拿到一本:Jakarta Commons经典实例.在这要说的是这两个子项目:
org.apache.commons.codec
org.apache.commons.lang

 

1.lang:
看一看你在写的项目中有没有引入这个jar文件.看一看下面的对比是否有必要在没有引入的时候引入他.
1.1对于习惯了脚本语言的我来说,java提供的真是太少了.比如我想判断一个字符串是否有值(不论是数字或是字符串,只要不是空,null就好).
google到的:

public static boolean hasValue(String str) { try { if (null != str.trim() && !"".equals(str.trim())) { if(str.trim().length() >0 ) return true; } } catch (NullPointerException e) { return false; } return false; }

 

lang提供的StringUtils,只要一行即可:

public static boolean hasValue(String str) { return StringUtils.isNotBlank(str); }

 

1.2对于request.getParameter获取的字符串转成数字.如果不判断是否是数字的情况下直接用Integer.valueOf后果可想而知
google到的

public static boolean isNumber(String str){ boolean isbool=true; try { Integer.parseInt(str); } catch (NumberFormatException e) { // TODO Auto-generated catch block isbool=false; } return isbool; }

 

lang提供的StringUtils,只要一行即可:

public static boolean isNumber(String str){ return StringUtils.isNumeric(str); }

 

1.3对于日期的格式化

public static String formateddateymd(Date date){ String fordate=""; try { if(date!=null){ SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); fordate=sdf.format(date); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return fordate; }

 

lang提供的DateFormatUtils,只要一行即可:

public static String formateddateymd(Date date){ return (date!=null)?DateFormatUtils.ISO_DATE_FORMAT.format(date):""; }

 

1.4生成指定位数的随机数
google到的

public synchronized static String genRandomNum(int pwd_len) { // 35是因为数组是从0开始的,26个字母+10个数字 final int maxNum = 10; // 生成的随机数 int i; // 生成的密码的长度 int count = 0; //char[] str = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k','l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y','z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; char[] str = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; StringBuffer pwd = new StringBuffer(""); Random r = new Random(); while (count < pwd_len) { // 生成随机数,取绝对值,防止生成负数,生成的数最大为36-1 i = Math.abs(r.nextInt(maxNum)); if (i >= 0 && i < str.length) { pwd.append(str[i]); count++; } } return pwd.toString(); }

 

上帝呀!真是挺长的.看lang提供的:RandomStringUtils

 

public synchronized static String genRandomNum(int count) { return RandomStringUtils.randomAlphanumeric(count); }

 

randomAlphanumeric是由:大,小字符和数字组成的,类似这样的:qK4p1t8RHxTk
randomNumeric是只有数字组成的

 

1.5数组的扩容.lang提供的ArrayUtils.他提供了很多重载的add的方法.

 

public static String[] resolveBirthday(String birthday) { String[] birth = new String[] { "1900", "01", "01" }; if (birthday.indexOf("-") != -1 && birthday.length() > 2) { birth = StringUtils.split(birthday,"-",3); if(birth.length<3){ for(int i=birth.length;i<3;i++){ birth=(String[]) ArrayUtils.add(birth,"01"); } } } return birth; }

 

 

1.6我记得在google上能搜到java实现javascript的escape功能!这个确实不错,在以前写ajax时经常用到.
google搜到的.我没测试好不好用

public static String escape(String src) { int i; char j; StringBuffer tmp = new StringBuffer(); tmp.ensureCapacity(src.length() * 6); for (i = 0; i < src.length(); i++) { j = src.charAt(i); if (Character.isDigit(j) || Character.isLowerCase(j) || Character.isUpperCase(j)) tmp.append(j); else if (j < 256) { tmp.append("%"); if (j < 16) tmp.append("0"); tmp.append(Integer.toString(j, 16)); } else { tmp.append("%u"); tmp.append(Integer.toString(j, 16)); } } return tmp.toString(); }

 

这个lang提供的就更全面了,看StringEscapeUtils.即然上面是实现javascript的escape,哪就看StringEscapeUtils提供的

public static String escape(String src) { return StringEscapeUtils.escapeJavaScript(src); }

 

相应的unescape也有,不是说更全面么在哪呢?

public static String escapeHtml(String str) public static String escapeJava(String str) public static void escapeJava(Writer out,String str)throws IOException public static String escapeJavaScript(String str) public static void escapeJavaScript(Writer out,String str)throws IOException public static String escapeSql(String str) public static String escapeXml(String str)

 

2.codec
在项目中需要有登陆操作时,会员的密码都是经过加密的,也不知我找的这个是不是对的,如果你有知道Common下更好的可以告诉我.先说声:"谢谢"
google到的

public static String hashPassword(String password) { String hashword = null; try { MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(password.getBytes()); BigInteger hash = new BigInteger(1, md5.digest()); hashword = hash.toString(16); if (hashword.length() == 31) hashword = "0" + hashword; } catch (NoSuchAlgorithmException nsae) { // ignore } return hashword; }

 

     
开始时我用的是这个方法,下面是等价的DigestUtils

public static String hashPassword(String password) { return DigestUtils.md5Hex(password); }

 

用ASF的话,不用重新造轮子,commons里有你日常需要用到的大多数东东,如果你发现别的语言有的,但java没有提供,请你一定要访问ASF的网站.让我们一起为能有ASF这样的战友高兴一下吧

 

你可能感兴趣的:(apache commons 小览)