Apache Commons是Apache开源的一个java组件库,其中包含了大量子项目,其中常用的组件有:
组件 |
功能介绍 |
BeanUtils |
提供了对于JavaBean进行各种操作,克隆对象,属性等等. |
Codec |
处理常用的编码方法的工具类包 例如DES、SHA1、MD5、Base64等. |
Collections |
java集合框架操作. |
Compress |
java提供文件打包 压缩类库. |
Configuration |
一个java应用程序的配置管理类库. |
DBCP |
提供数据库连接池服务. |
DbUtils |
提供对jdbc 的操作封装来简化数据查询和记录读取操作. |
|
java发送邮件 对javamail的封装. |
FileUpload |
提供文件上传功能,需要commons -IO的支持 |
HttpClien |
对HTTP协议操作的封装,提供HTTP客户端与服务器的各种通信操作. 现在已改成HttpComponents |
IO |
io工具的封装. |
Lang |
Java基本对象方法的工具类包 如:StringUtils,ArrayUtils等等. |
Logging |
提供的是一个Java 的日志接口. |
Validator |
提供了客户端和服务器端的数据验证框架. |
接下来通过实例来说明各个组件的使用:
目录
1.BeanUtils
2.Codec
3.Collections
4.I/O
5.Lang3
6.Compress
7.FileUpload
8.HttpClient
9.Email
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
@AllArgsConstructor
@NoArgsConstructor
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 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个测试方法控制台输出:
处理常用的编码方法的工具类包 例如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之后是%2B,就可以正常解析了
对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 list1=Arrays.asList(arryays);
List 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);
}
}
集合操作的结果:
新集合操作结果:
对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 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快捷操作文件读写
操作了多次,写了好几遍
是一个公共的工具合集,涵盖了字符串操作、数组操作、JVM交互操作等,用的最新的3版本,所以叫Lang3
测试类:
import com.xiaomifeng1010.beanutils.bean.Person;
import org.apache.commons.lang3.*;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.ImmutableTriple;
import org.junit.Test;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
/**
* @author xiaomifeng1010
* @version 1.0
* @date: 2020/5/1 3:51
*/
public class Lang3Test {
/**
* 测试字符串工具类
*/
@Test
public void StringUtilsTest(){
// 声明一个字符串变量,内容是三个空格
String blank=" ";
// 判断是否为空,注意即使只有三个空格,空格也是内容,非empty,返回false
boolean isEmpty= StringUtils.isEmpty(blank);
System.out.println("字符串blank是否为空:"+isEmpty);
// 判断字符串是否是空白(blank),根据单词就可以知义,虽然有三个空格,但是是空白的内容,啥也看不到,所以返回true
boolean isBlank=StringUtils.isBlank(blank);
System.out.println("字符串blank内容是否为空白:"+isBlank);
String str=" xiao mi feng 1010 ";
// trim()方法只能去除字符串首尾的空格
str=StringUtils.trim(str);
System.out.println("str去除空格后:"+str+"你");
// 比较两个字符串是否相同,支持null
System.out.println("两个字符串是否相同:"+StringUtils.equals(str,"xiao mi feng 1010"));
// 字符串包含匹配
System.out.println("str中是否包含‘xiao mi feng'字符串:"+StringUtils.contains(str,"xiao mi feng"));
// 字符串分割,按照空格分割,该方法使用有些注意事项:他和String类中的split方法不同,自带的split方法使用正则表达式,
// 这个split方法直接使用完整的字符来匹配,且会丢弃空字符串
String[] splitStr=StringUtils.split(str," ");
System.out.println("str字符串分割后:"+ Arrays.toString(splitStr));
// 连接字符串
String joinStr=StringUtils.joinWith("-",splitStr);
System.out.println("splitStr以’-‘连接后:"+joinStr);
// 从某个字符后截取一段字符
String subStr=StringUtils.substringAfter(str,"feng");
System.out.println("str变量从feng之后截取的字符为:"+subStr);
// 从连接字符串的最后一个"-"之后截取
subStr=StringUtils.substringAfterLast(joinStr,"-");
System.out.println("joinStr字符串从最后一个连接符’-‘之后截取的字符:"+subStr);
// 判断是否为数字型字符串
System.out.println("'123'字符串是否为数字类型:"+StringUtils.isNumeric("123"));
// 对字符串中的HTML标签转义,主要用户页面响应输出时候,不需要浏览器解析标签,直接以字符原本的面貌展现
String htmlTagStr="你好
";
System.out.println("未转义前:"+htmlTagStr);
htmlTagStr=StringEscapeUtils.escapeHtml4(htmlTagStr);
System.out.println("html标签转义后:"+htmlTagStr);
}
/**
* 测试数组工具类
*/
@Test
public void arrayUtilsTest(){
// 合并两个数组
String[] array1=StringUtils.split("1,2,3,4",",");
String[] array2=StringUtils.split("a,b,c,d",",");
// 相当于复制扩充了一个新数组
String[] arrayUnion=ArrayUtils.addAll(array1,array2);
System.out.println("两个数组合并后:"+ArrayUtils.toString(arrayUnion));
// 反转数组元素
ArrayUtils.reverse(arrayUnion);
System.out.println("数组元素反转之后:"+ArrayUtils.toString(arrayUnion));
// 截取一定范围内数组元素,生成新的数组(截取索引为2-5的数组元素,包含索引2不包含索引5的元素)
// {d,c,b,a,4,3,2,1}截取索引2-5之后为{b,a,4}
String[] subArray=ArrayUtils.subarray(arrayUnion,2,5);
System.out.println("截取后的新数组为:"+ArrayUtils.toString(subArray));
// 随机排列数组元素,类似洗牌
ArrayUtils.shuffle(arrayUnion);
System.out.println("随机排列数组元素后:"+ArrayUtils.toString(arrayUnion));
// 二维数组可以转换成Map类型,目前这种不可以
// Map map=ArrayUtils.toMap(arrayUnion);
// System.out.println("数组转换成Map类型对象:"+map);
}
/**
* 测试随机类(产生随机数或随机字符)
*/
@Test
public void RandomUtilTest(){
// 生成随机数字;随机产生0-10范围内的整数,包括0,不包括10,前闭后开
int number = RandomUtils.nextInt(0, 10);
System.out.println("产生随机整数:" + number);
// 随机生成3个字符,组成一个字符串(包含字母和数字)
String randomStr=RandomStringUtils.random(3,true,true);
System.out.println("随机字符串:"+randomStr);
// 随机生成5个字符,包含数字和字母
randomStr=RandomStringUtils.randomAlphanumeric(5);
System.out.println("随机字符串:"+randomStr);
}
/**
* 测试数字类工具
*/
@Test
public void NumberUtilsTest(){
String numberStr="256";
int number=NumberUtils.toInt(numberStr);
System.out.println("数字型字符转换成int:"+number);
double numberD=NumberUtils.toDouble(numberStr+"t");
// 字符串转换为double类型,如果字符串格式不对或者为null,则返回double默认值0.0,并不会抛出异常
System.out.println("数字型字符转换成double:"+numberD);
// 数组中求最大值
long maxValue=NumberUtils.max(new long [] {
5L,7L,34L,2L,-1L
});
System.out.println("数组中最大值为:"+maxValue);
BigDecimal bigDecimal=NumberUtils.toScaledBigDecimal(5.23);
bigDecimal=bigDecimal.pow(2);
System.out.println(bigDecimal);
}
/**
* 测试日期工具类,感觉还是没有joda-time好用,推荐使用joda-time
*/
@Test
public void dateUtilsTest(){
// 设置年份
Date date=DateUtils.setYears(new Date(),2021);
String dateStr=DateFormatUtils.format(date,"YYYY-MM-dd HH:mm:ss");
System.out.println("设置年份后的日期为:"+dateStr);
// 几天后的日期
date=DateUtils.addDays(date,3);
System.out.println("三天后的日期:"+date);
// 截取日期,截取日期到小时,后边的分和秒设置为0
DateUtils.truncate(date, Calendar.HOUR);
}
/**
* 测试ClassUtils的用法
*/
@Test
public void classUtilsTest(){
// 获取类名
String className=ClassUtils.getShortClassName(Lang3Test.class);
System.out.println("本测试类的类名:"+className);
// 获取包名
String packageName=ClassUtils.getPackageName(Person.class);
System.out.println("Person类所在包名;"+packageName);
}
@Test
public void ImmutableTest() {
Person p1=new Person(13,"albert","male");
Person p2=new Person(18,"xiaohua","female");
Person p3= new Person(23,"tom","male");
// ImmutablePair可以包含两个对象,左右两个元素组成的不可变对
ImmutablePair immutablePair= ImmutablePair.of(p1,p2);
immutablePair.getLeft();
immutablePair.getRight();
// 可以存放三个对象的,分左,中,右
ImmutableTriple.of(p1,p2,p3);
}
}
测试字符串工具输出结果:
测试数组工具类的输出结果:
测试随机工具类的输出结果:
测试数字工具类的输出结果:
测试日期工具类的结果:
推荐使用joda-time工具包(第三方工具包)
测试类工具包的结果:
用于打包、压缩文件的工具库
测试类,测试压缩单个文件为zip文件,以及将zip文件解压到指定文件目录下
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import java.io.*;
import java.util.UUID;
/**
* @author xiaomifeng1010
* @version 1.0
* @date: 2020/5/1 13:26
*/
/**
* 测试压缩单个文件,将当前项目所在磁盘下的test.txt文件压缩为test.zip
*/
public class CompressTest {
@Test
public void compressFile2ZipTest() {
// 待压缩文件(项目当前所在磁盘下data目录下的test.txt文件)即E:\data\test.txt
File file = new File(File.separator + "data" + File.separator + "test.txt");
String filePath = file.getAbsolutePath();
System.out.println("待压缩文件的路径:" + filePath);
// 获取源文件名(去掉拓展名)
// fileName带有拓展名(即.txt)
String fileName=file.getName();
// 去掉拓展名
String shortFileName= StringUtils.substringBeforeLast(fileName,".");
// 输出的最终压缩文件(输出压缩文件到项目当前所在磁盘下data目录下的test.zip文件),E:\data\test.zip
File zipFile = new File(File.separator + "data" + File.separator +shortFileName+".zip");
// 先读取文件内容,然后再以压缩条目形式写出输出文件,形成一个压缩文件
try (FileInputStream fis = new FileInputStream(file);
ZipArchiveOutputStream zipOutput = new ZipArchiveOutputStream(zipFile)) {
// 创建压缩对象(zip压缩条目)
ZipArchiveEntry zipEntry = new ZipArchiveEntry(file,file.getName());
zipOutput.putArchiveEntry(zipEntry);
int j;
while ((j = fis.read()) != -1) {
zipOutput.write(j);
}
zipOutput.closeArchiveEntry();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 测试解压zip压缩文件(压缩文件中就一个文件,且层级就一级)
*/
@Test
public void decompressZipFileTest(){
// 待解压文件
File zipFile = new File(File.separator + "data" + File.separator + "test.zip");
if (!zipFile.exists()) {
System.out.println("压缩文件不存在");
}else{
try(InputStream is=new FileInputStream(zipFile);
ZipArchiveInputStream zais=new ZipArchiveInputStream(is)
){
ZipArchiveEntry zipEntry = null;
// 将zip压缩包中文件获取出来,然后写入到指定文件夹
while ((zipEntry=zais.getNextZipEntry())!=null){
// 获取压缩包层级目录文件名
String zipEntryFileName=zipEntry.getName();
System.out.println("压缩包文件名:"+zipEntryFileName);
// 解压出来的文件存放路径
String uuidName=UUID.randomUUID().toString();
// 项目所在磁盘下data目录下新建一个目录(目录名用uuid命名)
String dirPath=File.separator + "data" + File.separator+uuidName;
File dirFile=new File(dirPath);
if (!dirFile.exists()){
dirFile.mkdirs();
}
File file=new File(dirFile.getAbsolutePath()+File.separator+zipEntryFileName);
byte[] content = new byte[(int) zipEntry.getSize()];
// 按字节读取内容
zais.read(content);
try(OutputStream os=new BufferedOutputStream(new FileOutputStream(file))){
// 将内容写入到指定路径
os.write(content);
}
//
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行两个测试方法后,生成文件:
解压后的文件:
提供文件上传支持的工具包(同时需要common-io包的支持)
前端的form表单需要设定为enctype="multipart/form-data"
这个例子,我之前在springMVC上传文件中写到过:https://blog.csdn.net/u011174699/article/details/102559240
该工具包,顾名思义是和HTTP协议相关的,它提供客户端与服务端的各种通信操作,支持各种请求方法,SSL连接,Cookie和Session保持等,支持https请求。
实例测试类:
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.junit.Test;
import java.io.IOException;
/**
* @author xiaomifeng1010
* @version 1.0
* @date: 2020/5/1 22:28
*/
public class HttpClientTest {
/**
* 测试get请求,请求百度首页
*/
@Test
public void getMethodTest(){
HttpClient httpClient = new HttpClient();
String url ="http://www.baidu.com";
GetMethod getMethod=new GetMethod(url);
// 使用系统提供的默认的重试策略(请求不成功会重试3次)
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,new DefaultHttpMethodRetryHandler());
try {
// 执行请求,并返回响应码
int responseStatus=httpClient.executeMethod(getMethod);
if (responseStatus!= HttpStatus.SC_OK){
System.out.println("请求失败"+getMethod.getStatusLine());
}
// 获取响应内容
byte[] responseBody=getMethod.getResponseBody();
System.out.println(new String(responseBody));
} catch (IOException e) {
e.printStackTrace();
}finally {
getMethod.releaseConnection();
}
}
/**
* 测试post请求,Oracle官网注册
*/
@Test
public void PostMethodTest() {
// 创建HttpClient实例
HttpClient httpclient = new HttpClient();
String url="https://profile.oracle.com/myprofile/account/create-account.jspx";
// 创建post方法
PostMethod postMethod=new PostMethod(url);
// 填入各个表单域的值,请求Oracle官网注册页面,填入注册需要的邮箱,密码
NameValuePair[] requestParams ={new NameValuePair("email","[email protected]"),
new NameValuePair("password","123456")};
// 将post方法请求体的参数放入到请求体中
postMethod.setRequestBody(requestParams);
try {
// 执行post请求,并返回响应状态码
int responseStatusCode=httpclient.executeMethod(postMethod);
System.out.println("响应状态码:"+responseStatusCode+"\t"+postMethod.getStatusText());
// HttpClient对于要求接受后继服务的请求,象POST和PUT等不能自动处理转发
// 对于301或者302重定向的请求
if (responseStatusCode==HttpStatus.SC_MOVED_TEMPORARILY || responseStatusCode==HttpStatus.SC_MOVED_PERMANENTLY ){
Header locationHeader=postMethod.getResponseHeader("location");
String location = null;
if (location!=null){
location=locationHeader.getValue();
System.out.println("重定向到:"+location);
}else{
System.err.println("重定向失败");
//
}
return;
}
// 无需重定向,直接返回响应结果
byte[] responseBody=postMethod.getResponseBody();
System.out.println("注册Oracle官网:"+new String(responseBody));
} catch (IOException e) {
e.printStackTrace();
}
}
}
get请求百度首页
post请求Oracle官网注册页面
此外HttpClient工具包中,还可以设置http的连接池,HttpRequestBase(譬如子类HttpGet,HttpPost,HttpPut,HttpDelete等类),AsyncHttpClient用于异步通信的处理,使用HttpClientBuilder能够对HttpClient的Cookie以及connect timeout、socket timeout、keep live策略进行配置。
开源的邮件工具包,是对JavaMail API的封装,javamail项目地址:https://github.com/javaee/javamail/releases
测试发送邮件:
使用网易邮箱发送邮件
需要在邮箱中进行设置,开启mstp服务,然后会提示用手机发送短信,发送短信后,网页生成一个授权码
import org.apache.commons.mail.DefaultAuthenticator;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;
import org.junit.Test;
/**
* @author xiaomifeng1010
* @version 1.0
* @date: 2020/5/1 23:59
*/
public class CommonsEmailTest {
/**
* 测试网易邮箱发送邮件到qq邮箱;不带附件
*/
@Test
public void sendEmailTest(){
// SimpleEmail用来发送不带附件的邮件
Email email = new SimpleEmail();
// 设置邮箱服务器
String emailServerAddres="smtp.163.com";
email.setHostName(emailServerAddres);
// 邮件发送服务器端口号:SSL->994/25,25是企业邮箱端口
final int SMTP_PORT = 994;
email.setSmtpPort(SMTP_PORT);
// 邮箱登录用户名,即邮箱地址
final String AUTH_USERNAME="your email address";
// 客户端授权密码,不是邮箱登录密码
final String AUTH_PASSWORD="ORKTJFLLVKGBZSYR";
// 以授权方式登录
email.setAuthenticator(new DefaultAuthenticator(AUTH_USERNAME,AUTH_PASSWORD));
email.setSSLOnConnect(true);
try {
// 设置发件人
email.setFrom(AUTH_USERNAME);
// 设置邮件主题
email.setSubject("发送邮件测试");
// 邮件内容
email.setMsg("你好,xiaomifeng1010");
// 设置收件人
email.addTo("another email address");
email.send();
System.out.println("发送成功");
} catch (EmailException e) {
e.printStackTrace();
}
}
}
在网易邮箱的已发送中可以看到刚刚发送的邮件
然后登录QQ邮箱查看一下邮箱,收件箱收到了邮件
注意SimpleEmail只能发送不带附件的邮件,要发送带附件的邮件使用另外三个继承类就可以了
使用MultipartEmail发送带文件的邮件
/**
* 测试发送带有附件的邮件(本地文件作为附件)
*/
@Test
public void AttachEmailTest(){
// 设置带附件
MultiPartEmail email = new MultiPartEmail();
// 设置邮箱服务器
String emailServerAddres = "smtp.163.com";
email.setHostName(emailServerAddres);
// 邮件发送服务器端口号:SSL->994/25,25是企业邮箱端口
final int SMTP_PORT = 994;
email.setSmtpPort(SMTP_PORT);
// 邮箱登录用户名,即邮箱地址
final String AUTH_USERNAME = "email address";
// 客户端授权密码,不是邮箱登录密码
final String AUTH_PASSWORD = "ORKTJFLLVKGBZSYR";
// 以授权方式登录
email.setAuthenticator(new DefaultAuthenticator(AUTH_USERNAME, AUTH_PASSWORD));
email.setSSLOnConnect(true);
try {
// 设置发件人
email.setFrom(AUTH_USERNAME);
// 设置邮件主题
email.setSubject("发送测试邮件,有附件");
// 邮件内容
email.setMsg("你好,xiaomifeng1010");
// 设置收件人
email.addTo("another email address");
// 创建附件对象
EmailAttachment attachment = new EmailAttachment();
// 附件的文件路径(将本项目坐在磁盘下的data目录下的test.txt文件作为附件)
String filePath= File.separator+"data"+File.separator+"test.txt";
File file=new File(filePath);
// 附件名称
String attachmentName="测试用附件";
attachment.setPath(filePath);
attachment.setName(attachmentName);
// 设置附件排列方式
attachment.setDisposition(EmailAttachment.ATTACHMENT);
// 添加附件
email.attach(file);
// 发送邮件
email.send();
System.out.println("带附件邮件发送成功");
} catch (EmailException e) {
e.printStackTrace();
}
}
网易邮箱查看发送成功