一. 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);
}
}