Apache工具库——Apache Commons的使用
Apache Commons是Apache开源的一个java组件库,其中包含了大量子项目,其中常用的组件有:
组件 |
功能介绍 |
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
BeanUtils是基于jdk的java.beans,提供了一系列对java bean的操作,比如对象,属性复制,读取和设置Bean的属性值,动态定义和访问Bean属性等。
对于Bean的操作主要通过BeanUtils这个类。
BeanUtils将property分成简单类型(String、Integer),索引类型(数组、ArrayList)以及Map类型。可以直接通过set和get设置或获取bean属性。
实例代码演示
创建了一个bean类Person
package com.xiaomifeng1010.beanutils.bean;
import lombok.Data;
/**
* @author xiaomifeng1010
* @version 1.0
* @date: 2020/4/30 16:31
*/
@Data
public class Person {
private Integer age;
private String name;
private String gender;
}
测试类:
import com.xiaomifeng1010.beanutils.bean.Person;
import org.apache.commons.beanutils.BeanUtils;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
/**
* @author xiaomifeng1010
* @version 1.0
* @date: 2020/4/30 16:40
*/
public class BeanUtilsTest {
/**
* 测试BeanUtils克隆一个bean对象
* @throws InvocationTargetException
* @throws NoSuchMethodException
* @throws InstantiationException
* @throws IllegalAccessException
*/
@Test
public void testCloneBean() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
Person person=new Person();
// person.setAge(12);
// person.setName("xiaomifeng");
// person.setGender("male");
// 通过上边对象setter设置属性值,或者通过BeanUtils类给bean对象设置属性值
BeanUtils.setProperty(person,"age",12);
BeanUtils.setProperty(person,"name","xiaomfieng");
BeanUtils.setProperty(person,"gender","male");
System.out.println("before clone,the person's property whose age is "+person.getAge()+" and name is "+person.getName());
// 克隆一个对象(深复制,原型模式)
try {
//
// 克隆bean对象赋值给personClone
Person personClone= (Person) BeanUtils.cloneBean(person);
// 或者使用另一个方法(通过复制对象属性值)达到克隆对象personClone2,注意spring框架里边也有BeanUtils
// 工具类,它的copyProperties方法中的参数,第一个参数为原对象,第二个对象为目标对象,和这里相反
Person personClone2=new Person();
BeanUtils.copyProperties(personClone2,person);
// 克隆之后,修改原bean属性
person.setName("farmer");
System.out.println("modify the person's name:"+person.getName());
System.out.println("after clone,the personClone's property whose age is "+personClone.getAge()+" and name is "+personClone.getName());
System.out.println("after clone,the personClone2's property whose age is "+personClone2.getAge()+" and name is "+personClone2.getName());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
/**
* 通过java反射机制,将一个Map对象转换为一个Bean
* map的key必须与bean属性相对应
*/
@Test
public void testMapToBean(){
Map<String,String> map=new HashMap<>();
map.put("name","xiaomieng");
map.put("age","22");
map.put("gender","male");
Person person=new Person();
try {
// 将map转换为一个person对象,此时person的属性已经通过map赋值了
BeanUtils.populate(person,map);
System.out.println("map transform person:"+person);
// 将一个Bean转换为Map对象的操作
Map map2=BeanUtils.describe(person);
System.out.println("person transform map:"+map2);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
两个测试方法输出:
第1个测试方法控制台输出:
第2个测试方法控制台输出:
2、Codec
处理常用的编码方法的工具类包 例如DES、SHA1、MD5、Base64、Hex、URL等。
测试类:
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.net.URLCodec;
import org.junit.Test;
import java.io.UnsupportedEncodingException;
/**
* @author xiaomifeng1010
* @version 1.0
* @date: 2020/4/30 17:52
*/
public class CodecTest {
/**
* 测试base64编码
*/
@Test
public void base64EncodeTest(){
Base64 base64 = new Base64();
String originalString="xiaomifeng1010";
try {
String encodeBase64String=base64.encodeToString(originalString.getBytes("utf-8"));
System.out.println("after base64Encode,the encodeBase64String is "+encodeBase64String);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
/**
* 测试base64解码
*/
@Test
public void base64DecodeTest(){
Base64 base64 = new Base64();
try {
String encodeBase64String =base64.encodeToString("xiaomifeng1010".getBytes("utf-8"));
String decodeBase64String= new String(base64.decodeBase64(encodeBase64String));
System.out.println("decodeBase64,the decodeBase64String is "+decodeBase64String);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
/**
* 客户端在进行网页请求的时候,网址中可能会包含非ASCII码形式的内容,比如中文
* 而直接把中文放到网址中请求是不允许的,所以需要用URLEncoder编码地址,
* 将网址中的非ASCII码内容转换成可以传输的字符
* 或者其他一些特殊字符,比如上边的base64编码中可能出现的特殊字符"+","="等,
* 直接在浏览器地址中出现会出现错误,需要url编码,转换成%开头加上字符的形式,
* 让浏览器可以解析。
*
*/
@Test
public void urlEncodeTest(){
try {
String urlParameter=new Base64().encodeToString("xiaomifeng1010".getBytes("utf-8"));
System.out.println("after base64Encode,the 'xiaomifeng1010' is used as urlParameter:"+urlParameter);
URLCodec urlCodec=new URLCodec();
String urlEncodeParameter=urlCodec.encode(urlParameter,"utf-8");
System.out.println("after urlEncode,the urlparameter would be:"+urlEncodeParameter);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
base64编码的效果:
base64解码:
base64编码后,再进行urlencode
urlencode编码后,“=”被替换成了%3D
现在在浏览器中测试一下,没有urlencode之前,作为参数:
等号可以解析出来
换成%3D也能成功解析出来
但是如果将“=”换成特殊符号“+”,就解析不出来了
可以使用上边的方法对“+” 号urlencode之后是%2B,就可以正常解析了
3.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系列接口的一组类
测试类:
import org.apache.commons.collections.BidiMap;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.OrderedMap;
import org.apache.commons.collections.bidimap.TreeBidiMap;
import org.apache.commons.collections.map.LinkedMap;
import org.junit.Test;
import java.util.*;
/**
* @author xiaomifeng1010
* @version 1.0
* @date: 2020/4/30 19:48
*/
public class CollctionsTest {
/**
* 集合之间的操作
*/
@Test
public void collectionOperationTest(){
String[] arryays="a,b,c,d,e,f,g,h,i,j,k,l,m,n".split(",");
List<String> list1=Arrays.asList(arryays);
List<String> list2=new ArrayList<>();
list2.add("c");
list2.add("p");
list2.add("l");
list2.add("d");
// 判断集合非空
if (CollectionUtils.isNotEmpty(list1) && CollectionUtils.isNotEmpty(list2)){
// 两个集合取并集
Collection collection1=CollectionUtils.union(list1,list2);
// 两个集合取差集
Collection collection2=CollectionUtils.subtract(list1,list2);
// 两个集合取交集
Collection collection3=CollectionUtils.retainAll(list1,list2);
System.out.println("list1和list2并集之后:"+collection1);
System.out.println("list1和list2差集之后:"+collection2);
System.out.println("list1和list2交集之后:"+collection3);
}
}
/**
* 测试新的集合类型
*/
@Test
public void newCollectionTest() {
// 得到集合里按顺序存放的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"
BidiMap bidiMap=new TreeBidiMap();
// 罗马数字Ⅳ=4,V=5
bidiMap.put("Ⅳ","4");
bidiMap.put("Ⅴ","5");
// 通过key得到value
String returnValue= (String) bidiMap.get("Ⅳ");
// 通过value得到key
String returnKey =String.valueOf(bidiMap.getKey("4"));
System.out.println("通过IV获取到:"+returnValue);
System.out.println("获取4的key:"+returnKey);
returnValue= (String) bidiMap.get("Ⅴ");
returnKey= (String) bidiMap.getKey("5");
System.out.println("获取5的key:"+returnKey);
System.out.println("通过V获取到:"+returnValue);
// 删除5
bidiMap.removeValue("5");
// 将bidiMap中的key与value位置互换,反转得到inverseMap
BidiMap inverseMap = bidiMap.inverseBidiMap();
System.out.println("bidiMap反转后的inverseMap:"+inverseMap);
}
}
集合操作的结果:
新集合操作结果:
4.I/O
对java.io的扩展 操作文件非常方便
测试类:
import org.apache.commons.io.FileSystemUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
/**
* @author xiaomifeng1010
* @version 1.0
* @date: 2020/4/30 20:54
*/
public class CommonsIOTest {
/**
* 不使用工具包情况下的stream的读写操作
*/
@Test
public void traditionalIOStreamOperationTest(){
// 读取Stream
try(InputStream in=new URL("http://www.baidu.com").openStream()){
// 不使用工具包
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line=br.readLine())!=null){
System.out.println(line);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 使用IOUtils操作stream读写
*/
@Test
public void ioUtilsTest(){
try(InputStream in= new URL("http://www.baidu.com").openStream()){
// 使用IOUtils只需要这一行代码,就可以读取到网页内容,较少了很多代码
String webPageContent=IOUtils.toString(in,"utf-8");
// List<String> webPageContent= IOUtils.readLines(in,"utf-8");
System.out.println(webPageContent);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 使用FileUtils快捷操作文件读写
*/
@Test
public void fileOperationTest(){
File file=new File(File.separator+"data"+File.separator+"test.txt");
System.out.println("文件路径:"+ file.getAbsolutePath());
String content="你好,游客\r\n";
try {
// 查看磁盘剩余空间
System.out.println("data路径所在磁盘剩余空间:"+ FileSystemUtils.freeSpace(file.getAbsolutePath()));
// 将字符串写入文件(append为true,新内容以追加的形式写入,append为flase,新内容将会覆盖以往的内容)
FileUtils.writeStringToFile(file,content,"utf-8",true);
// 将直接数组写入文件
FileUtils.writeByteArrayToFile(file,"欢迎浏览页面\r\n".getBytes(),true);
// 从文件中读取内容
List lines= FileUtils.readLines(file,"utf-8");
// 读取成字节数组
byte[] fileContentBytes=FileUtils.readFileToByteArray(file);
System.out.println("test.txt文件内容:"+lines);
System.out.println("test.txt文件内容(字节形式):"+fileContentBytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
第1个测试方法:读取百度首页
第2个测试方法,使用IOUtils类操作读取百度首页
第3个测试方法,使用FileUtils快捷操作文件读写
操作了多次,写了好几遍