[转] 工具包详解(二)之 Apache Commons

参考链接: https://blog.csdn.net/lhw_csd/article/details/81084862

2个月前 111次点击 来自 后端

标签: Java

Apache Commons是Apache开源的一个java组件库,其中包含了大量子项目,其中常用的组件有:

组件

功能介绍

BeanUtils

提供了对于JavaBean进行各种操作,克隆对象,属性等等.

Codec

处理常用的编码方法的工具类包 例如DESSHA1MD5Base64.

Collections

java集合框架操作.

Compress

java提供文件打包 压缩类库.

Configuration

一个java应用程序的配置管理类库.

DBCP

提供数据库连接池服务.

DbUtils

提供对jdbc 的操作封装来简化数据查询和记录读取操作.

Email

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


**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
@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<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快捷操作文件读写

操作了多次,写了好几遍

5.Lang3

是一个公共的工具合集,涵盖了字符串操作、数组操作、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="<h3>你好</h3>";
        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工具包(第三方工具包)

测试类工具包的结果:

6.Compress

用于打包、压缩文件的工具库

测试类,测试压缩单个文件为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();

            }
        }
    }

}


运行两个测试方法后,生成文件:

解压后的文件:

7.FileUpload

提供文件上传支持的工具包(同时需要common-io包的支持)

前端的form表单需要设定为enctype="multipart/form-data"

这个例子,我之前在springMVC上传文件中写到过:https://blog.csdn.net/u011174699/article/details/102559240

8.HttpClient

该工具包,顾名思义是和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","wwwpss19419@163.com"),
                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策略进行配置。

9.Email

开源的邮件工具包,是对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();
        }



    }

网易邮箱查看发送成功

本文转自 https://blog.csdn.net/u011174699/article/details/105863949,如有侵权,请联系删除。

Made with in Shangrao,China By Devler.

Copyright © Devler 2012 - 2022

赣ICP备19009883号-1

Top ↑