JDK环境变量配置及常用Java工具类指南

2026-06-28阅读 0热度 0
其他

一. JDK环境变量配置

1. 位置

配置JDK环境变量第一步:找到入口。在桌面右键点击“我的电脑”(或“此电脑”),选择“属性”,接着进入“高级系统设置”,最后点击“环境变量”按钮。

JDK环境变量配置, 以及一些常用Ja va工具类

2. 作用域

环境变量窗口里会看到两个区域:用户变量和系统变量。它们的作用域完全不同——用户变量只对当前登录用户生效,而系统变量则影响整个计算机上的所有用户。

3. 配置内容

接下来就是添加具体的变量了。需要添加以下三个变量,如果变量已经存在,直接在原有值的后面追加即可。注意每一项之间用英文分号隔开。

变量名变量值
JA VA_HOMED:Ja vajdk1.8;
PATH%JA VA_HOME%bin;
CLASSPATH%JA VA_HOME%libtools.jar;

二. Ja va后台获得客户端IP

获取客户端真实IP是个常见需求,尤其是在使用了反向袋里(比如Nginx)的情况下,简单的 request.getRemoteAddr() 就不够用了。这时候需要从请求头里一层层地找。直接看代码,逻辑很清晰:

import com.alibaba.druid.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ja vax.servlet.http.HttpServletRequest;

/**
 * 获取客户端IP地址
 */
public class IPUtils {
    private static Logger logger = LoggerFactory.getLogger(IPUtils.class);

    /**
     * 获取客户端IP地址
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = null;
        try {
            ip = request.getHeader("x-forwarded-for");
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        } catch (Exception e) {
            logger.error("IPUtils ERROR ", e);
        }
        return ip;
    }
}

三. 无参获取Request和Response

有时候在工具类或非Controller层需要拿到Request对象,但方法签名里没有传参。Spring提供了一个很好用的 RequestContextHolder,可以直接从当前线程绑定中获取。实现如下:

import ja vax.servlet.http.HttpServletRequest;
import ja vax.servlet.http.HttpServletResponse;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

public class HttpContextUtils {
    /**
     * 获取Request
     */
    public static HttpServletRequest getHttpServletRequest() {
        if(RequestContextHolder.getRequestAttributes()==null){
            return null;
        }
        return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
    }

    /**
     * 获取Response
     */
    public static HttpServletResponse getHttpServletResponse() {
        if(RequestContextHolder.getRequestAttributes()==null){
            return null;
        }
        return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();
    }
}

四. Ja va代码行数统计

想知道项目里写了多少行代码?这个小工具可以帮你统计Ja va文件的代码行数、注释行数和空白行数。需要注意的是,这个类需要放在 src/test/ja va 目录下才能正常工作。核心思路就是递归扫描目录,然后逐行分析。

import ja va.io.BufferedReader;
import ja va.io.File;
import ja va.io.FileNotFoundException;
import ja va.io.FileReader;
import ja va.io.IOException;
import ja va.util.ArrayList;

public class CodeCounter {
    static long files = 0;
    static long codeLines = 0;
    static long commentLines = 0;
    static long blankLines = 0;
    static ArrayList fileArray = new ArrayList();

    public static ArrayList getFile(File f) {
        File[] ff = f.listFiles();
        for (File child : ff) {
            if (child.isDirectory()) {
                getFile(child);
            } else
                fileArray.add(child);
        }
        return fileArray;
    }

    private static void count(File f) {
        BufferedReader br = null;
        boolean flag = false;
        try {
            br = new BufferedReader(new FileReader(f));
            String line = "";
            while ((line = br.readLine()) != null) {
                line = line.trim();
                if (line.matches("^[ ]*$")) {
                    blankLines++;
                } else if (line.startsWith("//")) {
                    commentLines++;
                } else if (line.startsWith("/*") && !line.endsWith("*/")) {
                    commentLines++;
                    flag = true;
                } else if (line.startsWith("/*") && line.endsWith("*/")) {
                    commentLines++;
                } else if (flag == true) {
                    commentLines++;
                    if (line.endsWith("*/")) {
                        flag = false;
                    }
                } else {
                    codeLines++;
                }
            }
            files++;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                    br = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        String file = CodeCounter.class.getResource("/").getFile();
        String path = file.replace("target/test-classes", "src");
        ArrayList al = getFile(new File(path));
        for (File f : al) {
            if (f.getName().matches(".*.ja va$")){
                count(f);
                System.out.println(f);
            }
        }
        System.out.println("统计文件:" + files);
        System.out.println("代码行数:" + codeLines);
        System.out.println("注释行数:" + commentLines);
        System.out.println("空白行数:" + blankLines);
    }
}

五. 判断设备类型(PC, 手机等), 浏览器类型(IE, Google等)

在Web开发中经常需要根据用户设备返回不同的页面,比如手机端和PC端分别渲染。推荐一个成熟的第三方库 UserAgentUtils,它能从User-Agent中解析出操作系统、浏览器和设备类型。先引入依赖:

1. Ma ven导包如下


    eu.bitwalker
    UserAgentUtils
    1.21

2. 工具类如下

import ja vax.servlet.http.HttpServletRequest;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.DeviceType;
import eu.bitwalker.useragentutils.UserAgent;

public class UserAgentUtils {
    public static UserAgent getUserAgent(HttpServletRequest request) {
        return UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
    }

    public static DeviceType getDeviceType(HttpServletRequest request) {
        return getUserAgent(request).getOperatingSystem().getDeviceType();
    }

    public static boolean isComputer(HttpServletRequest request) {
        return DeviceType.COMPUTER.equals(getDeviceType(request));
    }

    public static boolean isMobile(HttpServletRequest request) {
        return DeviceType.MOBILE.equals(getDeviceType(request));
    }

    public static boolean isTablet(HttpServletRequest request) {
        return DeviceType.TABLET.equals(getDeviceType(request));
    }

    public static boolean isMobileOrTablet(HttpServletRequest request){
        DeviceType deviceType = getDeviceType(request);
        return DeviceType.MOBILE.equals(deviceType) || DeviceType.TABLET.equals(deviceType);
    }

    public static Browser getBrowser(HttpServletRequest request) {
        return getUserAgent(request).getBrowser();
    }

    public static boolean isLteIE8(HttpServletRequest request) {
        Browser browser = getBrowser(request);
        return Browser.IE5.equals(browser) || Browser.IE6.equals(browser) || Browser.IE7.equals(browser)
                || Browser.IE8.equals(browser);
    }
}

3. 进行拦截并根据需要进行处理

有了判断工具,下一步就是在Spring的拦截器里根据设备类型切换视图。比如手机或平板访问时,自动加上 mobile/ 前缀:

import ja vax.servlet.http.HttpServletRequest;
import ja vax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.apache.commons.lang3.StringUtils;

public class MobileInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        if (modelAndView != null) {
            if (UserAgentUtils.isMobileOrTablet(request)
                    && !StringUtils.startsWithIgnoreCase(modelAndView.getViewName(), "redirect:")) {
                modelAndView.setViewName("mobile/" + modelAndView.getViewName());
            }
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
    }
}

六. 根据日期生成目录

上传文件时,为了避免文件名重复,通常会用日期加时间戳来生成存储路径。下面这个工具类生成形如 2018/07/26/1532572300220 的路径:

import ja va.text.SimpleDateFormat;
import ja va.util.Date;

public class DirectoryUtils {
    public static String getDir() {
        StringBuilder sb = new StringBuilder("");
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
        String path = format.format(date);
        long time = new Date().getTime();
        sb.append(path).append("/").append(time);
        return sb.toString();
    }
}

七. 根据附件名获得附件类型

当我们需要根据文件名后缀返回对应的类型(比如图片、文档、视频)时,可以借助 commons-ioFilenameUtils 来快速获取扩展名,然后做映射。

1. Ma ven导包


    commons-io
    commons-io
    2.6

2. 工具类

import org.apache.commons.io.FilenameUtils;

public class FileTypeUtils {
    public static String getFileType(String fileName) {
        if (fileName != null && !"".equals(fileName)) {
            String extension = FilenameUtils.getExtension(fileName);
            if ("jng".equalsIgnoreCase(extension) || "jpg".equalsIgnoreCase(extension)
                    || "png".equalsIgnoreCase(extension) || "gif".equalsIgnoreCase(extension)
                    || "jpeg".equalsIgnoreCase(extension) || "bmp".equalsIgnoreCase(extension)) {
                return "IMG";
            } else if ("txt".equalsIgnoreCase(extension)) {
                return "TXT";
            } else if ("doc".equalsIgnoreCase(extension) || "docx".equalsIgnoreCase(extension)) {
                return "DOC";
            } else if ("pdf".equalsIgnoreCase(extension)) {
                return "PDF";
            } else if ("xls".equalsIgnoreCase(extension) || "xlsx".equalsIgnoreCase(extension)) {
                return "XLS";
            } else if ("ppt".equalsIgnoreCase(extension) || "pptx".equalsIgnoreCase(extension)) {
                return "PPT";
            } else if ("zip".equalsIgnoreCase(extension)) {
                return "ZIP";
            } else if ("mp3".equalsIgnoreCase(extension)) {
                return "MP3";
            } else if ("mp4".equalsIgnoreCase(extension) || "flv".equalsIgnoreCase(extension)
                    || "a vi".equalsIgnoreCase(extension)) {
                return "A VI";
            } else if ("HTML".equalsIgnoreCase(extension)) {
                return "HTM";
            } else if ("VSD".equalsIgnoreCase(extension)) {
                return "VSD";
            } else {
                return "OTHER";
            }
        }
        return "";
    }
}

八. 附件上传下载

文件上传下载是每个Web项目几乎都会遇到的功能。下面这个工具类整合了上传和下载两个方法,上传时通过 System.getProperty("webPath") 获取部署根目录(需要在web.xml中配置),下载时支持中文文件名编码。

1. web.xml中需要加入如下代码


    webAppRootKey
    webPath

2. Ja va代码如下

import ja va.io.File;
import ja va.io.FileInputStream;
import ja va.io.IOException;
import ja va.io.InputStream;
import ja va.io.OutputStream;
import ja va.io.UnsupportedEncodingException;
import ja va.net.URLEncoder;
import ja vax.servlet.http.HttpServletRequest;
import ja vax.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;

public class FileUtils {
    public static String fileUpload(MultipartFile file, String subPath) {
        String basePath = System.getProperty("webPath");
        String path = basePath.replaceAll("\\\\", "/") + subPath;
        String finalPath = path + "/" + file.getOriginalFilename();
        File dir = new File(path);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        try {
            file.transferTo(new File(finalPath));
        } catch (IOException e) {
            System.out.println("文件: " + file.getOriginalFilename() + "上传失败!");
            e.printStackTrace();
        }
        return finalPath;
    }

    public static boolean excelOutTemplate(HttpServletRequest request, HttpServletResponse response,
            String filePath, String fileShowName) {
        String localPath = request.getServletContext().getRealPath("/");
        String finalPath = localPath.endsWith("/") ? (localPath + filePath) : (localPath + "/" + filePath);
        File file = new File(finalPath);
        if (file.exists()) {
            try {
                response.addHeader("Content-Disposition",
                        "attachment;filename=" + URLEncoder.encode(fileShowName, "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            InputStream in = null;
            OutputStream out = null;
            try {
                in = new FileInputStream(finalPath);
                out = response.getOutputStream();
                int b;
                while ((b = in.read()) != -1)
                    out.write(b);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (in != null)
                        in.close();
                    if (out != null)
                        out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } else {
            System.out.println("服务器文件已经不存在了!");
            return false;
        }
        return true;
    }
}

九. 获得UUID

生成唯一标识符最简单的方式就是UUID,去掉横线之后变成32位字符串,很多场景下用来做主键或文件名前缀。

import ja va.util.UUID;

public class IDUtils {
    public static String getId() {
        String id = UUID.randomUUID().toString();
        id = id.replace("-", "");
        return id;
    }
}

十. 自定义异常类

为了让业务异常和系统异常区分开,通常会定义一个自定义运行时异常。这里封装了 msgcode 两个字段,方便在全局异常处理器中统一返回。

public class RRException extends RuntimeException {
    private static final long serialVersionUID = 1L;
    private String msg;
    private int code = 500;

    public RRException(String msg) {
        super(msg);
        this.msg = msg;
    }

    public RRException(String msg, Throwable e) {
        super(msg, e);
        this.msg = msg;
    }

    public RRException(String msg, int code) {
        super(msg);
        this.msg = msg;
        this.code = code;
    }

    public RRException(String msg, int code, Throwable e) {
        super(msg, e);
        this.msg = msg;
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }
}

十一. 字符串首字母大写

有时候需要把字段名从驼峰转成首字母大写,比如生成getter/setter时。下面这个实现通过字符数组偏移量直接操作,效率很高。

public class StringUtils {
    public static String captureName(String name) {
        char[] cs=name.toCharArray();
        cs[0]-=32;
        return String.valueOf(cs);
    }
}

十二. List乱序与按照汉字拼音排序

做抽奖或随机展示时经常需要打乱List顺序,而汉字拼音排序则适用于按名字首字母分组等场景。注意拼音排序依赖 CollatorLocale.CHINA 参数。

import ja va.text.Collator;
import ja va.util.ArrayList;
import ja va.util.Collections;
import ja va.util.Comparator;
import ja va.util.List;
import ja va.util.Random;

public class ListUtils {
    public static  List randomList(List sourceList) {
        if (sourceList == null || sourceList.size() == 0) {
            return sourceList;
        }
        List random = new ArrayList(sourceList.size());
        do {
            int index = Math.abs(new Random().nextInt(sourceList.size()));
            random.add(sourceList.remove(index));
        } while (sourceList.size() > 0);
        return random;
    }

    public static  List sortList(List sourceList) {
        if (sourceList == null || sourceList.size() == 0) {
            return sourceList;
        }
        List sort = new ArrayList(sourceList.size());
        sort.addAll(sourceList);
        Collections.sort(sort, new Comparator(){
            @Override
            public int compare(V v0, V v1) {
                List list = new ArrayList(2);
                list.add(v0.toString());
                list.add(v1.toString());
                Collections.sort(list, Collator.getInstance(ja va.util.Locale.CHINA));
                return list.indexOf(v0.toString()) == 0 ? -1 : 1;
            }
        });
        return sort;
    }
}

十三. Redis工具类

基于Spring Data Redis封装了一个通用的缓存操作工具,支持String、List、Set、Map等常用数据结构,同时封装了删除方法。使用时需要先配置好Redis连接。

1. properties配置文件

# redis 配置文件
redis.hostName=127.0.0.1
redis.port=6379
redis.timeout=36000
redis.usePool=true 
redis.maxIdle=6
redis.minEvictableIdleTimeMillis=300000
redis.numTestsPerEvictionRun=3
redis.timeBetweenEvictionRunsMillis=60000

2. Spring添加配置文件



    
    
    
    



    
    
    
    
    



    
    
        
    
    
        
    

3. Ma ven依赖


    org.springframework.data
    spring-data-redis
    1.6.2.RELEASE


    redis.clients
    jedis
    2.9.0

4. Redis工具类

import ja va.util.Iterator;
import ja va.util.List;
import ja va.util.Map;
import ja va.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.BoundListOperations;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Service
public class RedisCacheUtil {
    @Autowired
    @Qualifier("jedisTemplate")
    public RedisTemplate redisTemplate;

    public  void setCacheObject(K key, V value) {
        redisTemplate.boundValueOps(key).set(value);
    }

    @SuppressWarnings("unchecked")
    public  V getCacheObject(K key) {
        return (V) redisTemplate.boundValueOps(key).get();
    }

    public  void setCacheList(K key, List dataList) {
        redisTemplate.delete(key);
        for (V v : dataList) {
            redisTemplate.boundListOps(key).rightPush(v);
        }
    }

    @SuppressWarnings("unchecked")
    public  List getCacheList(K key) {
        BoundListOperations listOperation = (BoundListOperations) redisTemplate.boundListOps(key);
        return listOperation.range(0, listOperation.size());
    }

    @SuppressWarnings("unchecked")
    public  void setCacheSet(K key, Set dataSet) {
        redisTemplate.delete(key);
        BoundSetOperations setOperation = (BoundSetOperations) redisTemplate.boundSetOps(key);
        Iterator it = dataSet.iterator();
        while (it.hasNext()) {
            setOperation.add(it.next());
        }
    }

    @SuppressWarnings("unchecked")
    public  Set getCacheSet(K key) {
        return (Set) redisTemplate.boundSetOps(key).members();
    }

    public  void setCacheMap(K key, Map dataMap) {
        redisTemplate.delete(key);
        redisTemplate.boundHashOps(key).putAll(dataMap);
    }

    @SuppressWarnings("unchecked")
    public  Map getCacheMap(K key) {
        return (Map) redisTemplate.boundHashOps(key).entries();
    }

    public  void deleteByKey(K key) {
        redisTemplate.delete(redisTemplate.keys(key));
    }
}

十四. 判断是否是中文

有时候需要检查字符串是否包含中文字符,可以通过Unicode编码范围来判断。下面这个工具类支持中文汉字和中文符号。

public class CharUtils {
    public static boolean isChinese(String strName) {
        char[] ch = strName.toCharArray();
        for (int i = 0; i < ch.length; i++) {
            char c = ch[i];
            if (isChinese(c)) {
                return true;
            }
        }
        return false;
    }

    private static boolean isChinese(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
                || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
            return true;
        }
        return false;
    }
}

十五. 异常拦截处理

全局异常处理器是Spring MVC中非常重要的一环。这里实现了 HandlerExceptionResolver 接口,针对自定义异常、数据库主键重复、Shiro权限不足等分别返回不同的JSON信息,同时记录日志。

import ja vax.servlet.http.HttpServletRequest;
import ja vax.servlet.http.HttpServletResponse;
import org.apache.shiro.authz.AuthorizationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;

@Component
public class RRExceptionHandler implements HandlerExceptionResolver {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public ModelAndView resolveException(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex) {
        R r = new R();
        try {
            response.setContentType("application/json;charset=utf-8");
            response.setCharacterEncoding("utf-8");
            if (ex instanceof RRException) {
                r.put("code", ((RRException) ex).getCode());
                r.put("msg", ((RRException) ex).getMessage());
                r.put("tip", ((RRException) ex).getMessage());
            }
            else if(ex instanceof DuplicateKeyException){
                r = R.error("数据库中已存在该记录");
            }
            else if(ex instanceof AuthorizationException){
                r = R.error("没有权限,请联系管理员授权").put("tip", "没有权限,请联系管理员授权").put("content", null);
            }
            else{
                r = R.error();
            }
            logger.error(ex.getMessage(), ex);
            String json = JSON.toJSONString(r);
            response.getWriter().print(json);
        } catch (Exception e) {
            logger.error("RRExceptionHandler 异常处理失败", e);
            e.printStackTrace();
        }
        return new ModelAndView();
    }
}

十六. Cookie工具类

Cookie操作虽然简单,但涉及到编码、域名、路径等细节。这个工具类提供了获取、设置、删除Cookie的方法,支持编码和解码,同时考虑了多级域名的情况。

import ja va.io.UnsupportedEncodingException;
import ja va.net.URLDecoder;
import ja va.net.URLEncoder;
import ja vax.servlet.http.Cookie;
import ja vax.servlet.http.HttpServletRequest;
import ja vax.servlet.http.HttpServletResponse;

public class CookieUtils {
     public static String getCookieValue(HttpServletRequest request, String cookieName) {
        return getCookieValue(request, cookieName, false);
    }

    public static String getCookieValue(HttpServletRequest request, String cookieName, boolean isDecoder) {
        Cookie[] cookieList = request.getCookies();
        if (cookieList == null || cookieName == null) {
            return null;
        }
        String retValue = null;
        try {
            for (int i = 0; i < cookieList.length; i++) {
                if (cookieList[i].getName().equals(cookieName)) {
                    if (isDecoder) {
                        retValue = URLDecoder.decode(cookieList[i].getValue(), "UTF-8");
                    } else {
                        retValue = cookieList[i].getValue();
                    }
                    break;
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return retValue;
    }

    public static String getCookieValue(HttpServletRequest request, String cookieName, String encodeString) {
        Cookie[] cookieList = request.getCookies();
        if (cookieList == null || cookieName == null) {
            return null;
        }
        String retValue = null;
        try {
            for (int i = 0; i < cookieList.length; i++) {
                if (cookieList[i].getName().equals(cookieName)) {
                    retValue = URLDecoder.decode(cookieList[i].getValue(), encodeString);
                    break;
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return retValue;
    }

    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue) {
        setCookie(request, response, cookieName, cookieValue, -1);
    }

    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, int cookieMaxage) {
        setCookie(request, response, cookieName, cookieValue, cookieMaxage, false);
    }

    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, boolean isEncode) {
        setCookie(request, response, cookieName, cookieValue, -1, isEncode);
    }

    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, int cookieMaxage, boolean isEncode) {
        doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, isEncode);
    }

    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, int cookieMaxage, String encodeString) {
        doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, encodeString);
    }

    public static void deleteCookie(HttpServletRequest request, HttpServletResponse response,
            String cookieName) {
        doSetCookie(request, response, cookieName, "", -1, false);
    }

    private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
            String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) {
        try {
            if (cookieValue == null) {
                cookieValue = "";
            } else if (isEncode) {
                cookieValue = URLEncoder.encode(cookieValue, "utf-8");
            }
            Cookie cookie = new Cookie(cookieName, cookieValue);
            if (cookieMaxage > 0)
                cookie.setMaxAge(cookieMaxage);
            if (null != request) {
                String domainName = getDomainName(request);
                System.out.println(domainName);
                if (!"localhost".equals(domainName)) {
                }
            }
            cookie.setPath("/");
            response.addCookie(cookie);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
            String cookieName, String cookieValue, int cookieMaxage, String encodeString) {
        try {
            if (cookieValue == null) {
                cookieValue = "";
            } else {
                cookieValue = URLEncoder.encode(cookieValue, encodeString);
            }
            Cookie cookie = new Cookie(cookieName, cookieValue);
            if (cookieMaxage > 0)
                cookie.setMaxAge(cookieMaxage);
            if (null != request) {
                String domainName = getDomainName(request);
                System.out.println(domainName);
                if (!"localhost".equals(domainName)) {
                }
            }
            cookie.setPath("/");
            response.addCookie(cookie);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static final String getDomainName(HttpServletRequest request) {
        String domainName = null;
        String serverName = request.getRequestURL().toString();
        if (serverName == null || serverName.equals("")) {
            domainName = "";
        } else {
            final int end = serverName.lastIndexOf("/");
            serverName = serverName.substring(0, end);
            final String[] domains = serverName.split("\\.");
            int len = domains.length;
            if (len > 3) {
                domainName = "." + domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1];
            } else if (len <= 3 && len > 1) {
                domainName = "." + domains[len - 2] + "." + domains[len - 1];
            } else {
                domainName = serverName;
            }
        }
        if (domainName != null && domainName.indexOf(":") > 0) {
            String[] ary = domainName.split(":");
            domainName = ary[0];
        }
        return domainName;
    }
}

十七. 日期处理

日期格式化、获取某月的所有日期、判断是否同一天、计算相差天数——这些是日常开发中很常见的需求。下面这个工具类封装了这些方法,可以直接使用。

import ja va.text.SimpleDateFormat;
import ja va.util.ArrayList;
import ja va.util.Calendar;
import ja va.util.Date;
import ja va.util.List;

public class DateUtils {
    public final static String DATE_PATTERN = "yyyy-MM-dd";
    public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

    public static String format(Date date) {
        return format(date, DATE_PATTERN);
    }

    public static String format(Date date, String pattern) {
        if (date != null) {
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            return df.format(date);
        }
        return null;
    }

    public static List getAllDatesOfMonth(Date date) {
        List list = new ArrayList();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DATE, 1);
        int month = cal.get(Calendar.MONTH);
        while (cal.get(Calendar.MONTH) == month) {
            list.add(cal.getTime());
            cal.add(Calendar.DATE, 1);
        }
        return list;
    }

    public static boolean isSameDate(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        boolean isSameYear = cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR);
        boolean isSameMonth = isSameYear && cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH);
        boolean isSameDate = isSameMonth && cal1.get(Calendar.DAY_OF_MONTH) == cal2.get(Calendar.DAY_OF_MONTH);
        return isSameDate;
    }

    public static int getDateSpace(Date date1, Date date2) {
        Calendar calst = Calendar.getInstance();
        Calendar caled = Calendar.getInstance();
        calst.setTime(date1);
        caled.setTime(date2);
        calst.set(Calendar.HOUR_OF_DAY, 0);
        calst.set(Calendar.MINUTE, 0);
        calst.set(Calendar.SECOND, 0);
        caled.set(Calendar.HOUR_OF_DAY, 0);
        caled.set(Calendar.MINUTE, 0);
        caled.set(Calendar.SECOND, 0);
        return ((int) (caled.getTime().getTime() / 1000) - (int) (calst.getTime().getTime() / 1000)) / 3600 / 24;
    }
}

十八. HttpClient工具类(通过Ja va后台进行Http访问)

Ja va后端经常需要调用其他系统的HTTP接口,Apache HttpClient 是经典选择。这里封装了GET、POST请求(支持参数)、文件上传、文件下载以及SSL连接(支持证书导入和信任所有证书两种方式)。

1. Ma ven导包


    org.apache.httpcomponents
    httpclient
    4.3.1


    org.apache.httpcomponents
    httpcore
    4.3.1


    org.apache.httpcomponents
    httpmime
    4.3.1

2. Ja va代码

import ja va.io.File;
import ja va.io.FileInputStream;
import ja va.io.FileOutputStream;
import ja va.io.IOException;
import ja va.io.InputStream;
import ja va.io.UnsupportedEncodingException;
import ja va.security.KeyManagementException;
import ja va.security.KeyStore;
import ja va.security.KeyStoreException;
import ja va.security.NoSuchAlgorithmException;
import ja va.security.cert.CertificateException;
import ja va.security.cert.X509Certificate;
import ja va.util.ArrayList;
import ja va.util.HashMap;
import ja va.util.List;
import ja va.util.Map;
import ja va.util.Set;
import ja vax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.CharsetUtils;
import org.apache.http.util.EntityUtils;

public class HttpClientUtils {
    private static final int SUCCESS = 200;

    public static void ssl(String url) {
        CloseableHttpClient httpclient = null;
        try {
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            FileInputStream instream = new FileInputStream(new File("E:tomcat.keystore"));
            try {
                trustStore.load(instream, "123456".toCharArray());
            } catch (CertificateException e) {
                e.printStackTrace();
            } finally {
                try {
                    instream.close();
                } catch (Exception ignore) {
                }
            }
            SSLContext sslcontext = SSLContexts.custom()
                    .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy())
                    .build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                    sslcontext, new String[] { "TLSv1" }, null,
                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
            httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
            HttpGet httpget = new HttpGet(url);
            System.out.println("executing request" + httpget.getRequestLine());
            CloseableHttpResponse response = httpclient.execute(httpget);
            try {
                HttpEntity entity = response.getEntity();
                System.out.println("----------------------------------------");
                System.out.println(response.getStatusLine());
                if (entity != null) {
                    System.out.println("Response content length: " + entity.getContentLength());
                    System.out.println(EntityUtils.toString(entity));
                    EntityUtils.consume(entity);
                }
            } finally {
                response.close();
            }
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } finally {
            if (httpclient != null) {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static CloseableHttpClient createSSLClientDefault() {
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        return HttpClients.createDefault();
    }

    public static void ssl2(String url) {
        CloseableHttpClient httpclient = null;
        try {
            httpclient = createSSLClientDefault();
            HttpGet httpget = new HttpGet(url);
            System.out.println("executing request" + httpget.getRequestLine());
            CloseableHttpResponse response = httpclient.execute(httpget);
            try {
                HttpEntity entity = response.getEntity();
                System.out.println("----------------------------------------");
                System.out.println(response.getStatusLine());
                if (entity != null) {
                    System.out.println("Response content length: " + entity.getContentLength());
                    System.out.println(EntityUtils.toString(entity));
                    EntityUtils.consume(entity);
                }
            } finally {
                response.close();
            }
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (httpclient != null) {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static void closeClientAndResponse(CloseableHttpClient client, CloseableHttpResponse response) {
        try {
            if (response != null) {
                response.close();
            }
            if (client != null) {
                client.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static Map doGet(String url, Map params) {
        Map result = new HashMap<>(2);
        result.put("code", "200");
        CloseableHttpClient client = null;
        CloseableHttpResponse response = null;
        try {
            client = HttpClients.createDefault();
            URIBuilder uri = new URIBuilder(url);
            if (params != null) {
                Set> entries = params.entrySet();
                for (Map.Entry entry : entries) {
                    uri.addParameter(entry.getKey(), entry.getValue());
                }
            }
            HttpGet hg = new HttpGet(uri.build());
            hg.setHeader(new BasicHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"));
            hg.setHeader(new BasicHeader("Accept", "application/json;charset=utf-8"));
            response = client.execute(hg);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == SUCCESS) {
                String resStr = EntityUtils.toString(response.getEntity(), "utf-8");
                result.put("data", resStr);
            } else {
                result.put("code", statusCode + "");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeClientAndResponse(client, response);
        }
        return result;
    }

    public static Map doPost(String url, Map params){
        Map result = new HashMap<>(2);
        result.put("code", "200");
        CloseableHttpClient client = null;
        CloseableHttpResponse response = null;
        try {
            client = HttpClients.createDefault();
            HttpPost post = new HttpPost(url);
            List formList = new ArrayList<>();
            if (params != null) {
                Set> entries = params.entrySet();
                for (Map.Entry entry : entries) {
                    formList.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                }
            }
            StringEntity entity = new UrlEncodedFormEntity(formList, "utf-8");
            post.setEntity(entity);
            post.setHeader(new BasicHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"));
            post.setHeader(new BasicHeader("Accept", "application/json;charset=utf-8"));
            response = client.execute(post);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == SUCCESS) {
                String resStr = EntityUtils.toString(response.getEntity(), "utf-8");
                result.put("data", resStr);
            } else {
                result.put("code", statusCode + "");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            closeClientAndResponse(client, response);
        }
        return result;
    }

    public static void upload(String url) {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpPost httppost = new HttpPost(url);
            FileBody bin = new FileBody(new File("C:UserszhangwenchaoDesktopjinzhongzi.jpg"));
            HttpEntity reqEntity = MultipartEntityBuilder.create()
                    .setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
                    .addPart("uploadFile", bin)
                    .setCharset(CharsetUtils.get("UTF-8"))
                    .build();
            httppost.setEntity(reqEntity);
            System.out.println("executing request: " + httppost.getRequestLine());
            CloseableHttpResponse response = httpclient.execute(httppost);
            try {
                System.out.println("----------------------------------------");
                System.out.println(response.getStatusLine());
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    System.out.println("Response content length: " + resEntity.getContentLength());
                    System.out.println("Response content: " + EntityUtils.toString(resEntity));
                }
                EntityUtils.consume(resEntity);
            } finally {
                response.close();
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void download(String url) {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpGet httpget = new HttpGet(url);
            CloseableHttpResponse response = httpclient.execute(httpget);
            HttpEntity resEntity = response.getEntity();
            if (resEntity != null) {
                System.out.println("Response content length: " + resEntity.getContentLength());
                InputStream in = resEntity.getContent();
                String fileName = url.substring(url.lastIndexOf("/"));
                File file = new File("E:" + fileName);
                try {
                    FileOutputStream fout = new FileOutputStream(file);
                    int l = -1;
                    byte[] tmp = new byte[1024];
                    while ((l = in.read(tmp)) != -1) {
                        fout.write(tmp, 0, l);
                    }
                    fout.flush();
                    fout.close();
                } finally {
                    in.close();
                }
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

十九. 分页工具类

分页是后台系统的标配。这个 PageUtils 封装了总记录数、每页大小、总页数、当前页和分页数据,使用起来很直观。

import ja va.io.Serializable;
import ja va.util.List;

public class PageUtils implements Serializable {
    private static final long serialVersionUID = 1L;
    private int totalCount;
    private int pageSize;
    private int totalPage;
    private int currPage;
    private List list;

    public PageUtils(List list, int totalCount, int pageSize, int currPage) {
        this.list = list;
        this.totalCount = totalCount;
        this.pageSize = pageSize;
        this.currPage = currPage;
        this.totalPage = (int)Math.ceil((double)totalCount/pageSize);
    }

    // getters and setters omitted for brevity
}

二十. SQL查询工具类

在MyBatis中动态拼SQL时,排序字段容易产生SQL注入风险。下面这个工具类包含SQL过滤和查询参数封装,避免直接拼接。

1. SQL过滤

import org.apache.commons.lang.StringUtils;

public class SQLFilter {
    public static String sqlInject(String str){
        if(StringUtils.isBlank(str)){
            return str;
        }
        str = StringUtils.replace(str, "'", "");
        str = StringUtils.replace(str, "\"", "");
        str = StringUtils.replace(str, ";", "");
        str = StringUtils.replace(str, "\\", "");
        str = str.toLowerCase();
        String[] keywords = {"master", "truncate", "insert", "select", "delete", "update", "declare", "alert", "drop"};
        for(String keyword : keywords){
            if(str.contains(keyword)){
                throw new RuntimeException("包含非法字符");
            }
        }
        return str;
    }
}

2. SQL查询

import ja va.util.LinkedHashMap;
import ja va.util.Map;

public class Q extends LinkedHashMap {
    private static final long serialVersionUID = 1L;
    private int page;
    private int limit;

    public Q(Map params){
        this.putAll(params);
        String sidx = "";
        String order = "";
        if(params.get("page")!=null) {
            this.page = Integer.parseInt(params.get("page").toString());
        }
        if(params.get("limit")!=null) {
            this.limit = Integer.parseInt(params.get("limit").toString());
        }
        if(params.get("sidx")!=null) {
            sidx = params.get("sidx").toString();
        }
        if(params.get("order")!=null) {
            order = params.get("order").toString();
        }
        this.put("offset", (page - 1) * limit);
        this.put("page", page);
        this.put("limit", limit);
        if(params.get("limit")==null) {
            this.put("limit", null);
        }
        this.put("sidx", SQLFilter.sqlInject(sidx));
        this.put("order", SQLFilter.sqlInject(order));
    }

    public Q() {
        this.put("page", page);
        this.put("limit", null);
        this.put("sidx", "");
        this.put("order", "");
    }

    // getters and setters omitted
}

3. mapper文件中查询列表可以这么写

二十一. Shiro工具类

Apache Shiro 是Ja va常见的权限框架。下面这个工具类封装了获取Session、Subject、当前用户信息、验证码等常见操作。

1. Ma ven导包


    org.apache.shiro
    shiro-core
    1.3.2


    org.apache.shiro
    shiro-spring
    1.3.2


    org.apache.shiro
    shiro-ehcache
    1.3.2

2. 工具类

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;

public class ShiroUtils {
    public static Session getSession() {
        return SecurityUtils.getSubject().getSession();
    }

    public static Subject getSubject() {
        return SecurityUtils.getSubject();
    }

    public static SysUserEntity getUserEntity() {
        return (SysUserEntity)SecurityUtils.getSubject().getPrincipal();
    }

    public static Long getUserId() {
        return getUserEntity().getUserId();
    }

    public static void setSessionAttribute(Object key, Object value) {
        getSession().setAttribute(key, value);
    }

    public static Object getSessionAttribute(Object key) {
        return getSession().getAttribute(key);
    }

    public static boolean isLogin() {
        return SecurityUtils.getSubject().getPrincipal() != null;
    }

    public static void logout() {
        SecurityUtils.getSubject().logout();
    }

    public static String getKaptcha(String key) {
        String kaptcha = getSessionAttribute(key).toString();
        getSession().removeAttribute(key);
        return kaptcha;
    }
}

二十二. SpringContext工具类

有时候我们需要在非Spring管理的类中获取Bean,实现 ApplicationContextAware 接口是最常用的方式。工具类如下:

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringContextUtils implements ApplicationContextAware {
    public static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        SpringContextUtils.applicationContext = applicationContext;
    }

    public static Object getBean(String name) {
        return applicationContext.getBean(name);
    }

    public static  T getBean(String name, Class requiredType) {
        return applicationContext.getBean(name, requiredType);
    }

    public static boolean containsBean(String name) {
        return applicationContext.containsBean(name);
    }

    public static boolean isSingleton(String name) {
        return applicationContext.isSingleton(name);
    }

    public static Class getType(String name) {
        return applicationContext.getType(name);
    }
}

二十三. Properties载入工具类

读取properties配置文件时,这个工具类可以指定多个文件,并支持UTF-8编码,避免中文乱码。

1. 工具类如下

import ja va.io.IOException;
import ja va.io.InputStreamReader;
import ja va.util.Properties;

public class PropertiesLoader {
    private final Properties properties;

    public PropertiesLoader(String... resourcePaths) {
        properties = loadProperties(resourcePaths);
    }

    private Properties loadProperties(String[] resourcePaths) {
        Properties props = new Properties();
        for (String location : resourcePaths) {
            InputStreamReader is = null;
            try {
                is = new InputStreamReader(
                        PropertiesLoader.class.getClassLoader().getResourceAsStream(location), "UTF-8");
                props.load(is);
            } catch (Exception e) {
            } finally {
                try {
                    is.close();
                } catch (IOException e) {
                }
            }
        }
        return props;
    }

    public String getConfig(String key) {
        if (properties.containsKey(key)) {
            return properties.getProperty(key);
        }
        return "";
    }

    public int getIntConfig(String key) {
        return Integer.parseInt(getConfig(key));
    }
}

2. 使用

public static PropertiesLoader loader = new PropertiesLoader("config/config.properties");
public void test() {
    String content = loader.getConfig("content");
}

二十四. Ja va执行Bat命令(或其他命令)

有时候需要从Ja va调用外部脚本(比如批处理)。下面这个工具类通过 ProcessBuilder 执行bat文件,并通过判断输出中的特定标记来确认执行结果。

import ja va.io.BufferedReader;
import ja va.io.IOException;
import ja va.io.InputStreamReader;
import ja va.nio.charset.StandardCharsets;

public class BatUtils {
    public static boolean doBat(String batPath, String... args) {
        boolean result = false;
        String[] command;
        if (args == null || args.length == 0) {
            command = new String[]{batPath};
        } else {
            command = new String[args.length + 1];
            command[0] = batPath;
            System.arraycopy(args, 0, command, 1, args.length);
        }
        ProcessBuilder processBuilder = new ProcessBuilder(command);
        processBuilder.redirectErrorStream(true);
        try {
            Process process = processBuilder.start();
            BufferedReader bufferedReader = new BufferedReader(
                    new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                System.out.println(line);
                if (line.contains("Bat Finished! ")) {
                    line = bufferedReader.readLine();
                    System.out.println(line);
                    if (line.contains("Bat Success! ")) {
                        result = true;
                    } else if (line.contains("Bat Fail! ")){
                        // result remains false
                    }
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }
}

二十五. 不使用Request获得Web项目的全路径

在非Web环境下(比如工具类中)获取class文件的绝对路径,可以用 getResource("").getFile()。注意返回的路径前后都带有斜杠。

String path = Test.class.getResource("").getFile();

假如Test.class类文件在blog项目的 com/paulandcode/utils 目录下,则上面的path值为:

/D:/Tomcat/webapps/blog/WEB-INF/classes/com/paulandcode/utils/

二十六. 下划线与驼峰相互转换

数据库字段通常采用下划线命名(如 user_name),而Ja va实体类则使用驼峰(如 userName)。这个工具类支持数组和Map的键转换。

import ja va.util.HashMap;
import ja va.util.Map;

public class HumpUtils {
    private static final char UNDERLINE = '_';

    public static String[] arrUnderlineToHump(String[] arr) {
        if (arr == null) return null;
        String[] newArr = new String[arr.length];
        for (int i = 0; i < arr.length; i++) {
            newArr[i] = toHump(arr[i]);
        }
        return newArr;
    }

    public static String[] arrHumpToUnderline(String[] arr) {
        if (arr == null) return null;
        String[] newArr = new String[arr.length];
        for (int i = 0; i < arr.length; i++) {
            newArr[i] = toUnderline(arr[i]);
        }
        return newArr;
    }

    public static  Map mapKeyUnderlineToHump(Map map) {
        if (map == null) return null;
        Map newMap = new HashMap<>(map.size());
        for (Map.Entry entry : map.entrySet()) {
            newMap.put(toHump(entry.getKey()), entry.getValue());
        }
        return newMap;
    }

    public static  Map mapKeyHumpToUnderline(Map map) {
        if (map == null) return null;
        Map newMap = new HashMap<>(map.size());
        for (Map.Entry entry : map.entrySet()) {
            newMap.put(toUnderline(entry.getKey()), entry.getValue());
        }
        return newMap;
    }

    public static String toHump(String colName) {
        if (colName == null) return null;
        StringBuilder sb = new    
免责声明

本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。

相关阅读

更多
欢迎回来 登录或注册后,可保存提示词和历史记录
登录后可同步收藏、历史记录和常用模板
注册即表示同意服务条款与隐私政策