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

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 一. 位置 我的电脑右键 --> 属性 --> 高级系统设置 --> 环境变量 二. 作用域 环境变量窗口中有用户变量和系统变量, 两者的作用域不同, 前者作用域为当前登录用户, 后者作用域为整个计算机.

一. JDK环境变量配置

1. 位置

我的电脑右键 --> 属性 --> 高级系统设置 --> 环境变量

2. 作用域

环境变量窗口中有用户变量和系统变量, 两者的作用域不同, 前者作用域为当前登录用户, 后者作用域为整个计算机.

3. 配置内容

添加如下三个变量, 如果变量已经存在, 则在已有的变量值后面追加即可, 变量值的每一项内容之间要用英文分号隔开.

变量名 变量值
JAVA_HOME D:Javajdk1.8;
PATH %JAVA_HOME%bin;
CLASSPATH %JAVA_HOME%libtools.jar;

二. Java后台获得客户端IP

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

/**
 * 获取客户端IP地址
 * 
 * @author paulandcode
 * @email paulandcode@gmail.com
 * @date 2017年3月8日 下午12:57:02
 */
public class IPUtils {
  private static Logger logger = LoggerFactory.getLogger(IPUtils.class);

  /**
   * 获取客户端IP地址
   * 
   * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
   * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实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

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

/**
 * 
 * @author paulandcode
 * @email paulandcode@gmail.com
 * @date 2017年3月8日 下午12:57:02
 */
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();
  }
}

四. Java代码行数统计

该类须放在src/test/java下

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

/**
 * 
 * @author paulandcode
 * @email paulandcode@gmail.com
 * @date 2017年5月18日 下午13:27:13
 */
public class CodeCounter {
  static long files = 0;
  static long codeLines = 0;
  static long commentLines = 0;
  static long blankLines = 0;
  static ArrayList<File> fileArray = new ArrayList<File>();
  
  /**
   * 获得目录下的文件和子目录下的文件
   * @param f
   * @return
   */
  public static ArrayList<File> getFile(File f) {
    File[] ff = f.listFiles();
    for (File child : ff) {
      if (child.isDirectory()) {
        getFile(child);
      } else
        fileArray.add(child);
    }
    return fileArray;
  }

  /**
   * 统计方法
   * @param f
   */
  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<File> al = getFile(new File(path));
    for (File f : al) {
      if (f.getName().matches(".*\\.java$")){ // 匹配java格式的文件
        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等)

1. Maven导包如下

<dependency>
  <groupId>eu.bitwalker</groupId>
  <artifactId>UserAgentUtils</artifactId>
  <version>1.21</version>
</dependency>

2. 工具类如下

import javax.servlet.http.HttpServletRequest;

import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.DeviceType;
import eu.bitwalker.useragentutils.UserAgent;

/**
 * 用户代理字符串识别工具
 * 
 * @author paulandcode
 * @email paulandcode@gmail.com
 * @date 2017年5月18日 下午13:27:13
 */
public class UserAgentUtils {
  /**
   * 获取用户代理对象
   * 
   * @param request
   * @return
   */
  public static UserAgent getUserAgent(HttpServletRequest request) {
    return UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
  }

  /**
   * 获取设备类型
   * 
   * @param request
   * @return
   */
  public static DeviceType getDeviceType(HttpServletRequest request) {
    return getUserAgent(request).getOperatingSystem().getDeviceType();
  }

  /**
   * 是否是PC
   * 
   * @param request
   * @return
   */
  public static boolean isComputer(HttpServletRequest request) {
    return DeviceType.COMPUTER.equals(getDeviceType(request));
  }

  /**
   * 是否是手机
   * 
   * @param request
   * @return
   */
  public static boolean isMobile(HttpServletRequest request) {
    return DeviceType.MOBILE.equals(getDeviceType(request));
  }

  /**
   * 是否是平板
   * 
   * @param request
   * @return
   */
  public static boolean isTablet(HttpServletRequest request) {
    return DeviceType.TABLET.equals(getDeviceType(request));
  }

    /**
   * 是否是手机和平板
     *
   * @param request
   * @return
   */
  public static boolean isMobileOrTablet(HttpServletRequest request){
    DeviceType deviceType = getDeviceType(request);
    return DeviceType.MOBILE.equals(deviceType) || DeviceType.TABLET.equals(deviceType);
  }

  /**
   * 获取浏览类型
   * 
   * @param request
   * @return
   */
  public static Browser getBrowser(HttpServletRequest request) {
    return getUserAgent(request).getBrowser();
  }

  /**
   * 是否是IE版本且小于等于IE8
   * 
   * @param request
   * @return
   */
  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. 进行拦截并根据需要进行处理

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import org.apache.commons.lang3.StringUtils;
import com.paulandcode.utils.UserAgentUtils;

/**
 * 根据需要进行拦截, 并做不同处理
 * 
 * @author paulandcode
 * @email paulandcode@gmail.com
 * @date 2017年5月18日 下午13:27:13
 */
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 {
  }
}

六. 根据日期生成目录

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 根据日期生成目录
 *
 * @author paulandcode
 * @since 2018年7月26日 上午10:33:33
 */
public class DirectoryUtils {
  /**
   * 生成目录
   * return 2018/07/26/1532572300220
   */
  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();
  }
}

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

1. Maven导包

<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
  <version>2.6</version>
</dependency>

2. 工具类

import org.apache.commons.io.FilenameUtils;

/**
 * 附件类型工具类
 *
 * @author paulandcode
 * @since 2018年7月26日 上午10:57:28
 */
public class FileTypeUtils {
  /**
   * 根据附件名获得附件类型
   * 
   * @param fileName
   * @return
   */
  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)
          || "avi".equalsIgnoreCase(extension)) {
        return "AVI";
      } else if ("HTML".equalsIgnoreCase(extension)) {
        return "HTM";
      } else if ("VSD".equalsIgnoreCase(extension)) {
        return "VSD";
      } else {
        return "OTHER";
      }
    }
    return "";
  }
}

八. 附件上传下载

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

<context-param>
  <param-name>webAppRootKey</param-name>
  <param-value>webPath</param-value>
</context-param>

2. Java代码如下

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.multipart.MultipartFile;

/**
 * 附件上传下载
 *
 * @author paulandcode
 * @since 2018年7月26日 上午11:20:35
 */
public class FileUtils {
  /**
   * 附件上传
   * 
   * @author Paul
   * @param file
   *            HTML表单上传的附件
   * @param subPath
   *            如: storage/excel
   * @return 附件最终路径
   */
  public static String fileUpload(MultipartFile file, String subPath) {
    // webPath在web.xml中配置, D:\Java\apache-tomcat-9.0.0\webapps\blog\
    String basePath = System.getProperty("webPath");
    // D:/Java/apache-tomcat-9.0.0/webapps/blog/storage/excel
    String path = basePath.replaceAll("\\\\", "/") + subPath;
    // D:/Java/apache-tomcat-9.0.0/webapps/blog/storage/excel/test.xls
    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;
  }

  /**
   * 附件下载
   * 
   * @param request
   * @param response
   * @param filePath
   *            项目根目录下的文件路径, 如: storage/excel/test.xls
   * @param fileShowName
   *            下载文件所显示的文件名,需要带后缀名, 如: 测试.xls
   * @return
   */
  public static boolean excelOutTemplate(HttpServletRequest request, HttpServletResponse response, String filePath, String fileShowName) {
    // http://127.0.0.1:8080/blog
    String localPath = request.getServletContext().getRealPath("/");
    // http://127.0.0.1:8080/blog/storage/excel/test.xls
    String finalPath = localPath.endsWith("/") ? (localPath + filePath) : (localPath + "/" + filePath);
    File file = new File(finalPath);
    if (file.exists()) {
      // 防止中文乱码, 设置UTF-8编码
      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

import java.util.UUID;

/**
 * 获得UUID
 *
 * @author paulandcode
 * @since 2018年7月26日 下午3:00:24
 */
public class IDUtils {
  /**
   * UUID
   * @return
   */
  public static String getId() {
    String id = UUID.randomUUID().toString();
    id = id.replace("-", "");
    return id;
  }
}

十. 自定义异常类

/**
 * 自定义异常
 *
 * @author paulandcode
 * @since 2018年7月26日 下午4:05:28
 */
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;
  }
}

十一. 字符串首字母大写

/**
 * 字符串首字母大写
 *
 * @author paulandcode
 * @since 2018年7月26日 下午4:29:19
 */
public class StringUtils {
  /**
   * 字符串首字母大写
   */
  public static String captureName(String name) {
        char[] cs=name.toCharArray();
        cs[0]-=32;
        return String.valueOf(cs);
    }
}

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

import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;

/**
 * List乱序与按照汉字拼音排序
 *
 * @author paulandcode
 * @since 2018年7月26日 下午3:10:55
 */
public class ListUtils {
  /**
   * List乱序
   * @param sourceList
   * @return
   */
  public static <V> List<V> randomList(List<V> sourceList) {  
      if (sourceList == null || sourceList.size() == 0) {  
          return sourceList;  
      }  
      List<V> random = new ArrayList<V>(sourceList.size());  
      do {  
          int index = Math.abs(new Random().nextInt(sourceList.size()));  
          random.add(sourceList.remove(index));  
      } while (sourceList.size() > 0);  
      return random;  
  }
  
  /**
   * List按照汉字拼音排序, 根据需要重写V的toString()方法
   * @param sourceList
   * @return
   */
  public static <V> List<V> sortList(List<V> sourceList) {  
      if (sourceList == null || sourceList.size() == 0) {  
          return sourceList;  
      }  
      List<V> sort = new ArrayList<V>(sourceList.size());
      sort.addAll(sourceList);
      Collections.sort(sort, new Comparator<V>(){
        @Override
            public int compare(V v0, V v1) {
              List<String> list = new ArrayList<String>(2);
              list.add(v0.toString());
              list.add(v1.toString());
              Collections.sort(list, Collator.getInstance(java.util.Locale.CHINA));
              return list.indexOf(v0.toString()) == 0 ? -1 : 1;
            }
        });
      return sort;  
  }
}

十三. 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添加配置文件

<!-- 配置redis -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
  <!-- <property name="maxIdle" value="6"></property> <property name="minEvictableIdleTimeMillis" 
    value="300000"></property> <property name="numTestsPerEvictionRun" value="3"></property> 
    <property name="timeBetweenEvictionRunsMillis" value="60000"></property> -->
  <property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}"></property>
  <property name="maxIdle" value="${redis.maxIdle}"></property>
  <property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}"></property>
  <property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}"></property>
</bean>
<bean id="jedisConnectionFactory"
  class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
  destroy-method="destroy">
  <property name="poolConfig" ref="jedisPoolConfig"></property>
  <property name="hostName" value="${redis.hostName}"></property>
  <property name="port" value="${redis.port}"></property>
  <property name="timeout" value="${redis.timeout}"></property>
  <property name="usePool" value="${redis.usePool}"></property>
</bean>
<bean id="jedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
  <property name="connectionFactory" ref="jedisConnectionFactory"/>
  <property name="keySerializer">
    <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
  </property>
  <property name="valueSerializer">
    <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
  </property>
</bean>

3. Maven依赖

<dependency>
  <groupId>org.springframework.data</groupId>
  <artifactId>spring-data-redis</artifactId>
  <version>1.6.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>2.9.0</version>
</dependency>

4. Redis工具类

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.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;

/**
 * redis缓存存储与获取
 *
 * @author paulandcode
 * @since 2018年3月8日 下午2:56:46
 */
@Service
public class RedisCacheUtil {
  @Autowired
  @Qualifier("jedisTemplate")
  public RedisTemplate<Object, Object> redisTemplate;

  /**
   * 缓存基本的对象,Integer,String,实体类等
   * 
   * @param key
   * @param value
   */
  public <K, V> void setCacheObject(K key, V value) {
    redisTemplate.boundValueOps(key).set(value);
  }

  /**
   * 获得缓存的基本对象
   * 
   * @param key
   * @return
   */
  @SuppressWarnings("unchecked")
  public <K, V> V getCacheObject(K key) {
    return (V) redisTemplate.boundValueOps(key).get();
  }

  /**
   * 缓存List
   * 
   * @param key
   * @param dataList
   */
  public <K, V> void setCacheList(K key, List<V> dataList) {
    redisTemplate.delete(key);
    for (V v : dataList) {
      redisTemplate.boundListOps(key).rightPush(v);
    }
  }

  /**
   * 获得缓存的List
   * 
   * @param key
   * @return
   */
  @SuppressWarnings("unchecked")
  public <K, V> List<V> getCacheList(K key) {
    BoundListOperations<K, V> listOperation = (BoundListOperations<K, V>) redisTemplate.boundListOps(key);
    return listOperation.range(0, listOperation.size());
  }

  /**
   * 缓存Set
   * 
   * @param key
   * @param dataSet
   */
  @SuppressWarnings("unchecked")
  public <K, V> void setCacheSet(K key, Set<V> dataSet) {
    redisTemplate.delete(key);
    BoundSetOperations<K, V> setOperation = (BoundSetOperations<K, V>) redisTemplate.boundSetOps(key);
    Iterator<V> it = dataSet.iterator();
    while (it.hasNext()) {
      setOperation.add(it.next());
    }
  }

  /**
   * 获得缓存的Set
   * 
   * @param key
   * @return
   */
  @SuppressWarnings("unchecked")
  public <K, V> Set<V> getCacheSet(K key) {
    return (Set<V>) redisTemplate.boundSetOps(key).members();
  }

  /**
   * 缓存Map
   * 
   * @param key
   * @param dataMap
   */
  public <K, HK, HV> void setCacheMap(K key, Map<HK, HV> dataMap) {
    redisTemplate.delete(key);
    redisTemplate.boundHashOps(key).putAll(dataMap);
  }

  /**
   * 获得缓存的Map
   * 
   * @param key
   * @return
   */
  @SuppressWarnings("unchecked")
  public <K, HK, HV> Map<HK, HV> getCacheMap(K key) {
    return (Map<HK, HV>) redisTemplate.boundHashOps(key).entries();
  }

  /**
   * 根据key删除对应的缓存
   * 
   * @param key, 若key为String, key支持通配符
   */
  public <K> void deleteByKey(K key) {
    redisTemplate.delete(redisTemplate.keys(key));
  }
}

十四. 判断是否是中文

/**
 * 判断是否是中文.
 *
 * @author paulandcode
 * @since 2018年7月26日 下午4:29:19
 */
public class CharUtils {
  /**
   * 
   * 判断中文汉字和符号是否是中文.
   * @param strName 字符串
   * @return 字符串是否是中文
   */
  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;
  }

  /**
   * 
   * 根据Unicode编码判断中文汉字和符号是否是中文.
   * @param c 字符
   * @return 字符是否是中文
   */
  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;
  }
}

十五. 异常拦截处理

import javax.servlet.http.HttpServletRequest;
import javax.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;

/**
 * 异常拦截处理
 *
 * @author paulandcode
 * @since 2018年7月26日 下午4:15:52
 */
@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工具类

import java.io.UnsupportedEncodingException;  
import java.net.URLDecoder;  
import java.net.URLEncoder;  
import javax.servlet.http.Cookie;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;

/**
 * Cookie工具类
 *
 * @author paulandcode
 * @since 2018年7月26日 下午4:15:52
 */
public class CookieUtils {
   /** 
     * 得到Cookie的值, 不编码 
     *  
     * @param request 
     * @param cookieName 
     * @return 
     */  
    public static String getCookieValue(HttpServletRequest request, String cookieName) {  
        return getCookieValue(request, cookieName, false);  
    }  
  
    /** 
     * 得到Cookie的值
     *  
     * @param request 
     * @param cookieName 
     * @return 
     */  
    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;  
    }  
  
    /** 
     * 得到Cookie的值
     *  
     * @param request 
     * @param cookieName 
     * @return 
     */  
    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;  
    }  
  
    /**
     *   
     * 设置Cookie的值 不设置生效时间默认浏览器关闭即失效,也不编码.
     * @param request
     * @param response
     * @param cookieName
     * @param cookieValue
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,  
            String cookieValue) {  
        setCookie(request, response, cookieName, cookieValue, -1);  
    }  
  
    /**
     *   
     * 设置Cookie的值 在指定时间内生效,但不编码.
     * @param request
     * @param response
     * @param cookieName
     * @param cookieValue
     * @param cookieMaxage cookie生效的最大秒数 
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,  
            String cookieValue, int cookieMaxage) {  
        setCookie(request, response, cookieName, cookieValue, cookieMaxage, false);  
    }  
  
    /**
     *   
     * 设置Cookie的值 不设置生效时间,但编码.
     * @param request
     * @param response
     * @param cookieName
     * @param cookieValue
     * @param isEncode
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,  
            String cookieValue, boolean isEncode) {  
        setCookie(request, response, cookieName, cookieValue, -1, isEncode);  
    }  
  
    /**
     *   
     * 设置Cookie的值 在指定时间内生效, 编码参数.
     * @param request
     * @param response
     * @param cookieName
     * @param cookieValue
     * @param cookieMaxage cookie生效的最大秒数 
     * @param isEncode 是否编码
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,  
            String cookieValue, int cookieMaxage, boolean isEncode) {  
        doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, isEncode);  
    }  
  
    /** 
     * 设置Cookie的值 在指定时间内生效, 编码参数(指定编码) 
     */  
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,  
            String cookieValue, int cookieMaxage, String encodeString) {  
        doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, encodeString);  
    }  
  
    /**
     *   
     * 删除Cookie.
     * @param request
     * @param response
     * @param cookieName
     */
    public static void deleteCookie(HttpServletRequest request, HttpServletResponse response,  
            String cookieName) {  
        doSetCookie(request, response, cookieName, "", -1, false);  
    }  
  
    /** 
     * 设置Cookie的值,并使其在指定时间内生效 
     *  
     * @param cookieMaxage cookie生效的最大秒数 
     */  
    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) {// 设置域名的cookie  
                String domainName = getDomainName(request);  
                System.out.println(domainName);  
                if (!"localhost".equals(domainName)) {  
                    //cookie.setDomain(domainName);  
                }  
            }  
            cookie.setPath("/");  
            response.addCookie(cookie);  
        } catch (Exception e) {  
             e.printStackTrace();  
        }  
    }  
  
    /** 
     * 设置Cookie的值,并使其在指定时间内生效 
     *  
     * @param cookieMaxage cookie生效的最大秒数 
     */  
    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) {// 设置域名的cookie  
                String domainName = getDomainName(request);  
                System.out.println(domainName);  
                if (!"localhost".equals(domainName)) {  
                    //本地测试的时候不要写.实际发布时在打开  
                    //cookie.setDomain(domainName);  
                }  
            }  
            cookie.setPath("/");  
            response.addCookie(cookie);  
        } catch (Exception e) {  
             e.printStackTrace();  
        }  
    }  
  
    /** 
     * 得到cookie的域名 
     */  
    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) {  
                // www.xxx.com.cn  
                domainName = "." + domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1];  
            } else if (len <= 3 && len > 1) {  
                // xxx.com or xxx.cn  
                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 java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 日期处理
 * 
 * @author paulandcode
 * @email paulandcode@gmail.com
 * @date 2017年5月18日 下午13:27:13
 */
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";

  /**
   * 
   * 默认按照"yyyy-MM-dd"格式化日期.
   * @param date
   * @return
   */
  public static String format(Date date) {
    return format(date, DATE_PATTERN);
  }

  /**
   * 
   * 按照指定的日期格式来格式化日期.
   * @param date
   * @param pattern 日期格式
   * @return
   */
  public static String format(Date date, String pattern) {
    if (date != null) {
      SimpleDateFormat df = new SimpleDateFormat(pattern);
      return df.format(date);
    }
    return null;
  }

  /**
   * 返回给定日期所在月的所有日期集合
   * 
   * @param date
   * @return
   */
  public static List<Date> getAllDatesOfMonth(Date date) {
    List<Date> list = new ArrayList<Date>();
    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;
  }

  /**
   * 判断两个日期是否是同一天
   * 
   * @param date1
   * @param date2
   * @return
   */
  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;
  }

  /**
   * 
   * 计算两个日期之间相差多少天
   * 
   * @param date1
   * @param date2
   * @return
   * @throws ParseException
   */
  public static int getDateSpace(Date date1, Date date2) {
    Calendar calst = Calendar.getInstance();
    Calendar caled = Calendar.getInstance();
    calst.setTime(date1);
    caled.setTime(date2);

    // 设置时间为0时
    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工具类(通过Java后台进行Http访问)

1. Maven导包

<dependency>  
    <groupId>org.apache.httpcomponents</groupId>  
    <artifactId>httpclient</artifactId>  
    <version>4.3.1</version>  
</dependency>  
<dependency>  
    <groupId>org.apache.httpcomponents</groupId>  
    <artifactId>httpcore</artifactId>  
    <version>4.3.1</version>  
</dependency>  
<dependency>  
    <groupId>org.apache.httpcomponents</groupId>  
    <artifactId>httpmime</artifactId>  
    <version>4.3.1</version>  
</dependency>

2. Java代码

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

import javax.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.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.BasicNameValuePair;
import org.apache.http.util.CharsetUtils;
import org.apache.http.util.EntityUtils;

/**
 * HttpClient工具类
 *
 * @author paulandcode
 * @since 2018年7月26日 下午2:35:09
 */
public class HttpClientUtils {
  /**
   * 成功状态码
   */
  private static final int SUCCESS = 200;

  /**
   * HttpClient连接SSL,需要导入证书的方法 若SSL需要导入信任的证书,使用该方法
   * 
   * @param url
   */
  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 {
        // 加载keyStore d:\\tomcat.keystore
        trustStore.load(instream, "123456".toCharArray());
      } catch (CertificateException e) {
        e.printStackTrace();
      } finally {
        try {
          instream.close();
        } catch (Exception ignore) {
        }
      }
      // 相信自己的CA和所有自签名的证书
      SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy())
          .build();
      // 只允许使用TLSv1协议
      SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" },
          null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
      httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
      // 创建http请求(get方式)
      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();
        }
      }
    }
  }

  /**
   * 不需要导入证书,SSL信任所有证书,使用该方法
   * 
   * @return
   */
  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();

  }

  /**
   * HttpClient连接SSL,不需要导入证书 信任所有证书,跳过证书验证
   * 
   * @param url
   */
  public static void ssl2(String url) {
    CloseableHttpClient httpclient = null;
    try {

      httpclient = createSSLClientDefault();
      // 创建http请求(get方式)
      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();
        }
      }
    }
  }

  /**
   * 关闭HttpClient的客户端和响应
   *
   * @param client 客户端
   * @param response 响应
   * @return void
   */
  private static void closeClientAndResponse(CloseableHttpClient client, CloseableHttpResponse response) {
      try {
          if (response != null) {
              response.close();
          }
          if (client != null) {
              client.close();
          }
      } catch (IOException e) {
          e.printStackTrace();
      }
  }

  /**
   * HttpClient模拟浏览器进行Get请求
   *
   * @param url 请求路径, 示例: http://localhost:8080/api/testget
   * @param params 请求参数
   * @return java.util.Map<java.lang.String,java.lang.String>
   */
  public static Map<String, String> doGet(String url, Map<String, String> params) {
      Map<String, String> result = new HashMap<>(2);
      result.put("code", "200");
      CloseableHttpClient client = null;
      CloseableHttpResponse response = null;
      try {
          //创建一个httpclient对象
          client = HttpClients.createDefault();
          //创建URIBuilder
          URIBuilder uri = new URIBuilder(url);
          //设置参数
          if (params != null) {
              Set<Map.Entry<String, String>> entries = params.entrySet();
              for (Map.Entry<String, String> entry : entries) {
                  uri.addParameter(entry.getKey(), entry.getValue());
              }
          }
          //创建httpGet对象
          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) {
              // 通过EntityUtils的一个工具方法获取返回内容
              String resStr = EntityUtils.toString(response.getEntity(), "utf-8");
              result.put("data", resStr);
          } else {
              result.put("code", statusCode + "");
          }
      } catch (URISyntaxException | IOException e) {
          e.printStackTrace();
      } finally {
          //关闭response和client
          closeClientAndResponse(client, response);
      }
      return result;
  }

  /**
   * HttpClient模拟浏览器进行Post请求
   *
   * @param url 请求路径, 示例: http://localhost:8080/api/testget
   * @param params 请求参数
   * @return java.util.Map<java.lang.String,java.lang.String>
   */
  public static Map<String, String> doPost(String url, Map<String, String> params){
      Map<String, String> result = new HashMap<>(2);
      result.put("code", "200");
      CloseableHttpClient client = null;
      CloseableHttpResponse response = null;
      try {
          //创建一个httpclient对象
          client = HttpClients.createDefault();
          //创建一个post对象
          HttpPost post = new HttpPost(url);
          //创建一个Entity,模拟表单数据
          List<NameValuePair> formList = new ArrayList<>();
          //添加表单数据
          if (params != null) {
              Set<Map.Entry<String, String>> entries = params.entrySet();
              for (Map.Entry<String, String> entry : entries) {
                  formList.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
              }
          }
          //包装成一个Entity对象
          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"));
          //执行post请求
          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 {
          //关闭response和client
          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:\\Users\\zhangwenchao\\Desktop\\jinzhongzi.jpg"));
      // StringBody name = new StringBody("这个一测试",
      // ContentType.TEXT_PLAIN);
      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);

      // httppost = new
      // HttpPost(response.getLastHeader("location").getValue());
      // 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) {
    // 生成一个httpclient对象
    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);
            // 注意这里如果用OutputStream.write(buff)的话,图片会失真,大家可以试试
          }
          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();
      }
    }
  }
}

十九. 分页工具类

import java.io.Serializable;
import java.util.List;

/**
 * 分页工具类
 * 
 * @author paulandcode
 * @email paulandcode@gmail.com
 * @date 2017年5月18日 下午13:27:13
 */
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;
  
  /**
   * 新建分页
   * @param list        分页数据
   * @param totalCount  总记录数
   * @param pageSize    每页记录数
   * @param currPage    当前页数
   */
  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);
  }

  public int getTotalCount() {
    return totalCount;
  }

  public void setTotalCount(int totalCount) {
    this.totalCount = totalCount;
  }

  public int getPageSize() {
    return pageSize;
  }

  public void setPageSize(int pageSize) {
    this.pageSize = pageSize;
  }

  public int getTotalPage() {
    return totalPage;
  }

  public void setTotalPage(int totalPage) {
    this.totalPage = totalPage;
  }

  public int getCurrPage() {
    return currPage;
  }

  public void setCurrPage(int currPage) {
    this.currPage = currPage;
  }

  public List<?> getList() {
    return list;
  }

  public void setList(List<?> list) {
    this.list = list;
  } 
}

二十. SQL查询工具类

1. SQL过滤

import org.apache.commons.lang.StringUtils;

/**
 * SQL过滤
 *
 * @author paulandcode
 * @since 2018年7月26日 下午4:29:19
 */
public class SQLFilter {
  /**
   * 
   * SQL注入过滤.
   * @param str 待验证的字符串
   * @return 过滤后字符串
   */
    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 com.paulandcode.utils.SQLFilter;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * SQL查询.
 *
 * @author paulandcode
 * @since 2018年7月26日 下午4:29:19
 */
public class Q extends LinkedHashMap<String, Object> {
  private static final long serialVersionUID = 1L;
  //当前页码
    private int page;
    //每页条数
    private int limit;

    /**
     * 
     * 构造函数.
     * @param params
     */
    public Q(Map<String, Object> 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);
        }

        //防止SQL注入(因为sidx、order是通过拼接SQL实现排序的,会有SQL注入风险)
        // sidx为排序字段, 以英文逗号隔开
        this.put("sidx", SQLFilter.sqlInject(sidx));
        // order为排序方式, DESC或ASC
        this.put("order", SQLFilter.sqlInject(order));
    }

    /**
     * 
     * 构造函数.
     */
    public Q() {
        this.put("page", page);
        this.put("limit", null);
        this.put("sidx", "");
        this.put("order", "");
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public int getLimit() {
        return limit;
    }

    public void setLimit(int limit) {
        this.limit = limit;
    }
}

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

<select id="queryList" parameterType="map" resultType="com.paulandcode.entity.Test">
  SELECT
    id,
    name
  FROM test
  <choose>
  <when test="sidx.trim() != '' and sidx.trim() != ''">
    ORDER BY ${sidx} ${order}
  </when>
  <otherwise>
    ORDER BY id DESC
  </otherwise>
  </choose>
  <if test="offset != null and limit != null">
    LIMIT #{offset}, #{limit}
  </if>
</select>

二十一. Shiro工具类

1. Maven导包

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.3.2</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.3.2</version>
</dependency>
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-ehcache</artifactId>
  <version>1.3.2</version>
</dependency>

2. 工具类

import com.paulandcode.entity.SysUserEntity;

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

/**
 * Shiro工具类
 *
 * @author paulandcode
 * @since 2018年7月26日 下午4:29:19
 */
public class ShiroUtils {
  /**
   * 
   * 获得ShiroSession.
   * @return
   */
  public static Session getSession() {
    return SecurityUtils.getSubject().getSession();
  }

  /**
   * 
   * 获得Subject.
   * @return
   */
  public static Subject getSubject() {
    return SecurityUtils.getSubject();
  }

  /**
   * 
   * 获得Princpal, 此处的SysUserEntity是自定义UserRealm中的doGetAuthenticationInfo方法中设置的.
   * @return
   */
  public static SysUserEntity getUserEntity() {
    return (SysUserEntity)SecurityUtils.getSubject().getPrincipal();
  }

  /**
   * 
   * 获得用户id.
   * @return
   */
  public static Long getUserId() {
    return getUserEntity().getUserId();
  }
  
  /**
   * 
   * ShiroSession中放置某个键值对
   * @param key
   * @param value
   */
  public static void setSessionAttribute(Object key, Object value) {
    getSession().setAttribute(key, value);
  }

  /**
   * 
   * 获得ShiroSession中某个键值对
   * @param key
   * @return
   */
  public static Object getSessionAttribute(Object key) {
    return getSession().getAttribute(key);
  }

  /**
   * 
   * 是否已经登录.
   * @return
   */
  public static boolean isLogin() {
    return SecurityUtils.getSubject().getPrincipal() != null;
  }

  /**
   * 
   * 退出登录.
   */
  public static void logout() {
    SecurityUtils.getSubject().logout();
  }
  
  /**
   * 
   * 获得验证码, 获得一次后, 从ShiroSession中移除, 无法再次获得.
   * @param key
   * @return
   */
  public static String getKaptcha(String key) {
    String kaptcha = getSessionAttribute(key).toString();
    getSession().removeAttribute(key);
    return kaptcha;
  }
}

二十二. SpringContext工具类

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

/**
 * SpringContext 工具类
 *
 * @author paulandcode
 * @since 2018年7月26日 下午4:29:19
 */
@Component
public class SpringContextUtils implements ApplicationContextAware {
    public static ApplicationContext applicationContext; 

    /**
     *
     * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        SpringContextUtils.applicationContext = applicationContext;
    }

    /**
     * 
     * 获得Bean.
     * @param name Bean的名称
     * @return
     */
    public static Object getBean(String name) {
        return applicationContext.getBean(name);
    }

    /**
     * 
     * 获得Bean.
     * @param name Bean的名称
     * @param requiredType 类型
     * @return
     */
    public static <T> T getBean(String name, Class<T> requiredType) {
        return applicationContext.getBean(name, requiredType);
    }

    /**
     * 
     * 是否包含某个Bean.
     * @param name Bean的名称
     * @return
     */
    public static boolean containsBean(String name) {
        return applicationContext.containsBean(name);
    }

    /**
     * 
     * Bean是否是单例.
     * @param name Bean的名称
     * @return
     */
    public static boolean isSingleton(String name) {
        return applicationContext.isSingleton(name);
    }

    /**
     * 
     * Bean的类型.
     * @param name Bean的名称
     * @return
     */
    public static Class<? extends Object> getType(String name) {
        return applicationContext.getType(name);
    }
}

二十三. Properties载入工具类

1. 工具类如下

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;

/**
 * properties载入工具类
 * 
 * @author paulandcode
 * @email paulandcode@gmail.com
 * @date 2017年5月18日 下午13:27:13
 */
public class PropertiesLoader {
  private final Properties properties;

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

  /**
   * 载入多个properties文件
   * 
   * @param resourcePaths
   * @return
   */
  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;
  }

  /**
   *  获得字符串参数
   * 
   * @param key
   * @return
   */
  public String getConfig(String key) {
    if (properties.containsKey(key)) {
      return properties.getProperty(key);
    }
    return "";
  }
  
  /**
   * 
   * 获得数字参数 
   * @param 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");
}

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

下面代码中的"Bat Finished! "是为了标记Bat执行结束, 可以在Bat文件的最后加入"echo Bat Finished! "来标记Bat执行结束. "Bat Success! "是为了标记Bat执行成功, "Bat Fail! "标记Bat执行失败, 可以将Bat文件进行相应的echo输出达到这样的效果. 这样做的目的是为了让java知道Bat是否成功执行结束, 若程序无需知道是否执行结束, 则Process process = processBuilder.start();这一句代码之后的其他代码可以去掉.

package com.ribeen.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

/**
 * 执行bat命令
 *
 * @author paulandcode paulandcode@gmail.com
 * @date 2018/10/9 14:59
 */
public class BatUtils {
    /**
     * 执行kettle命令
     *
     * @param batPath     bat文件路径, 如: E:/test/test.bat
     * @param args     参数, 最多可以有9个参数, 从左到右代表1到9, 在Bat文件中用1%到9%表示参数
     * @return boolean 执行成功或失败
     */
    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为false
                    }
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }
}

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

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

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

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

注意: 得到的值前后都有个斜杠

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

package com.product.utils;

import java.util.HashMap;
import java.util.Map;

/**
 * 下划线与驼峰相互转换
 *
 * @author paulandcode paulandcode@gmail.com
 * @date 2018/10/4 14:21
 */
public class HumpUtils {
    private static final char UNDERLINE = '_';
    
    /**
     * 数组由下划线转换为驼峰
     *
     * @param arr 带有下划线的数组
     * @return java.util.Map<java.lang.String,V>
     */
    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;
    }

    /**
     * 数组由驼峰转换为下划线
     *
     * @param arr 带有下划线的数组
     * @return java.util.Map<java.lang.String,V>
     */
    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;
    }

    /**
     * 将Map中的key由下划线转换为驼峰
     *
     * @param map 带有下划线的map
     * @return java.util.Map<java.lang.String,V>
     */
    public static <V> Map<String, V> mapKeyUnderlineToHump(Map<String, V> map) {
        if (map == null) {
            return null;
        }
        Map<String, V> newMap = new HashMap<>(map.size());
        for (Map.Entry<String, V> entry : map.entrySet()) {
            String key = entry.getKey();
            String newKey = toHump(key);
            newMap.put(newKey, entry.getValue());
        }
        return newMap;
    }

    /**
     * 将Map中的key由驼峰转换为下划线
     *
     * @param map 带有驼峰的map
     * @return java.util.Map<java.lang.String,V>
     */
    public static <V> Map<String, V> mapKeyHumpToUnderline(Map<String, V> map) {
        if (map == null) {
            return null;
        }
        Map<String, V> newMap = new HashMap<>(map.size());
        for (Map.Entry<String, V> entry : map.entrySet()) {
            String key = entry.getKey();
            String newKey = toUnderline(key);
            newMap.put(newKey, entry.getValue());
        }
        return newMap;
    }

    /**
     * 下划线转驼峰
     *
     * @param colName 字符串
     * @return java.lang.String
     */
    public static String toHump(String colName) {
        if (colName == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        String[] str = colName.toLowerCase().split(String.valueOf(UNDERLINE));
        for (String s : str) {
            if (s.length() == 1) {
                sb.append(s.toUpperCase());
                continue;
            }
            if (s.length() > 1) {
                sb.append(s.substring(0, 1).toUpperCase());
                sb.append(s.substring(1));
            }
        }
        String result = sb.toString();
        return result.substring(0, 1).toLowerCase() + result.substring(1);
    }

    /**
     * 驼峰转下划线
     *
     * @param colName 字符串
     * @return java.lang.String
     */
    private static String toUnderline(String colName) {
        if (colName == null) {
            return null;
        }
        String result = colName.replaceAll("[A-Z]", String.valueOf(UNDERLINE) + "$0");
        return result.toLowerCase();
    }
}

二十七. Web响应信息工具类

package com.paulandcode.common;

import java.util.HashMap;
import java.util.Map;

/**
 * Web响应信息
 * 前后端通信时一般0或200为正常, 1或500以及其他为异常
 * 数据库中字段的值一般0为false, 1为true
 *
 * @author paulandcode paulandcode@gmail.com
 * @since 2019/3/27 17:23
 */
public class R extends HashMap<String, Object> {
    private static final long serialVersionUID = -7035368021961298846L;

    /**
     * 构造函数, 默认成功.
     */
    private R() {
        put("code", 0);
    }

    /**
     * 响应未知异常.
     *
     * @return com.paulandcode.common.R
     */
    public static R err() {
        return err(1, "未知异常, 请联系管理员! ");
    }

    /**
     * 响应自定义异常信息.
     *
     * @param msg 异常信息
     * @return com.paulandcode.common.R
     */
    public static R err(String msg) {
        return err(1, msg);
    }

    /**
     * 响应自定义异常信息和状态码.
     *
     * @param code 状态码
     * @param msg  异常信息
     * @return com.paulandcode.common.R
     */
    public static R err(int code, String msg) {
        R r = new R();
        r.put("code", code);
        r.put("msg", msg);
        return r;
    }

    /**
     * 响应成功并自定义信息.
     *
     * @param msg 成功信息
     * @return com.paulandcode.common.R
     */
    public static R msg(String msg) {
        R r = new R();
        r.put("msg", msg);
        return r;
    }

    /**
     * 响应成功.
     *
     * @return com.paulandcode.common.R
     */
    public static R ok() {
        return new R();
    }

    /**
     * 响应成功并自定义信息.
     *
     * @param data 成功数据
     * @return com.paulandcode.common.R
     */
    public static R ok(Object data) {
        return ok().data(data);
    }

    /**
     * 响应成功并加入一些键值对.
     *
     * @param map 键值对
     * @return com.paulandcode.common.R
     */
    public static R ok(Map<String, Object> map) {
        R r = new R();
        r.putAll(map);
        return r;
    }

    /**
     * 响应信息移除指定键值对.
     *
     * @param key 键
     * @return com.paulandcode.common.R
     */
    public R remove(String key) {
        super.remove(key);
        return this;
    }

    /**
     * 响应中加入一个键值对.
     *
     * @param key   键
     * @param value 值
     * @return com.paulandcode.common.R
     */
    @Override
    public R put(String key, Object value) {
        super.put(key, value);
        return this;
    }

    /**
     * 放入响应数据
     *
     * @param data 响应数据
     * @return com.paulandcode.common.R
     */
    public R data(Object data) {
        return put("data", data);
    }

    /**
     * 放入数据总数
     *
     * @param count 总数
     * @return com.paulandcode.common.R
     */
    public R count(int count) {
        return put("count", count);
    }
}
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
23天前
|
安全 Java 编译器
JDK 10中的局部变量类型推断:Java编程的简化与革新
JDK 10引入的局部变量类型推断通过`var`关键字简化了代码编写,提高了可读性。编译器根据初始化表达式自动推断变量类型,减少了冗长的类型声明。虽然带来了诸多优点,但也有一些限制,如只能用于局部变量声明,并需立即初始化。这一特性使Java更接近动态类型语言,增强了灵活性和易用性。
99 53
|
16天前
|
IDE Java 编译器
开发 Java 程序一定要安装 JDK 吗
开发Java程序通常需要安装JDK(Java Development Kit),因为它包含了编译、运行和调试Java程序所需的各种工具和环境。不过,某些集成开发环境(IDE)可能内置了JDK,或可使用在线Java编辑器,无需单独安装。
|
1月前
|
Java 数据库连接 数据库
如何构建高效稳定的Java数据库连接池,涵盖连接池配置、并发控制和异常处理等方面
本文介绍了如何构建高效稳定的Java数据库连接池,涵盖连接池配置、并发控制和异常处理等方面。通过合理配置初始连接数、最大连接数和空闲连接超时时间,确保系统性能和稳定性。文章还探讨了同步阻塞、异步回调和信号量等并发控制策略,并提供了异常处理的最佳实践。最后,给出了一个简单的连接池示例代码,并推荐使用成熟的连接池框架(如HikariCP、C3P0)以简化开发。
48 2
|
2月前
|
设计模式 Java API
[Java]静态代理与动态代理(基于JDK1.8)
本文介绍了代理模式及其分类,包括静态代理和动态代理。静态代理分为面向接口和面向继承两种形式,分别通过手动创建代理类实现;动态代理则利用反射技术,在运行时动态创建代理对象,分为JDK动态代理和Cglib动态代理。文中通过具体代码示例详细讲解了各种代理模式的实现方式和应用场景。
28 0
[Java]静态代理与动态代理(基于JDK1.8)
|
2月前
|
安全 Java 数据安全/隐私保护
如何配置 Java 安全管理器来避免访问控制异常
配置Java安全管理器以防止访问控制异常,需在启动JVM时通过 `-Djava.security.manager` 参数启用,并设置安全策略文件,定义权限规则,限制代码执行操作,确保应用安全。
|
2月前
|
Java BI 调度
Java Spring的定时任务的配置和使用
遵循上述步骤,你就可以在Spring应用中轻松地配置和使用定时任务,满足各种定时处理需求。
148 1
|
2月前
|
Java
让星星⭐月亮告诉你,jdk1.8 Java函数式编程示例:Lambda函数/方法引用/4种内建函数式接口(功能性-/消费型/供给型/断言型)
本示例展示了Java中函数式接口的使用,包括自定义和内置的函数式接口。通过方法引用,实现对字符串操作如转换大写、数值转换等,并演示了Function、Consumer、Supplier及Predicate四种主要内置函数式接口的应用。
27 1
|
2月前
|
Java
Java基础之 JDK8 HashMap 源码分析(中间写出与JDK7的区别)
这篇文章详细分析了Java中HashMap的源码,包括JDK8与JDK7的区别、构造函数、put和get方法的实现,以及位运算法的应用,并讨论了JDK8中的优化,如链表转红黑树的阈值和扩容机制。
29 1
|
15天前
|
Java 开发者
Java多线程编程中的常见误区与最佳实践####
本文深入剖析了Java多线程编程中开发者常遇到的几个典型误区,如对`start()`与`run()`方法的混淆使用、忽视线程安全问题、错误处理未同步的共享变量等,并针对这些问题提出了具体的解决方案和最佳实践。通过实例代码对比,直观展示了正确与错误的实现方式,旨在帮助读者构建更加健壮、高效的多线程应用程序。 ####
|
6天前
|
缓存 Java 开发者
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####