Apache Commons 工具类介绍及简单使用(转载)
原文链接
http://www.cnblogs.com/younggun/p/3247261.html
Apache Commons包含了很多开源的工具,用于解决平时编程经常会遇到的问题,减少重复劳动。下面是我这几年做开发过程中自己用过的工具类做简单介绍。
组件 | 功能介绍 |
BeanUtils | 提供了对于JavaBean进行各种操作,克隆对象,属性等等. |
Betwixt | XML与Java对象之间相互转换. |
Codec | 处理常用的编码方法的工具类包 例如DES、SHA1、MD5、Base64等. |
Collections | java集合框架操作. |
Compress | java提供文件打包 压缩类库. |
Configuration | 一个java应用程序的配置管理类库. |
DBCP | 提供数据库连接池服务. |
DbUtils | 提供对jdbc 的操作封装来简化数据查询和记录读取操作. |
java发送邮件 对javamail的封装. | |
FileUpload | 提供文件上传功能. |
HttpClien | 提供HTTP客户端与服务器的各种通讯操作. 现在已改成HttpComponents |
IO | io工具的封装. |
Lang | Java基本对象方法的工具类包 如:StringUtils,ArrayUtils等等. |
Logging | 提供的是一个Java 的日志接口. |
Validator | 提供了客户端和服务器端的数据验证框架. |
1、BeanUtils
提供了对于JavaBean进行各种操作, 比如对象,属性复制等等。

//1、 克隆对象
// 新创建一个普通Java Bean,用来作为被克隆的对象 public class Person {
private String name = "";
private String email = ""; private int age;
//省略 set,get方法
} // 再创建一个Test类,其中在main方法中代码如下:
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
public class Test { /** * @param args */
public static void main(String[] args) {
Person person = new Person();
person.setName("tom");
person.setAge(21);
try {
//克隆
Person person2 = (Person)BeanUtils.cloneBean(person);
System.out.println(person2.getName()+">>"+person2.getAge());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace(); } } } // 原理也是通过Java的反射机制来做的。
// 2、 将一个Map对象转化为一个Bean
// 这个Map对象的key必须与Bean的属性相对应。
Map map = new HashMap();
map.put("name","tom");
map.put("email","tom@");
map.put("age","21");
//将map转化为一个Person对象
Person person = new Person();
BeanUtils.populate(person,map);
// 通过上面的一行代码,此时person的属性就已经具有了上面所赋的值了。
// 将一个Bean转化为一个Map对象了,如下:
Map map = BeanUtils.describe(person)

2、Betwixt
XML与Java对象之间相互转换。

//1、 将JavaBean转为XML内容
// 新创建一个Person类
public class Person{
private String name;
private int age;
/** Need to allow bean to be created via reflection */
public PersonBean() {
}
public PersonBean(String name, int age) {
this.name = name;
this.age = age;
}
//省略set, get方法
public String toString() {
return "PersonBean[name='" + name + "',age='" + age + "']";
}
} //再创建一个WriteApp类:
import java.io.StringWriter;
import org.apache.commons.betwixt.io.BeanWriter;
public class WriteApp {
/**
* 创建一个例子Bean,并将它转化为XML.
*/
public static final void main(String [] args) throws Exception {
// 先创建一个StringWriter,我们将把它写入为一个字符串
StringWriter outputWriter = new StringWriter();
// Betwixt在这里仅仅是将Bean写入为一个片断
// 所以如果要想完整的XML内容,我们应该写入头格式
outputWriter.write(“<?xml version=’1.0′ encoding=’UTF-8′ ?>\n”);
// 创建一个BeanWriter,其将写入到我们预备的stream中
BeanWriter beanWriter = new BeanWriter(outputWriter);
// 配置betwixt
// 更多详情请参考java docs 或最新的文档
beanWriter.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(false);
beanWriter.getBindingConfiguration().setMapIDs(false);
beanWriter.enablePrettyPrint();
// 如果这个地方不传入XML的根节点名,Betwixt将自己猜测是什么
// 但是让我们将例子Bean名作为根节点吧
beanWriter.write(“person”, new PersonBean(“John Smith”, 21));
//输出结果
System.out.println(outputWriter.toString());
// Betwixt写的是片断而不是一个文档,所以不要自动的关闭掉writers或者streams,
//但这里仅仅是一个例子,不会做更多事情,所以可以关掉
outputWriter.close();
}
}
//2、 将XML转化为JavaBean
import java.io.StringReader;
import org.apache.commons.betwixt.io.BeanReader;
public class ReadApp {
public static final void main(String args[]) throws Exception{
// 先创建一个XML,由于这里仅是作为例子,所以我们硬编码了一段XML内容
StringReader xmlReader = new StringReader(
"<?xml version=’1.0′ encoding=’UTF-8′ ?> <person><age>25</age><name>James Smith</name></person>");
//创建BeanReader
BeanReader beanReader = new BeanReader();
//配置reader
beanReader.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(false);
beanReader.getBindingConfiguration().setMapIDs(false);
//注册beans,以便betwixt知道XML将要被转化为一个什么Bean
beanReader.registerBeanClass("person", PersonBean.class);
//现在我们对XML进行解析
PersonBean person = (PersonBean) beanReader.parse(xmlReader);
//输出结果
System.out.println(person);
}
}

3、Codec
提供了一些公共的编解码实现,比如Base64, Hex, MD5,Phonetic and URLs等等。

//Base64编解码
private static String encodeTest(String str){
Base64 base64 = new Base64();
try {
str = base64.encodeToString(str.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println("Base64 编码后:"+str);
return str;
} private static void decodeTest(String str){
Base64 base64 = new Base64();
//str = Arrays.toString(Base64.decodeBase64(str));
str = new String(Base64.decodeBase64(str));
System.out.println("Base64 解码后:"+str);
}

4、Collections
对java.util的扩展封装,处理数据还是挺灵活的。
org.apache.commons.collections – Commons Collections自定义的一组公用的接口和工具类
org.apache.commons.collections.bag – 实现Bag接口的一组类
org.apache.commons.collections.bidimap – 实现BidiMap系列接口的一组类
org.apache.commons.collections.buffer – 实现Buffer接口的一组类
org.apache.commons.collections.collection – 实现java.util.Collection接口的一组类
org.apache.commons.collections.comparators – 实现java.util.Comparator接口的一组类
org.apache.commons.collections.functors – Commons Collections自定义的一组功能类
org.apache.commons.collections.iterators – 实现java.util.Iterator接口的一组类
org.apache.commons.collections.keyvalue – 实现集合和键/值映射相关的一组类
org.apache.commons.collections.list – 实现java.util.List接口的一组类
org.apache.commons.collections.map – 实现Map系列接口的一组类
org.apache.commons.collections.set – 实现Set系列接口的一组类

/**
* 得到集合里按顺序存放的key之后的某一Key
*/
OrderedMap map = new LinkedMap();
map.put("FIVE", "5");
map.put("SIX", "6");
map.put("SEVEN", "7");
map.firstKey(); // returns "FIVE"
map.nextKey("FIVE"); // returns "SIX"
map.nextKey("SIX"); // returns "SEVEN" /**
* 通过key得到value
* 通过value得到key
* 将map里的key和value对调
*/ BidiMap bidi = new TreeBidiMap();
bidi.put("SIX", "6");
bidi.get("SIX"); // returns "6"
bidi.getKey("6"); // returns "SIX"
// bidi.removeValue("6"); // removes the mapping
BidiMap inverse = bidi.inverseBidiMap(); // returns a map with keys and values swapped
System.out.println(inverse); /**
* 得到两个集合中相同的元素
*/
List<String> list1 = new ArrayList<String>();
list1.add("1");
list1.add("2");
list1.add("3");
List<String> list2 = new ArrayList<String>();
list2.add("2");
list2.add("3");
list2.add("5");
Collection c = CollectionUtils.retainAll(list1, list2);
System.out.println(c);

5、Compress
commons compress中的打包、压缩类库。

//创建压缩对象
ZipArchiveEntry entry = new ZipArchiveEntry("CompressTest");
//要压缩的文件
File f=new File("e:\\test.pdf");
FileInputStream fis=new FileInputStream(f);
//输出的对象 压缩的文件
ZipArchiveOutputStream zipOutput=new ZipArchiveOutputStream(new File("e:\\test.zip"));
zipOutput.putArchiveEntry(entry);
int i=0,j;
while((j=fis.read()) != -1)
{
zipOutput.write(j);
i++;
System.out.println(i);
}
zipOutput.closeArchiveEntry();
zipOutput.close();
fis.close();

6、Configuration
用来帮助处理配置文件的,支持很多种存储方式。
1. Properties files
2. XML documents
3. Property list files (.plist)
4. JNDI
5. JDBC Datasource
6. System properties
7. Applet parameters
8. Servlet parameters

//举一个Properties的简单例子
# usergui.properties
colors.background = #FFFFFF
colors.foreground = #000080
window.width = 500
window.height = 300 PropertiesConfiguration config = new PropertiesConfiguration("usergui.properties");
config.setProperty("colors.background", "#000000);
config.save(); config.save("usergui.backup.properties);//save a copy
Integer integer = config.getInteger("window.width");

7、DBCP
(Database Connection Pool)是一个依赖Jakarta commons-pool对象池机制的数据库连接池,Tomcat的数据源使用的就是DBCP。

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException; import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
//官方示例
public class PoolingDataSources { public static void main(String[] args) {
System.out.println("加载jdbc驱动");
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("Done.");
//
System.out.println("设置数据源");
DataSource dataSource = setupDataSource("jdbc:oracle:thin:@localhost:1521:test");
System.out.println("Done."); //
Connection conn = null;
Statement stmt = null;
ResultSet rset = null; try {
System.out.println("Creating connection.");
conn = dataSource.getConnection();
System.out.println("Creating statement.");
stmt = conn.createStatement();
System.out.println("Executing statement.");
rset = stmt.executeQuery("select * from person");
System.out.println("Results:");
int numcols = rset.getMetaData().getColumnCount();
while(rset.next()) {
for(int i=0;i<=numcols;i++) {
System.out.print("\t" + rset.getString(i));
}
System.out.println("");
}
} catch(SQLException e) {
e.printStackTrace();
} finally {
try { if (rset != null) rset.close(); } catch(Exception e) { }
try { if (stmt != null) stmt.close(); } catch(Exception e) { }
try { if (conn != null) conn.close(); } catch(Exception e) { }
}
} public static DataSource setupDataSource(String connectURI) {
//设置连接地址
ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
connectURI, null); // 创建连接工厂
PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(
connectionFactory); //获取GenericObjectPool 连接的实例
ObjectPool connectionPool = new GenericObjectPool(
poolableConnectionFactory); // 创建 PoolingDriver
PoolingDataSource dataSource = new PoolingDataSource(connectionPool); return dataSource;
}
}

8、DbUtils
Apache组织提供的一个资源JDBC工具类库,它是对JDBC的简单封装,对传统操作数据库的类进行二次封装,可以把结果集转化成List。,同时也不影响程序的性能。
DbUtils类:启动类
ResultSetHandler接口:转换类型接口
MapListHandler类:实现类,把记录转化成List
BeanListHandler类:实现类,把记录转化成List,使记录为JavaBean类型的对象
Qrery Runner类:执行SQL语句的类

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
//转换成list
public class BeanLists {
public static void main(String[] args) {
Connection conn = null;
String url = "jdbc:mysql://localhost:3306/ptest";
String jdbcDriver = "com.mysql.jdbc.Driver";
String user = "root";
String password = "ptest"; DbUtils.loadDriver(jdbcDriver);
try {
conn = DriverManager.getConnection(url, user, password);
QueryRunner qr = new QueryRunner();
List results = (List) qr.query(conn, "select id,name from person", new BeanListHandler(Person.class));
for (int i = 0; i < results.size(); i++) {
Person p = (Person) results.get(i);
System.out.println("id:" + p.getId() + ",name:" + p.getName());
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DbUtils.closeQuietly(conn);
}
}
} public class Person{
private Integer id;
private String name; //省略set, get方法
} import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.MapListHandler; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException; import java.util.List;
import java.util.Map;
//转换成map
public class MapLists {
public static void main(String[] args) {
Connection conn = null;
String url = "jdbc:mysql://localhost:3306/ptest";
String jdbcDriver = "com.mysql.jdbc.Driver";
String user = "root";
String password = "ptest"; DbUtils.loadDriver(jdbcDriver);
try {
conn = DriverManager.getConnection(url, user, password);
QueryRunner qr = new QueryRunner();
List results = (List) qr.query(conn, "select id,name from person", new MapListHandler());
for (int i = 0; i < results.size(); i++) {
Map map = (Map) results.get(i);
System.out.println("id:" + map.get("id") + ",name:" + map.get("name"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DbUtils.closeQuietly(conn);
}
}
}

9、Email
提供的一个开源的API,是对javamail的封装。

//用commons email发送邮件
public static void main(String args[]){
Email email = new SimpleEmail();
email.setHostName("smtp.googlemail.com");
email.setSmtpPort(465);
email.setAuthenticator(new DefaultAuthenticator("username", "password"));
email.setSSLOnConnect(true);
email.setFrom("user@gmail.com");
email.setSubject("TestMail");
email.setMsg("This is a test mail ... :-)");
email.addTo("foo@bar.com");
email.send();
}

10、FileUpload
java web文件上传功能。

//官方示例:
//* 检查请求是否含有上传文件
// Check that we have a file upload request
boolean isMultipart = ServletFileUpload.isMultipartContent(request); //现在我们得到了items的列表 //如果你的应用近于最简单的情况,上面的处理就够了。但我们有时候还是需要更多的控制。
//下面提供了几种控制选择:
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory(); // Set factory constraints
factory.setSizeThreshold(yourMaxMemorySize);
factory.setRepository(yourTempDirectory); // Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory); // 设置最大上传大小
upload.setSizeMax(yourMaxRequestSize); // 解析所有请求
List /* FileItem */ items = upload.parseRequest(request); // Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory(
yourMaxMemorySize, yourTempDirectory); //一旦解析完成,你需要进一步处理item的列表。
// Process the uploaded items
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next(); if (item.isFormField()) {
processFormField(item);
} else {
processUploadedFile(item);
}
} //区分数据是否为简单的表单数据,如果是简单的数据:
// processFormField
if (item.isFormField()) {
String name = item.getFieldName();
String value = item.getString();
//...省略步骤
} //如果是提交的文件:
// processUploadedFile
if (!item.isFormField()) {
String fieldName = item.getFieldName();
String fileName = item.getName();
String contentType = item.getContentType();
boolean isInMemory = item.isInMemory();
long sizeInBytes = item.getSize();
//...省略步骤
} //对于这些item,我们通常要把它们写入文件,或转为一个流
// Process a file upload
if (writeToFile) {
File uploadedFile = new File(...);
item.write(uploadedFile);
} else {
InputStream uploadedStream = item.getInputStream();
//...省略步骤
uploadedStream.close();
} //或转为字节数组保存在内存中:
// Process a file upload in memory
byte[] data = item.get();
//...省略步骤
//如果这个文件真的很大,你可能会希望向用户报告到底传了多少到服务端,让用户了解上传的过程
//Create a progress listener
ProgressListener progressListener = new ProgressListener(){
public void update(long pBytesRead, long pContentLength, int pItems) {
System.out.println("We are currently reading item " + pItems);
if (pContentLength == -1) {
System.out.println("So far, " + pBytesRead + " bytes have been read.");
} else {
System.out.println("So far, " + pBytesRead + " of " + pContentLength
+ " bytes have been read.");
}
}
};
upload.setProgressListener(progressListener);

11、HttpClient
基于HttpCore实 现的一个HTTP/1.1兼容的HTTP客户端,它提供了一系列可重用的客户端身份验证、HTTP状态保持、HTTP连接管理module。

//GET方法
import java.io.IOException;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams; public class GetSample{
public static void main(String[] args) {
// 构造HttpClient的实例
HttpClient httpClient = new HttpClient();
// 创建GET方法的实例
GetMethod getMethod = new GetMethod("http://www.ibm.com");
// 使用系统提供的默认的恢复策略
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler());
try {
// 执行getMethod
int statusCode = httpClient.executeMethod(getMethod);
if (statusCode != HttpStatus.SC_OK) {
System.err.println("Method failed: "
+ getMethod.getStatusLine());
}
// 读取内容
byte[] responseBody = getMethod.getResponseBody();
// 处理内容
System.out.println(new String(responseBody));
} catch (HttpException e) {
// 发生致命的异常,可能是协议不对或者返回的内容有问题
System.out.println("Please check your provided http address!");
e.printStackTrace();
} catch (IOException e) {
// 发生网络异常
e.printStackTrace();
} finally {
// 释放连接
getMethod.releaseConnection();
}
}
} //POST方法
import java.io.IOException;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams; public class PostSample{
public static void main(String[] args) {
// 构造HttpClient的实例
HttpClient httpClient = new HttpClient();
// 创建POST方法的实例
String url = "http://www.oracle.com/";
PostMethod postMethod = new PostMethod(url);
// 填入各个表单域的值
NameValuePair[] data = { new NameValuePair("id", "youUserName"),
new NameValuePair("passwd", "yourPwd") };
// 将表单的值放入postMethod中
postMethod.setRequestBody(data);
// 执行postMethod
int statusCode = httpClient.executeMethod(postMethod);
// HttpClient对于要求接受后继服务的请求,象POST和PUT等不能自动处理转发
// 301或者302
if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY ||
statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
// 从头中取出转向的地址
Header locationHeader = postMethod.getResponseHeader("location");
String location = null;
if (locationHeader != null) {
location = locationHeader.getValue();
System.out.println("The page was redirected to:" + location);
} else {
System.err.println("Location field value is null.");
}
return;
}
}
}

12、IO
对java.io的扩展 操作文件非常方便。

//1.读取Stream //标准代码:
InputStream in = new URL( "http://jakarta.apache.org" ).openStream();
try {
InputStreamReader inR = new InputStreamReader( in );
BufferedReader buf = new BufferedReader( inR );
String line;
while ( ( line = buf.readLine() ) != null ) {
System.out.println( line );
}
} finally {
in.close();
} //使用IOUtils InputStream in = new URL( "http://jakarta.apache.org" ).openStream();
try {
System.out.println( IOUtils.toString( in ) );
} finally {
IOUtils.closeQuietly(in);
} //2.读取文件
File file = new File("/commons/io/project.properties");
List lines = FileUtils.readLines(file, "UTF-8");
//3.察看剩余空间
long freeSpace = FileSystemUtils.freeSpace("C:/");

13、Lang
主要是一些公共的工具集合,比如对字符、数组的操作等等。
aaarticlea/png;base64,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" alt="" />

// 1 合并两个数组: org.apache.commons.lang. ArrayUtils
// 有时我们需要将两个数组合并为一个数组,用ArrayUtils就非常方便,示例如下:
private static void testArr() {
String[] s1 = new String[] { "1", "2", "3" };
String[] s2 = new String[] { "a", "b", "c" };
String[] s = (String[]) ArrayUtils.addAll(s1, s2);
for (int i = 0; i < s.length; i++) {
System.out.println(s[i]);
}
String str = ArrayUtils.toString(s);
str = str.substring(1, str.length() - 1);
System.out.println(str + ">>" + str.length()); }
//2 截取从from开始字符串
StringUtils.substringAfter("SELECT * FROM PERSON ", "from");
//3 判断该字符串是不是为数字(0~9)组成,如果是,返回true 但该方法不识别有小数点和 请注意。
StringUtils.isNumeric("454534"); //返回true
//4.取得类名
System.out.println(ClassUtils.getShortClassName(Test.class));
//取得其包名
System.out.println(ClassUtils.getPackageName(Test.class)); //5.NumberUtils
System.out.println(NumberUtils.stringToInt("6"));
//6.五位的随机字母和数字
System.out.println(RandomStringUtils.randomAlphanumeric(5));
//7.StringEscapeUtils
System.out.println(StringEscapeUtils.escapeHtml("<html>"));
//输出结果为<html>
System.out.println(StringEscapeUtils.escapeJava("String")); //8.StringUtils,判断是否是空格字符
System.out.println(StringUtils.isBlank(" "));
//将数组中的内容以,分隔
System.out.println(StringUtils.join(test,","));
//在右边加下字符,使之总长度为6
System.out.println(StringUtils.rightPad("abc", 6, 'T'));
//首字母大写
System.out.println(StringUtils.capitalize("abc"));
//Deletes all whitespaces from a String 删除所有空格
System.out.println( StringUtils.deleteWhitespace(" ab c "));
//判断是否包含这个字符
System.out.println( StringUtils.contains("abc", "ba"));
//表示左边两个字符
System.out.println( StringUtils.left("abc", 2));
System.out.println(NumberUtils.stringToInt("33"));

14、Logging
提供的是一个Java 的日志接口,同时兼顾轻量级和不依赖于具体的日志实现工具。

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; public class CommonLogTest {
private static Log log = LogFactory.getLog(CommonLogTest.class);
//日志打印
public static void main(String[] args) {
log.error("ERROR");
log.debug("DEBUG");
log.warn("WARN");
log.info("INFO");
log.trace("TRACE");
System.out.println(log.getClass());
} }

15、Validator
通用验证系统,该组件提供了客户端和服务器端的数据验证框架。
验证日期

// 获取日期验证
DateValidator validator = DateValidator.getInstance(); // 验证/转换日期
Date fooDate = validator.validate(fooString, "dd/MM/yyyy");
if (fooDate == null) {
// 错误 不是日期
return;
}

表达式验证

// 设置参数
boolean caseSensitive = false;
String regex1 = "^([A-Z]*)(?:\\-)([A-Z]*)*$"
String regex2 = "^([A-Z]*)$";
String[] regexs = new String[] {regex1, regex1}; // 创建验证
RegexValidator validator = new RegexValidator(regexs, caseSensitive); // 验证返回boolean
boolean valid = validator.isValid("abc-def"); // 验证返回字符串
String result = validator.validate("abc-def"); // 验证返回数组
String[] groups = validator.match("abc-def");

配置文件中使用验证

<form-validation>
<global>
<validator name="required"
classname="org.apache.commons.validator.TestValidator"
method="validateRequired"
methodParams="java.lang.Object, org.apache.commons.validator.Field"/>
</global>
<formset>
</formset>
</form-validation> 添加姓名验证. <form-validation>
<global>
<validator name="required"
classname="org.apache.commons.validator.TestValidator"
method="validateRequired"
methodParams="java.lang.Object, org.apache.commons.validator.Field"/>
</global>
<formset>
<form name="nameForm">
<field property="firstName" depends="required">
<arg0 key="nameForm.firstname.displayname"/>
</field>
<field property="lastName" depends="required">
<arg0 key="nameForm.lastname.displayname"/>
</field>
</form>
</formset>
</form-validation>

验证类

Excerpts from org.apache.commons.validator.RequiredNameTest
//加载验证配置文件
InputStream in = this.getClass().getResourceAsStream("validator-name-required.xml"); ValidatorResources resources = new ValidatorResources(in);
//这个是自己创建的bean 我这里省略了
Name name = new Name(); Validator validator = new Validator(resources, "nameForm");
//设置参数
validator.setParameter(Validator.BEAN_PARAM, name); Map results = null;
//验证
results = validator.validate(); if (results.get("firstName") == null) {
//验证成功
} else {
//有错误 int errors = ((Integer)results.get("firstName")).intValue();
}

Apache Commons 工具类介绍及简单使用(转载)的更多相关文章
- Apache Commons 工具类介绍及简单使用
转自:http://www.cnblogs.com/younggun/p/3247261.html Apache Commons包含了很多开源的工具,用于解决平时编程经常会遇到的问题,减少重复劳动.下 ...
- Java:Apache Commons 工具类介绍及简单使用
Apache Commons包含了很多开源的工具,用于解决平时编程经常会遇到的问题,减少重复劳动.下面是我这几年做开发过程中自己用过的工具类做简单介绍. Commons简介 组件 功能介绍 commo ...
- Apache Commons 工具类简单使用
Apache Commons包含了很多开源的工具,用于解决平时编程经常会遇到的问题,减少重复劳动.下面是我这几年做开发过程中自己用过的工具类做简单介绍. 组件 功能介绍 BeanUtils 提供了对于 ...
- linkin大话数据结构--apache commons工具类
Apache Commons包含了很多开源的工具,用于解决平时编程经常会遇到的问题,减少重复劳动. 一.Commons BeanUtils 说明:针对Bean的一个工具集.由于Bean往往是有一堆ge ...
- Apache Commons 工具集介绍
Apache Commons包含了很多开源的工具,用于解决平时编程经常会遇到的问题,减少重复劳动.下面是我这几年做开发过程中自己用过的工具类做简单介绍. 组件 功能介绍 BeanUtils 提供了对于 ...
- Apache Commons 工具类
http://blog.csdn.net/feicongcong/article/details/53374399http://blog.csdn.net/hsienhua/article/detai ...
- Apache的commons工具类
package cn.zhou; import java.io.File; import java.io.IOException; import org.apache.commons.io.FileU ...
- commons工具类
转自:https://blog.csdn.net/leaderway/article/details/52387925 1.1. 开篇 在Java的世界,有很多(成千上万)开源的框架,有成功的,也有不 ...
- Java语言Lang包下常用的工具类介绍_java - JAVA
文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 无论你在开发哪中 Java 应用程序,都免不了要写很多工具类/工具函数.你可知道,有很多现成的工具类可用,并且代码质量都 ...
随机推荐
- LLVM思想与功能综述
llvm似乎还有一个奇怪的优化方法:llvm(low level virtual machine)本身就是一种抽象的.虚拟的计算机架构,其特性介于RISC和CISC之间,llvm会先将代码编译为llv ...
- element 弹框关闭报错
<template> <el-container style="padding: 00px 20px 0px 20px"> <el-dialog ti ...
- [Windows] GIF编辑器
目录 1. 功能简介 2. 下载地址 3. 使用教程 3.1. 其他视频转gif的方案 1. 功能简介 可以自定义录屏位置.区域大小做GIF 可以编辑GIF.压缩GIF等 可以将视频转换成GIF 可以 ...
- VNware上安装虚拟机Ubuntu16.10 并安装petalinux
1.下载 VMware VMware-workstation-full-15.0.0-10134415.exe 自己寻找激活码 Ubuntu镜像 UG1144 PetaLinux Tools Docu ...
- W3C 事件切换 颜色变化
颜色变化代码: HTML: <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...
- No module named flask 导包失败,Python3重新安装Flask模块
在部署环境过程中,通过pip install -r requirements.txt安装包,结果启动项目时总是报错,显示没有flask模块,通过pip install flask还是不行,于是下载fl ...
- HashMap测试程序1
package com.iotek.map; import java.util.Collection;import java.util.HashMap;import java.util.Map;imp ...
- Xcode出现报错,但是没有给出详细信息,可以看这里
Xcode出现报错,"Xcode build:clang: error: linker command failed with exit code 1 (use -v to..." ...
- php单点登录实现原理实例详解
单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任. 单点登录在大型网站里使用 ...
- ubuntu 16.4下hadoop配置伪分布式时出现的坑
在ubuntu16.4下spark的单机/伪分布式配置我在此就不在一一赘述,详情请点击如下连接: Hadoop安装教程_单机/伪分布式配置_Hadoop2.6.0/Ubuntu14.04 我出现问题是 ...