# 其他常用类

back2 专题

# Enum

返回顶部

一般使用方法

public enum DeviceType {
     Firecontrolhost(
            "消控主机",
            getTableName(com.faith.mvc.entity.TsBiFirecontrolhost.class),
            getTableName(com.faith.mvc.entity.TsDataFirecontrolhost.class),
            Lists.newArrayList(
                    WarningProcessType.Misinformation,
                    WarningProcessType.Fault,
//                    WarningProcessType.Abnormal,
                    WarningProcessType.Fire,
                    WarningProcessType.Other
            ),
            "T.EQUIPNO,T.EQUIPNAME"
    ),
    OtherDevice("其它设备", getTableName(com.faith.mvc.entity.TsBiOtherDevice.class), null,
            Lists.newArrayList(WarningProcessType.Misinformation, WarningProcessType.Fault,   WarningProcessType.Other),
            "");
    private String typeName;
    private String busiTable;
    private String dataTable;
    private List<WarningProcessType> warningProcessTypes;
    private Map<String, String> processStatusMap;
    private String specialFields;
    /*
     * @param typeName            类型名称
     * @param busiTable           基础表名
     * @param dataTable           数据表名
     * @param warningProcessTypes 拥有的告警类型
     */
    DeviceType(String typeName, String busiTable, String dataTable, List<WarningProcessType> warningProcessTypes,String specialFields) {
        this.typeName = typeName;
        this.busiTable = busiTable;
        this.dataTable = dataTable;
        this.warningProcessTypes = warningProcessTypes;
        this.specialFields=specialFields;

        processStatusMap = new HashMap<>();
        for (WarningProcessType warningProcessType : warningProcessTypes) {
            processStatusMap.put(warningProcessType.getStatus(), warningProcessType.getStatusName());
        }
    }
public static DeviceType getByTable(String table) {
    if (StringUtils.isBlank(table)) {
        return null;
    }

    for (DeviceType deviceType : DeviceType.values()) {
        if (StringUtils.equals(deviceType.getBusiTable(), table)
                || StringUtils.equals(deviceType.getDataTable(), table)) {
            return deviceType;
        }
    }
    return null;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

# FTP

返回顶部

package com.faith.utils;

import com.faith.exception.BusinessException;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.log4j.Logger;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class FtpUtil {
    private static Logger log = Logger.getLogger(FtpUtil.class);

    private FTPClient ftpClient;
    public static final int BINARY_FILE_TYPE = FTP.BINARY_FILE_TYPE;
    public static final int ASCII_FILE_TYPE = FTP.ASCII_FILE_TYPE;

    /**
     * 每次Ftp操作前,先获取连接
     *
     * @param server   Ftp服务器地址,IP
     * @param port     Ftp端口
     * @param user     用户名
     * @param password 密码
     * @param path     工作间
     * @return void 返回类型
     * @throws SocketException
     * @throws IOException     设定文件
     * @Title: connectServer
     * @author zhuyj
     */
    private void connectServer(String server, int port, String user,
                              String password, String path) throws SocketException, IOException {
        ftpClient = new FTPClient();
        ftpClient.setDataTimeout(120000);       //设置传输超时时间为60秒
        ftpClient.setConnectTimeout(120000);       //连接超时为60秒

//        ftpClient.setFileType(BINARY_FILE_TYPE);
        /**
         * 解决中文文件名乱码问题
         */
        ftpClient.setControlEncoding("GBK");
        ftpClient.connect(server, port);
        log.info("Connected to " + server + ".");
        log.info(ftpClient.getReplyCode());
        /**
         * 登陆Ftp
         */
        ftpClient.login(user, password);

        //进入多级目录,若不存在则创建
        createAndChangeDirs(path);
//        /**
//         * 如果Ftp中不存在此目录则创建
//         */
//        if (path.length() != 0 && !existDirectory(path)) {
//            ftpClient.makeDirectory(path);
//        }
//        /**
//         * 设置此目录为工作
//         */
//        if (path.length() != 0) {
//            ftpClient.changeWorkingDirectory(path);
//        }

    }

    /**
     * FTP.BINARY_FILE_TYPE | FTP.ASCII_FILE_TYPE
     * 设置传输文件格式
     *
     * @author zhuyj
     */
    public void setFileType(int fileType) throws IOException {
        ftpClient.setFileType(fileType);
    }

    /**
     * 每次Ftp时必须获取异常,在finally块中关闭连接
     *
     * @throws IOException
     * @author zhuyj
     */
    public void closeServer() throws IOException {
        try {
            /**
             * 关闭连接前先退出登陆
             *
             */
            ftpClient.logout();
        } catch (RuntimeException e) {
            log.error("关闭Ftp连接错误:" + e.getMessage());
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (ftpClient.isConnected()) {
                ftpClient.disconnect();
            }
        }
    }

    /**
     * 更改工作间
     *
     * @param path
     * @return boolean 返回类型
     * @throws IOException 设定文件
     * @Title: changeDirectory
     * @Description: TODO(这里用一句话描述这个方法的作用)
     * @author zhuyj
     */
    public boolean changeDirectory(String path) throws IOException {
        return ftpClient.changeWorkingDirectory(path);
    }

    /**
     * 创建目录
     *
     * @param pathName
     * @return boolean 返回类型
     * @throws IOException 设定文件
     * @throws
     * @Title: createDirectory
     * @Description: TODO(这里用一句话描述这个方法的作用)
     * @author zhuyj
     */
    public boolean createDirectory(String pathName) throws IOException {
        return ftpClient.makeDirectory(pathName);
    }

    /**
     * 创建多级目录
     * @param remote
     * @throws UnsupportedEncodingException
     * @throws IOException
     */
    public void createAndChangeDirs(String remote)throws UnsupportedEncodingException, IOException {

        //以/结尾,确保最后一个目录被创建
        if(!remote.endsWith("/")){
            remote += "/";
        }

        String directory = remote.substring(0, remote.lastIndexOf("/") + 1);

        if (!directory.equals("/") && !ftpClient.changeWorkingDirectory(

                new String(directory.getBytes("GBK"), "iso-8859-1"))) {

            // 如果远程目录不存在,则递归创建远程服务器目录
            int start = 0;
            int end = 0;
            if (directory.startsWith("/")) {
                start = 1;
            } else {
                start = 0;
            }

            end = directory.indexOf("/", start);

            while (true) {

                String subDirectory = new String(remote.substring(start, end).getBytes("GBK"),"iso-8859-1");

                if (!ftpClient.changeWorkingDirectory(subDirectory)) {

                    if (ftpClient.makeDirectory(subDirectory)) {

                        ftpClient.changeWorkingDirectory(subDirectory);
                    } else {
                        throw new BusinessException("01", "目录创建失败");
                    }
                }

                start = end + 1;

                end = directory.indexOf("/", start);

                // 检查所有目录是否创建完毕
                if (end <= start ) {
                    break;
                }
            }
        }
    }

    /**
     * 删除目录
     *
     * @param path
     * @return boolean 返回类型
     * @throws IOException 设定文件
     * @throws
     * @Title: removeDirectory
     * @Description: TODO(这里用一句话描述这个方法的作用)
     * @author zhuyj
     */
    public boolean removeDirectory(String path) throws IOException {
        return ftpClient.removeDirectory(path);
    }

    /**
     * @param path
     * @param isAll
     * @return boolean 返回类型
     * @throws IOException 设定文件
     * @Title: removeDirectory
     * @Description: 删除Ftp目录
     * @author zhuyj
     */
    public boolean removeDirectory(String path, boolean isAll)
            throws IOException {
        if (!isAll) {
            return removeDirectory(path);
        }

        FTPFile[] ftpFileArr = ftpClient.listFiles(path);
        if (ftpFileArr == null || ftpFileArr.length == 0) {
            return removeDirectory(path);
        }

        for (FTPFile ftpFile : ftpFileArr) {
            String name = ftpFile.getName();
            if (ftpFile.isDirectory()) {
                /**
                 * 去掉.和..,否则死循环了
                 */
                if (!ftpFile.getName().equals(".") && (!ftpFile.getName().equals(".."))) {
                    System.out.println("* 删除子目录 [" + path + "/" + name + "]");
                    removeDirectory(path + "/" + name, true);
                }
            } else if (ftpFile.isFile()) {
                System.out.println("* 删除文件 [" + path + "/" + name + "]");
                deleteFile(path + "/" + name);
            } else if (ftpFile.isSymbolicLink()) {

            } else if (ftpFile.isUnknown()) {

            }
        }
        return ftpClient.removeDirectory(path);
    }

    /**
     * 检查当前路径是否存在目录?存在返回true,否则返回false
     */
    public boolean existDirectory(String path) throws IOException {
        boolean flag = false;
        FTPFile[] ftpFileArr = ftpClient.listFiles();
        for (FTPFile ftpFile : ftpFileArr) {
            if (ftpFile.isDirectory()
                    && ftpFile.getName().equalsIgnoreCase(path)) {
                flag = true;
                break;
            }
        }
        return flag;
    }

    /**
     * 检查当前路径是否存在文件?存在返回true,否则返回false
     */
    public boolean existFile(String path) throws IOException {
        boolean flag = false;
        FTPFile[] ftpFileArr = ftpClient.listFiles();
        for (FTPFile ftpFile : ftpFileArr) {
            if (ftpFile.isFile()
                    && ftpFile.getName().equalsIgnoreCase(path)) {
                flag = true;
                break;
            }
        }
        return flag;
    }

    /**
     * 检查当前路径是否存在文件?存在返回true,否则返回false
     */
    public boolean existFile(String path, String fileName) throws IOException {
        boolean flag = false;
        System.out.println(flag);
        System.out.println(ftpClient);

        FTPFile[] ftpFileArr = ftpClient.listFiles(path);
        for (FTPFile ftpFile : ftpFileArr) {
            if (ftpFile.isFile() && ftpFile.getName().equalsIgnoreCase(fileName)) {
                flag = true;
                break;
            }
        }

        return flag;
    }

    /**
     * @param path
     * @return List<String> 返回类型
     * @throws IOException 设定文件
     * @throws
     * @Title: 获取ftp目录所有文件
     * @Description: TODO(这里用一句话描述这个方法的作用)
     * @author zhuyj
     */
    public List<String> getFileList(String path) throws IOException {

        FTPFile[] ftpFiles = ftpClient.listFiles(path);

        List<String> retList = new ArrayList<String>();
        if (ftpFiles == null || ftpFiles.length == 0) {
            return retList;
        }
        for (FTPFile ftpFile : ftpFiles) {
            if (ftpFile.isFile()) {
                retList.add(ftpFile.getName());
            } else {
                retList.add(ftpFile.getName());
            }
        }
        return retList;
    }

    /**
     * @param pathName
     * @return boolean 返回类型
     * @throws IOException 设定文件
     * @throws
     * @Title: 删除ftp文件
     * @Description: TODO(这里用一句话描述这个方法的作用)
     */
    public boolean deleteFile(String pathName) throws IOException {
        boolean flag = ftpClient.deleteFile(pathName);
        return flag;
    }

    /**
     * 文件上传
     *
     * @param fileName
     * @param newName
     * @return
     * @throws IOException
     */
    public boolean uploadFile(String fileName, String newName)
            throws IOException {
        boolean flag = false;
        InputStream iStream = null;
        try {
            iStream = new FileInputStream(fileName);
            int i = iStream.available();
            if (i > 0) {
                flag = ftpClient.storeFile(newName, iStream);
            }

        } catch (IOException e) {
            log.error("上传服务器文件到Ftp错误:" + e.getMessage());
            e.printStackTrace();
            flag = false;
            return flag;
        } finally {
            if (iStream != null) {
                iStream.close();
            }
        }
        return flag;
    }

    /**
     * @param fileName
     * @return boolean 返回类型
     * @throws IOException 设定文件
     * @throws
     * @Title: uploadFile
     * @Description: TODO(这里用一句话描述这个方法的作用)
     */
    public boolean uploadFile(String fileName) throws IOException {
        int i = fileName.lastIndexOf("/");
        log.debug("fileName:" + fileName);
        log.debug("newName:" + fileName.substring(i).replaceAll("/", ""));
        return uploadFile(fileName, fileName.substring(i).replaceAll("/", ""));
    }

    /**
     * FTP文件上传方法
     *
     * @param file   上传的文件
     * @param folder 上传到的具体的目录,可根据业务场景自行定义,比如富琦维保项目的项目合同: fqwbht
     * @return 返回文件值对象,含文件的原始名称,新名称,最终的访问地址,文件类型,后缀等
     * @throws IOException
     */
    public static FileVO uploadFile(MultipartFile file, String folder) {

        try {
            FileVO fileVO = uploadFile(file.getOriginalFilename(), file.getInputStream(), folder);
            return fileVO;
        } catch (IOException e) {
            log.error("上传文件到Ftp错误:", e);
            throw new BusinessException("01", "文件上传失败");
        }
    }

    /**
     * FTP文件上传方法
     *
     * @param fileName   上传的文件名
     * @param inputStream   文件流
     * @param folder 上传到的具体的目录,可根据业务场景自行定义,比如富琦维保项目的项目合同: fqwbht
     * @return 返回文件值对象,含文件的原始名称,新名称,最终的访问地址,文件类型,后缀等
     * @throws IOException
     */
    public static FileVO uploadFile(String fileName, InputStream inputStream, String folder) {
        boolean flag = false;
        FtpUtil ftp = null;
        try {
            //String fileName = file.getOriginalFilename();
            int index = fileName.lastIndexOf(".");
            // 后缀
            String ext = fileName.substring(index + 1);
            // 保前缀
            String qz = fileName.substring(0, index);
            String id = UUID.randomUUID().toString();
            // 图片新名称
            String fileNewName = id + "." + ext;
            ftp = FtpUtil.getFtpUtil(folder);
            flag = ftp.ftpClient.storeFile(fileNewName, inputStream);
            //上传成功,返回文件对象
            if (!flag) {
                throw new BusinessException("01", "文件上传失败");
            }

            String filePath = folder + "/" + fileNewName;
            FileVO fileVO = new FileVO(fileName, fileNewName, filePath, Constants.getFtpFullImageUrl(filePath), ext);
            return fileVO;
        } catch (IOException e) {
            log.error("上传文件到Ftp错误:", e);
            throw new BusinessException("01", "文件上传失败");
        } finally {
            try {
                if (ftp != null)
                    ftp.closeServer();
            } catch (IOException e) {
                log.error("Ftp流关闭错误:", e);
            }
        }
    }


    /**
     * 从远程下载文件到应用服务器
     *
     * @param remoteFileName
     * @param localFileName
     * @return
     * @throws IOException
     * @author zhuyj
     */
    public boolean download(String remoteFileName, String localFileName)
            throws IOException {
        boolean flag = false;
        File outfile = new File(localFileName);
        OutputStream oStream = null;
        try {
            oStream = new FileOutputStream(outfile);
            flag = ftpClient.retrieveFile(remoteFileName, oStream);
        } catch (IOException e) {
            log.error("下载Ftp文件到服务器错误:" + e.getMessage());
            flag = false;
            return flag;
        } finally {
            if (oStream != null) {
                oStream.close();
            }
        }
        return flag;
    }

    /**
     * 从远程下载文件
     *
     * @param filePath
     * @param localFileName
     * @return
     * @throws IOException
     * @author zhuyj
     */
    public static void download(String filePath, OutputStream outputStream) {

        try {

            int index = filePath.lastIndexOf("/");
            String folder = filePath.substring(0, index);
            String fileName = filePath.substring(index + 1);

            FtpUtil.getFtpUtil(folder).ftpClient.retrieveFile(fileName, outputStream);
        } catch (IOException e) {
            log.error("下载文件错误:", e);
            throw new BusinessException("01", "文件下载失败");
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.flush();
                    outputStream.close();
                } catch (IOException e) {
                    log.error("文件输出流关闭失败", e);
                }
            }
        }
    }


    /**
     * 批量从FTP下载文件到应用服务器
     *
     * @param remotePath ftp文件路径
     * @param localPath  应用服务器文件路径
     * @param fileNames  需要下载的文件名称
     * @return void 返回类型
     * @throws IOException 设定文件
     * @throws
     * @Title: download
     * @Description: TODO(这里用一句话描述这个方法的作用)
     */
    public void download(String remotePath, String localPath, List<String> fileNames)
            throws IOException {
        for (String name : fileNames) {
            /*
             * 应用服务器文件
             */
            String localFileName = localPath + "/" + name;
            /*
             * ftp文件
             */
            String remoteFileName = remotePath + name;
            File outfile = new File(localFileName);
            OutputStream oStream = null;
            try {
                oStream = new FileOutputStream(outfile);
                ftpClient.retrieveFile(remoteFileName, oStream);
            } catch (IOException e) {
                log.error("下载Ftp文件到服务器错误:" + e.getMessage());
            } finally {
                if (oStream != null) {
                    oStream.close();
                }
            }
        }
    }

    /**
     * 从Ftp中获取文件输入流
     *
     * @param sourceFileName
     * @return
     * @throws IOException
     * @author zhuyj
     */
    public InputStream downFile(String sourceFileName) throws IOException {
        return ftpClient.retrieveFileStream(sourceFileName);
    }

    public static FtpUtil getFtpUtil(String path) throws IOException {
        FtpUtil ftp = new FtpUtil();
        try {
            String ftpurl = Constants.getFtpUrl();
            String port = Constants.getFtpPort();
            String user = Constants.getFtpUser();
            String pws = Constants.getFtpPass();
            ftp.connectServer(ftpurl, 21, user, pws, path);
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ftp;

    }


    public static void main(String[] args) {
        FtpUtil ftp = new FtpUtil();
        try {
            ftp.connectServer(Constants.getFtpUrl(), Integer.parseInt(Constants.getFtpPort()), Constants.getFtpUser(), Constants.getFtpPass(), "image");
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            boolean uploadFlag = ftp.uploadFile("d:/test.jpg");
            System.out.println("uploadFlag:" + uploadFlag);
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                ftp.closeServer();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606

# FileUpload

返回顶部

package com.faith.utils;

import com.faith.exception.BusinessException;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.*;
import java.util.function.Function;

public class FileUploadUtil {

   private static final Logger logger = Logger.getLogger(FileUploadUtil.class);

   /**
    *  将图片文件转化为字节数组字符串,并对其进行Base64编码处理
    * @param imgFilePath 路径
    * @return
    */
   public static String ImgToBase(String imgFilePath) {
      byte[] data = null;

      // 读取图片字节数组
      try {
         InputStream in = new FileInputStream(imgFilePath);
         data = new byte[in.available()];
         in.read(data);
         in.close();
      } catch (IOException e) {
         e.printStackTrace();
      }

      // 对字节数组Base64编码
      BASE64Encoder encoder = new BASE64Encoder();
      if(null != data){
         return encoder.encode(data);// 返回Base64编码过的字节数组字符串
      }
      return null;
   }

   /**
    *  Base64字符串解码并生成图片
    * @param imgStr 字符串
    * @param imgFilePath 路径
    * @return
    */
   public static boolean BaseToImg(String imgStr, String imgFilePath,String imgName) {
      if (imgStr == null) // 图像数据为空
         return false;
      File file =new File(imgFilePath);
      if(!file.exists()){
         file.mkdirs();
      }
      BASE64Decoder decoder = new BASE64Decoder();
      try {
         // Base64解码
         byte[] bytes = decoder.decodeBuffer(imgStr);
         for (int i = 0; i < bytes.length; ++i) {
            if (bytes[i] < 0) {// 调整异常数据
               bytes[i] += 256;
            }
         }
         // 生成jpeg图片
         OutputStream out = new FileOutputStream(imgFilePath+"\\"+imgName);
         out.write(bytes);
         out.flush();
         out.close();
         return true;
      } catch (Exception e) {
         return false;
      }
   }

   public static <T> List<T> upload(HttpServletRequest request, Function<FileMap, T> fun,Long maxSize){

      if (!ServletFileUpload.isMultipartContent(request)) {
         throw new BusinessException("01", "没有待上传的文件");
      }

      try {
         // 1. 创建DiskFileItemFactory对象,设置缓冲区大小和临时文件目录
         DiskFileItemFactory factory = new DiskFileItemFactory();
         // 2. 创建ServletFileUpload对象,并设置上传文件的大小限制。
         ServletFileUpload sfu = new ServletFileUpload(factory);
         //限制大小
         if(null != maxSize && maxSize > 0){
            sfu.setSizeMax(maxSize);
         }
         sfu.setHeaderEncoding("utf-8");

         // 3.
         // 调用ServletFileUpload.parseRequest方法解析request对象,得到一个保存了所有上传内容的List对象。
         List<FileItem> fileItemList = sfu.parseRequest(request);
         Iterator<FileItem> fileItems = fileItemList.iterator();

         //提取请求参数
         Map<String, String> params = new HashMap<>();

         List<FileItem> fileList = new ArrayList<>();

         // 4. 遍历list,每迭代一个FileItem对象,调用其isFormField方法判断是否是上传文件
         while (fileItems.hasNext()) {
            FileItem fileItem = fileItems.next();
            // 普通表单元素
            if (fileItem.isFormField()) {

               String name = fileItem.getFieldName();// name属性值
               String value = fileItem.getString("utf-8");// name对应的value值
               params.put(name, value);

            } else { // <input type="file">的上传文件的元素

               fileList.add(fileItem);
            }
         }

         FileMap fileMap = new FileMap();
         fileMap.setParams(params);

         List<T> list = new ArrayList<>();
         for (FileItem fileItem : fileList) {

            fileMap.setFileItem(fileItem);

            T t = fun.apply(fileMap);
            list.add(t);

            // 6. 调用FileItem的delete()方法,删除临时文件
            fileItem.delete();
         }

         return list;

      } catch (UnsupportedEncodingException e) {
         logger.error("文件上传-参数编码解析异常", e);
         throw new BusinessException("01", "参数解析失败");
      } catch (FileUploadException e) {
         logger.error("文件上传异常", e);
         throw new BusinessException("01", "文件上传失败");
      }
   }

   /**
    * 文件上传MAP
    */
   public static class FileMap{
      private FileItem fileItem;
      private Map<String, String> params;

      public FileItem getFileItem() {
         return fileItem;
      }

      public void setFileItem(FileItem fileItem) {
         this.fileItem = fileItem;
      }

      public Map<String, String> getParams() {
         return params;
      }

      public void setParams(Map<String, String> params) {
         this.params = params;
      }
   }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

# 反射

返回顶部

# Java 中的反射机制

back

# 反射中常见的类

  • Class 类

Class 类实例表示正在运行的 Java 应用程序中的类和接口。Class 是普通类、接口、枚举类、数组等的抽象,即它们的类型就是 Class,它们是 Class 的实例。
既然 Class 代表着类和接口,那么我们可以通过他的实例(字节码文件)来获取对应类或接口的信息,如:注解、修饰符、类型、类的名称、属性、方法、构造方法、直接父类和子类等,还有可以创建它的实例,但只能调用无参构造方法来创建

  • Field 类

Field 表示类的属性,属性含有修饰符、类型、属性名称和值。所以可以通过 Field 的实例获取属性的修饰符、类型、属性名称,并且可以修改属性的值。

  • Method 类

Method 表示类的成员方法,方法包括注解、修饰符、返回类型、方法名,参数等。所以可以通过 Method 的实例获取方法的的信息,如,注解、修饰符、返回类型、方法名并且可以调用所表示的方法。

  • Constructor 类

Constructor 表示构造方法,可以通过 Constructor 的实例获取构造方法的信息,如,修饰符等,并且可以通过它来创建它所在类的的实例。

  • Modifier 类

Modifier 表示修饰符,可通过它来获取修饰符的信息,例如何种修饰符等

  • Annotation

Annotation 代表注解

以上类都位于 java.lang 中

# 获取 Class 对象的方法

首先要获取 Class 对象吧,因为 Class 对象是代表着各种类,有了它之后才可以得到类的各种信息。获取方法如下:

  • 1)通过 object.getClass()
public static void main(String[] args) {
 Car car = new Car();
 Class clazz = car.getClass();
 }
1
2
3
4

注意:此方法不适用于 int、float 等基本类型

  • 2)通过(类型名).class、包装类.Type
public static void main(String[] args) {
 Class clazz = Car.class;
 Class cls1 = int.class;
 Class cls2 = String.class;
 Class cls3=Iteger.Type
 }
1
2
3
4
5
6
  • 3)通过 Class.forClass(String 类的全限定名)
try {
 Class clz = Class.forName("com.frank.test.Car");
} catch (ClassNotFoundException e) {
 e.printStackTrace();
}
1
2
3
4
5

采用哪种方法来获取,看实际情况而定。

# 获取类信息

有了 Class 对象后,就可以获取类的成员(方法+属性)注解类的修饰符等。上面也说了,java 中方法用 Method 类表示、属性用 Field 类表示、注解用 Annotation 类来表示、修饰符用 Modifier 类表示。Class 类中有对应的方法来获取他们。如下:

  • 获取属性 Field 的对象
//获取所有的属性,但不包括从父类继承下来的属性
public Field[] getDeclaredFields() throws SecurityException
//获取自身的所有的 public 属性,包括从父类继承下来的。
public Field[] getFields() throws SecurityException
//获取在本类中声明的指定的属性,参数为属性的名称
public Field getDeclaredField(String name)
//获取指定的公有属性,包括父类的,参数为属性的名称
public Field getField(String name)
1
2
3
4
5
6
7
8
  • 获取方法 Method 对象
//获取本类声明指定的的方法,第一个参数是方法的名称,后面的参数是方法参数类型的类,
//如获取setName(String name)方法,getDeclareMethod(“setName”,String.Class)
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
//获取公有的方法,包括父类的
public Method getMethod(String name, Class<?>... parameterTypes)
//获取本类中声明的所有方法
public Method[] getDeclaredMethods()
//获取所有的公有方法,包括父类的
public Method[] getMethods()
1
2
3
4
5
6
7
8
9
  • 获取构造器 Constructor 对象
//获取本类中指定的构造方法
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
//获取指定的公有构造方法
public Constructor<T> getConstructor(Class<?>... parameterTypes)
//获取本类中所有的构造方法
public Constructor<?>[] getDeclaredConstructors() throws SecurityException
//获取本类中所有的公有构造方法
public Constructor<?>[] getConstructors()
1
2
3
4
5
6
7
8

构造方法的获取与普通方法的获取大致是一样的。

# 获取类成员信息

上面只是获取了类的成员所代表类的对象,我们还要使用他们或者获取成员的信息(名称、修饰符等)。因为有了代表成员的对象,使用对象调用实例方法就可以了。

# Field 类

Field 类的方法大概可以分为两种,一种是获取属性的信息,另外一种是设置属性的值。

  • 第一种
//返回由此 Field对象表示的字段的名称
 String getName()
//返回一个 类对象标识了此表示的字段的声明类型 Field对象。
Class<?> getType()
//返回由该 Field对象表示的字段的Java语言修饰符,作为整数。把整数作为Modifier的构造方法的参数,就可以获取该整数代表的修饰符类的对象了
int getModifiers()
// ----------------------------------------------------------------
//获取类型为 int的静态或实例字段的值,或通过扩展转换转换为类型 int的另一个原始类型的值。
int getInt(Object obj)
//获取类型为 long的静态或实例字段的值,或通过扩大转换获得可转换为类型 long的另一个基本类型的值。
long getLong(Object obj)
1
2
3
4
5
6
7
8
9
10
11

......此处省略一堆 get**(Object obj)的方法,属性是什么基本类型,就 get 什么就行了

14 属性是引用类型,那么就调用以下方法 //返回该所表示的字段的 Field ,指定的对象上。 16 Object get(Object obj)

  • 第二种
//设置作为一个字段的值 double指定的对象上。
void setDouble(Object obj, double d)
//设置作为一个字段的值 float指定的对象上。
void setFloat(Object obj, float f)
//设置作为一个字段的值 int指定的对象上。
void setInt(Object obj, int i)
1
2
3
4
5
6

........此处省略一堆 set\*\*()方法,属性是什么基本类型就 set 什么就行了

  • 属性是引用类型,那么就调用以下方法
//将指定对象参数上的此 Field对象表示的字段设置为指定的新值。
void set(Object obj, Object value)
1
2

注意啦:如果没有访问权限的话,默认是不能设置属性值的,那怎么办呢?

这时我们调用 Class 对象的setAccessible(true)方法就可以了!

# Method 类

Method 类的方法主要是获取方法的信息

部分方法:

int getModifiers() //返回由该对象表示的可执行文件的Java语言modifiers 。
String getName() //返回由此 方法对象表示的方法的名称,作为 String 。
Annotation[][] getParameterAnnotations() //返回一个 Annotation s的数组数组,表示由该对象表示的Executable的形式参数的声明顺序的 Executable 。
int getParameterCount() //返回由此对象表示的可执行文件的形式参数(无论是显式声明还是隐式声明)的数量。
Class<?>[] getParameterTypes() //返回一个 类对象的数组, 类以声明顺序表示由该对象表示的可执行文件的形式参数类型。
1
2
3
4
5

# Constructor 类

Constructor 类的方法主要是获取构方法的信息和创建对象

获取方法信息:

int getModifiers() //返回由该对象表示的可执行文件的Java语言modifiers 。
String getName() //以字符串形式返回此构造函数的名称。
Annotation[][] getParameterAnnotations() //返回的数组的数组 Annotation表示的形参进行注释s时,声明顺序的的 Executable该对象表示。
int getParameterCount() //返回由此对象表示的可执行文件的形式参数(无论是显式声明还是隐式声明)的数量。
Class<?>[] getParameterTypes() //返回一个 类对象的数组, 类以声明顺序表示由该对象表示的可执行文件的形式参数类型。
1
2
3
4
5

# 反射创建对象和调用方法

# 创建普通类的对象

创建普通类的对象可以分为两种方法

  • 第一种:调用 Class 对象的方法
//首先获取Class对象
Class clazz=Class.forClass("test.Student");
//创建对象
Student stu=(Student)clazz.newInstance();
1
2
3
4

注:此方法只能创建无参构造函数的类的对象

  • 第二种:通过 Constructor 的 newInstance()方法
//首先创建Class对象
Class clazz=Class.forClass("test.Student");
//获取想调用的构造函数
Constructor constructor=clazz.getConstructor(String.class, int.class);
//调用Constructor的newInstance()方法
Student stu=(Student)constructor.newInstance("大王"20);
1
2
3
4
5
6

# 创建数组

数组本质上是一个 Class,而在 Class 中存在一个方法用来识别它是否为一个数组。
反射创建数组是通过 Array.newInstance(T.class,维数)这个方法。
第一个参数指定的是数组内的元素类型,后面的是可变参数,表示的是相应维度的数组长度限制。

比如,我要创建一个 int[2][3] 的数组。

Int[][] a=Array.newInstance(Integer.TYPE, 2, 3);
1

# 调用方法

用了上面的方法,就有 Class 对象,有方法 Method 对象,有实例,现在已经万事俱备,只欠东风了。
那我们怎么调用方法呢?在 Method 类有这么一个方法Object invoke(Object obj,Object... args),object 为实例对象,args 为调用方法的参数

来个栗子:

Class<?> c = Class.forName("com.kal01.reflect05.Person");//获取Class对象
Person p1 = (Person) c.newInstance();//获取实例
Method m3 = c.getDeclaredMethod("test");//获取方法
m3.setAccessible(true);//当没有访问权限时,设置一下就可以
m3.invoke(p1);//调用方法
m3.setAccessible(false);//修改了访问权限,记得修改回来
1
2
3
4
5
6

# 反射工具类

back

/**
 * Copyright (c) 2005-2012 springside.org.cn
 */
package com.faith.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

import java.lang.reflect.*;

/**
 * 反射工具类.
 * 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数.
 * @author calvin
 * @version 2013-01-15
 */
@SuppressWarnings("rawtypes")
public class Reflections {
   private static final String SETTER_PREFIX = "set";

   private static final String GETTER_PREFIX = "get";

   private static final String CGLIB_CLASS_SEPARATOR = "$$";
   private static Logger logger = LoggerFactory.getLogger(Reflections.class);

   /**
    * 调用Getter方法.
    * 支持多级,如:对象名.对象名.方法
    */
   public static Object invokeGetter(Object obj, String propertyName) {
      Object object = obj;
      for (String name : StringUtils.split(propertyName, ".")){
         String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);
         object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {});
      }
      return object;
   }

   /**
    * 调用Setter方法, 仅匹配方法名。
    * 支持多级,如:对象名.对象名.方法
    */
   public static void invokeSetter(Object obj, String propertyName, Object value) {
      Object object = obj;
      String[] names = StringUtils.split(propertyName, ".");
      for (int i=0; i<names.length; i++){
         if(i<names.length-1){
            String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]);
            object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {});
         }else{
            String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);
            invokeMethodByName(object, setterMethodName, new Object[] { value });
         }
      }
   }

   /**
    * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.
    */
   public static Object getFieldValue(final Object obj, final String fieldName) {
      Field field = getAccessibleField(obj, fieldName);

      if (field == null) {
         throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");
      }

      Object result = null;
      try {
         result = field.get(obj);
      } catch (IllegalAccessException e) {
         logger.error("不可能抛出的异常{}", e.getMessage());
      }
      return result;
   }

   /**
    * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.
    */
   public static void setFieldValue(final Object obj, final String fieldName, final Object value) {
      Field field = getAccessibleField(obj, fieldName);

      if (field == null) {
         throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");
      }

      try {
         field.set(obj, value);
      } catch (IllegalAccessException e) {
         logger.error("不可能抛出的异常:{}", e.getMessage());
      }
   }

   /**
    * 直接调用对象方法, 无视private/protected修饰符.
    * 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用.
    * 同时匹配方法名+参数类型,
    */
   public static Object invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,
         final Object[] args) {
      Method method = getAccessibleMethod(obj, methodName, parameterTypes);
      if (method == null) {
         throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");
      }

      try {
         return method.invoke(obj, args);
      } catch (Exception e) {
         throw convertReflectionExceptionToUnchecked(e);
      }
   }

   /**
    * 直接调用对象方法, 无视private/protected修饰符,
    * 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用.
    * 只匹配函数名,如果有多个同名函数调用第一个。
    */
   public static Object invokeMethodByName(final Object obj, final String methodName, final Object[] args) {
      Method method = getAccessibleMethodByName(obj, methodName);
      if (method == null) {
         throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");
      }

      try {
         return method.invoke(obj, args);
      } catch (Exception e) {
         throw convertReflectionExceptionToUnchecked(e);
      }
   }

   /**
    * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问.
    *
    * 如向上转型到Object仍无法找到, 返回null.
    */
   public static Field getAccessibleField(final Object obj, final String fieldName) {
      Validate.notNull(obj, "object can't be null");
      Validate.notBlank(fieldName, "fieldName can't be blank");
      for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
         try {
            Field field = superClass.getDeclaredField(fieldName);
            makeAccessible(field);
            return field;
         } catch (NoSuchFieldException e) {//NOSONAR
            // Field不在当前类定义,继续向上转型
            continue;// new add
         }
      }
      return null;
   }

   /**
    * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
    * 如向上转型到Object仍无法找到, 返回null.
    * 匹配函数名+参数类型。
    *
    * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
    */
   public static Method getAccessibleMethod(final Object obj, final String methodName,
         final Class<?>... parameterTypes) {
      Validate.notNull(obj, "object can't be null");
      Validate.notBlank(methodName, "methodName can't be blank");

      for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) {
         try {
            Method method = searchType.getDeclaredMethod(methodName, parameterTypes);
            makeAccessible(method);
            return method;
         } catch (NoSuchMethodException e) {
            // Method不在当前类定义,继续向上转型
            continue;// new add
         }
      }
      return null;
   }

   /**
    * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
    * 如向上转型到Object仍无法找到, 返回null.
    * 只匹配函数名。
    *
    * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
    */
   public static Method getAccessibleMethodByName(final Object obj, final String methodName) {
      Validate.notNull(obj, "object can't be null");
      Validate.notBlank(methodName, "methodName can't be blank");

      for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) {
         Method[] methods = searchType.getDeclaredMethods();
         for (Method method : methods) {
            if (method.getName().equals(methodName)) {
               makeAccessible(method);
               return method;
            }
         }
      }
      return null;
   }

   /**
    * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
    */
   public static void makeAccessible(Method method) {
      if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))
            && !method.isAccessible()) {
         method.setAccessible(true);
      }
   }

   /**
    * 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
    */
   public static void makeAccessible(Field field) {
      if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier
            .isFinal(field.getModifiers())) && !field.isAccessible()) {
         field.setAccessible(true);
      }
   }

   /**
    * 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处
    * 如无法找到, 返回Object.class.
    * eg.
    * public UserDao extends HibernateDao<User>
    *
    * @param clazz The class to introspect
    * @return the first generic declaration, or Object.class if cannot be determined
    */
   @SuppressWarnings("unchecked")
   public static <T> Class<T> getClassGenricType(final Class clazz) {
      return getClassGenricType(clazz, 0);
   }

   /**
    * 通过反射, 获得Class定义中声明的父类的泛型参数的类型.
    * 如无法找到, 返回Object.class.
    *
    * 如public UserDao extends HibernateDao<User,Long>
    *
    * @param clazz clazz The class to introspect
    * @param index the Index of the generic ddeclaration,start from 0.
    * @return the index generic declaration, or Object.class if cannot be determined
    */
   public static Class getClassGenricType(final Class clazz, final int index) {

      Type genType = clazz.getGenericSuperclass();

      if (!(genType instanceof ParameterizedType)) {
         logger.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");
         return Object.class;
      }

      Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

      if (index >= params.length || index < 0) {
         logger.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
               + params.length);
         return Object.class;
      }
      if (!(params[index] instanceof Class)) {
         logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
         return Object.class;
      }

      return (Class) params[index];
   }

   public static Class<?> getUserClass(Object instance) {
      Assert.notNull(instance, "Instance must not be null");
      Class clazz = instance.getClass();
      if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) {
         Class<?> superClass = clazz.getSuperclass();
         if (superClass != null && !Object.class.equals(superClass)) {
            return superClass;
         }
      }
      return clazz;

   }

   /**
    * 将反射时的checked exception转换为unchecked exception.
    */
   public static RuntimeException convertReflectionExceptionToUnchecked(Exception e) {
      if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException
            || e instanceof NoSuchMethodException) {
         return new IllegalArgumentException(e);
      } else if (e instanceof InvocationTargetException) {
         return new RuntimeException(((InvocationTargetException) e).getTargetException());
      } else if (e instanceof RuntimeException) {
         return (RuntimeException) e;
      }
      return new RuntimeException("Unexpected Checked Exception.", e);
   }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297

# 断言

返回顶部

# org.springframework.util.Assert

public static void state(boolean expression, String message) {
    if (!expression) {
        throw new IllegalStateException(message);
    }
}

public static void state(boolean expression, Supplier<String> messageSupplier) {
    if (!expression) {
        throw new IllegalStateException(nullSafeGet(messageSupplier));
    }
}

@Nullable
private static String nullSafeGet(@Nullable Supplier<String> messageSupplier) {
    return (messageSupplier != null ? messageSupplier.get() : null);
}

public static void isTrue(boolean expression, Supplier<String> messageSupplier) {
    if (!expression) {
        throw new IllegalArgumentException(nullSafeGet(messageSupplier));
    }
}

public static void isNull(@Nullable Object object, Supplier<String> messageSupplier) {
    if (object != null) {
        throw new IllegalArgumentException(nullSafeGet(messageSupplier));
    }
}

public static void notNull(@Nullable Object object, Supplier<String> messageSupplier) {
    if (object == null) {
        throw new IllegalArgumentException(nullSafeGet(messageSupplier));
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35