从"Blog"仓库中分离出来

This commit is contained in:
小海
2019-11-28 19:18:16 +08:00
commit 16cc30f513
119 changed files with 11291 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
package cn.celess.blog.util;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
/**
* @author : xiaohai
* @date : 2019/03/28 17:22
*/
public class DateFormatUtil {
public static String get(Date date) {
if (date == null) {
return null;
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(date);
}
public static String getForXmlDate(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZ");
GregorianCalendar gc = new GregorianCalendar();
String dateString = sdf.format(date);
try {
gc.setTime(sdf.parse(dateString));
XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
return date2.toString();
} catch (DatatypeConfigurationException | ParseException e) {
e.printStackTrace();
return null;
}
}
public static String getNow() {
return get(new Date());
}
}

View File

@@ -0,0 +1,93 @@
package cn.celess.blog.util;
import cn.celess.blog.entity.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @Author: 小海
* @Date: 2019/11/16 11:26
* @Description: JWT工具类
*/
@Component
public class JwtUtil {
private static final String CLAIM_KEY_USERNAME = "sub";
/**
* 5天(毫秒)
*/
public static final long EXPIRATION_LONG_TIME = 432000000;
/**
* 两小时(毫秒)
*/
public static final long EXPIRATION_SHORT_TIME = 7200000;
/**
* JWT 秘钥需自行设置不可泄露
*/
private static final String SECRET = "xxx";
public String generateToken(User user, boolean isRemember) {
Map<String, Object> claims = new HashMap<>(16);
claims.put(CLAIM_KEY_USERNAME, user.getEmail());
return Jwts.builder()
.setClaims(claims)
.setExpiration(new Date(Instant.now().toEpochMilli() + (isRemember ? EXPIRATION_LONG_TIME : EXPIRATION_SHORT_TIME)))
.signWith(SignatureAlgorithm.HS512, SECRET)
.compact();
}
public Boolean validateToken(String token, User user) {
String username = getUsernameFromToken(token);
return (username.equals(user.getEmail()) && !isTokenExpired(token));
}
/**
* 获取token是否过期
*/
public Boolean isTokenExpired(String token) {
try {
Date expiration = getExpirationDateFromToken(token);
return expiration.before(new Date());
} catch (ExpiredJwtException e) {
return true;
}
}
/**
* 根据token获取username
*/
public String getUsernameFromToken(String token) {
return getClaimsFromToken(token).getSubject();
}
/**
* 获取token的过期时间
*/
public Date getExpirationDateFromToken(String token) {
return getClaimsFromToken(token).getExpiration();
}
/**
* 解析JWT
*/
private Claims getClaimsFromToken(String token) {
Claims claims = Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token)
.getBody();
return claims;
}
}

View File

@@ -0,0 +1,14 @@
package cn.celess.blog.util;
import org.springframework.util.DigestUtils;
/**
* @author : xiaohai
* @date : 2019/03/30 18:56
*/
public class MD5Util {
public static String getMD5(String str) {
String md5 = DigestUtils.md5DigestAsHex(str.getBytes());
return md5;
}
}

View File

@@ -0,0 +1,126 @@
package cn.celess.blog.util;
import com.dyuproject.protostuff.LinkedBuffer;
import com.dyuproject.protostuff.ProtostuffIOUtil;
import com.dyuproject.protostuff.Schema;
import com.dyuproject.protostuff.runtime.RuntimeSchema;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
/**
* ProtoStuffSerializerUtil
*
* @author Sirius
* @date 2019-1-8
*/
public class ProtoStuffSerializerUtil {
/**
* 序列化对象
*
* @param obj
* @return
*/
public static <T> byte[] serialize(T obj) {
if (obj == null) {
throw new RuntimeException("序列化对象(" + obj + ")!");
}
@SuppressWarnings("unchecked")
Schema<T> schema = (Schema<T>) RuntimeSchema.getSchema(obj.getClass());
LinkedBuffer buffer = LinkedBuffer.allocate(1024 * 1024);
byte[] protostuff = null;
try {
protostuff = ProtostuffIOUtil.toByteArray(obj, schema, buffer);
} catch (Exception e) {
throw new RuntimeException("序列化(" + obj.getClass() + ")对象(" + obj + ")发生异常!", e);
} finally {
buffer.clear();
}
return protostuff;
}
/**
* 反序列化对象
*
* @param paramArrayOfByte
* @param targetClass
* @return
*/
public static <T> T deserialize(byte[] paramArrayOfByte, Class<T> targetClass) {
if (paramArrayOfByte == null || paramArrayOfByte.length == 0) {
throw new RuntimeException("反序列化对象发生异常,byte序列为空!");
}
T instance = null;
try {
instance = targetClass.newInstance();
} catch (InstantiationException e1) {
throw new RuntimeException("反序列化过程中依据类型创建对象失败!", e1);
} catch (IllegalAccessException e2) {
throw new RuntimeException("反序列化过程中依据类型创建对象失败!", e2);
}
Schema<T> schema = RuntimeSchema.getSchema(targetClass);
ProtostuffIOUtil.mergeFrom(paramArrayOfByte, instance, schema);
return instance;
}
/**
* 序列化列表
*
* @param objList
* @return
*/
public static <T> byte[] serializeList(List<T> objList) {
if (objList == null || objList.isEmpty()) {
throw new RuntimeException("序列化对象列表(" + objList + ")参数异常!");
}
@SuppressWarnings("unchecked")
Schema<T> schema = (Schema<T>) RuntimeSchema.getSchema(objList.get(0).getClass());
LinkedBuffer buffer = LinkedBuffer.allocate(1024 * 1024);
byte[] protostuff = null;
ByteArrayOutputStream bos = null;
try {
bos = new ByteArrayOutputStream();
ProtostuffIOUtil.writeListTo(bos, objList, schema, buffer);
protostuff = bos.toByteArray();
} catch (Exception e) {
throw new RuntimeException("序列化对象列表(" + objList + ")发生异常!", e);
} finally {
buffer.clear();
try {
if (bos != null) {
bos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return protostuff;
}
/**
* 反序列化列表
*
* @param paramArrayOfByte
* @param targetClass
* @return
*/
public static <T> List<T> deserializeList(byte[] paramArrayOfByte, Class<T> targetClass) {
if (paramArrayOfByte == null || paramArrayOfByte.length == 0) {
throw new RuntimeException("反序列化对象发生异常,byte序列为空!");
}
Schema<T> schema = RuntimeSchema.getSchema(targetClass);
List<T> result = null;
try {
result = ProtostuffIOUtil.parseListFrom(new ByteArrayInputStream(paramArrayOfByte), schema);
} catch (IOException e) {
throw new RuntimeException("反序列化对象列表发生异常!", e);
}
return result;
}
}

View File

@@ -0,0 +1,46 @@
package cn.celess.blog.util;
import cn.celess.blog.enmu.ResponseEnum;
import cn.celess.blog.entity.User;
import cn.celess.blog.exception.MyException;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;
/**
* @author : xiaohai
* @date : 2019/03/08 15:06
*/
@Component
public class RedisUserUtil {
@Autowired
RedisUtil redisUtil;
@Autowired
JwtUtil jwtUtil;
public User get(HttpServletRequest request) {
User user = getWithOutExc(request);
if (user == null) {
throw new MyException(ResponseEnum.HAVE_NOT_LOG_IN);
}
return user;
}
public User getWithOutExc(HttpServletRequest request) {
String token = request.getHeader("Authorization");
if (token == null || token.isEmpty()) {
return null;
}
String email = jwtUtil.getUsernameFromToken(token);
return (User) JSONObject.toBean(JSONObject.fromObject(redisUtil.get(email + "-login")), User.class);
}
public User set(User user) {
redisUtil.setEx(user.getEmail() + "-login", JSONObject.fromObject(user).toString(),
redisUtil.getExpire(user.getEmail() + "-login"), TimeUnit.MILLISECONDS);
return user;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,80 @@
package cn.celess.blog.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author : xiaohai
* @date : 2019/05/12 11:04
*/
public class RegexUtil {
/**
* 网址匹配
*
* @param url
* @return
*/
public static boolean urlMatch(String url) {
if (url == null || url.replaceAll(" ", "").isEmpty()) {
return false;
}
//正则 http(s)://www.celess/xxxx,www.celess.cn/xxx
String pattern = "^(http://|https://|)([\\w-]+\\.)+[\\w-]+(/[\\w-./?%&=]*)?$";
return match(url, pattern);
}
/**
* 邮箱验证
*
* @param email
* @return
*/
public static boolean emailMatch(String email) {
if (email == null || email.replaceAll(" ", "").isEmpty()) {
return false;
}
//正则
String pattern = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
return match(email, pattern);
}
/**
* 手机号匹配
*
* @param phone
* @return
*/
public static boolean phoneMatch(String phone) {
if (phone == null || phone.replaceAll(" ", "").isEmpty()) {
return false;
}
//正则
String pattern = "^([1][3,4,5,6,7,8,9])\\d{9}$";
return match(phone, pattern);
}
/**
* 密码正则
* 最短6位最长16位 {6,16}
* 可以包含小写大母 [a-z] 和大写字母 [A-Z]
* 可以包含数字 [0-9]
* 可以包含下划线 [ _ ] 和减号 [ - ]
*
* @param pwd
* @return
*/
public static boolean pwdMatch(String pwd) {
if (pwd == null || pwd.replaceAll(" ", "").isEmpty()) {
return false;
}
//正则
String pattern = "^[\\w_-]{6,16}$";
return match(pwd, pattern);
}
private static boolean match(String str, String pattern) {
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(str);
return m.matches();
}
}

View File

@@ -0,0 +1,17 @@
package cn.celess.blog.util;
import javax.servlet.http.HttpServletRequest;
/**
* @Author: 小海
* @Date: 2019/10/18 15:44
* @Description:
*/
public class RequestUtil {
public static String getCompleteUrlAndMethod(HttpServletRequest request) {
// like this : /articles?page=1&count=5:GET
return request.getRequestURI() +
(request.getQueryString() == null ? "" : "?" + request.getQueryString()) +
":" + request.getMethod();
}
}

View File

@@ -0,0 +1,59 @@
package cn.celess.blog.util;
import cn.celess.blog.enmu.ResponseEnum;
import cn.celess.blog.entity.Response;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @author : xiaohai
* @date : 2019/03/28 15:32
*/
@ResponseBody
public class ResponseUtil {
/**
* 成功相应
*
* @param result 结果
* @return
*/
public static Response success(Object result) {
Response response = new Response();
response.setCode(ResponseEnum.SUCCESS.getCode());
response.setMsg(ResponseEnum.SUCCESS.getMsg());
response.setDate(System.currentTimeMillis());
response.setResult(result);
return response;
}
/**
* 失败的响应
*
* @param result 结果
* @return
*/
public static Response failure(String result) {
Response response = new Response();
response.setCode(ResponseEnum.FAILURE.getCode());
response.setMsg(ResponseEnum.FAILURE.getMsg());
response.setDate(System.currentTimeMillis());
response.setResult(result);
return response;
}
/**
* 其他的响应
*
* @param r 枚举常量
* @param result 结果
* @return
*/
public static Response response(ResponseEnum r, String result) {
Response response = new Response();
response.setCode(r.getCode());
response.setMsg(r.getMsg());
response.setDate(System.currentTimeMillis());
response.setResult(result);
return response;
}
}

View File

@@ -0,0 +1,109 @@
package cn.celess.blog.util;
import cn.celess.blog.entity.Article;
import cn.celess.blog.mapper.ArticleMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author: 小海
* @Date 2019/07/30 17:29
* @Description
*/
@Component
public class SitemapGenerateUtil {
@Value("${sitemap.path}")
private String path;
private Map<String, String> urlList;
@Autowired
ArticleMapper articleMapper;
@Async
public void createSitemap() {
initList();
File file = new File(path);
try {
if (file.exists()) {
file.delete();
} else {
file.createNewFile();
}
} catch (IOException e) {
e.printStackTrace();
}
DocumentBuilder db = getDocumentBuilder();
Document document = db.newDocument();
document.setXmlVersion("1.0");
document.setXmlStandalone(true);
Element urlset = document.createElement("urlset");
urlset.setAttribute("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9");
// 创建url 结点
urlList.forEach((s, s2) -> {
Element url = document.createElement("url");
Element loc = document.createElement("loc");
Element lastmod = document.createElement("lastmod");
loc.setTextContent(s);
lastmod.setTextContent(s2);
url.appendChild(loc);
url.appendChild(lastmod);
urlset.appendChild(url);
});
document.appendChild(urlset);
try {
TransformerFactory tff = TransformerFactory.newInstance();
Transformer tf = tff.newTransformer();
tf.setOutputProperty(OutputKeys.INDENT, "yes");
tf.transform(new DOMSource(document), new StreamResult(file));
} catch (TransformerException e) {
e.printStackTrace();
}
}
private void initList() {
urlList = new HashMap<>();
urlList.put("https://www.celess.cn", DateFormatUtil.getForXmlDate(new Date()));
urlList.put("https://www.celess.cn/links", DateFormatUtil.getForXmlDate(new Date()));
urlList.put("https://www.celess.cn/leaveMsg", DateFormatUtil.getForXmlDate(new Date()));
List<Article> articles = articleMapper.findAll();
articles.forEach(article -> {
urlList.put("https://www.celess.cn/article/" + article.getId(), DateFormatUtil.getForXmlDate(
article.getUpdateDate() == null ? article.getPublishDate() : article.getUpdateDate()));
});
}
private static DocumentBuilder getDocumentBuilder() {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
try {
db = dbf.newDocumentBuilder();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
return db;
}
}

View File

@@ -0,0 +1,17 @@
package cn.celess.blog.util;
/**
* @author : xiaohai
* @date : 2019/03/28 17:21
*/
public class StringFromHtmlUtil {
public static String getString(String html) {
//从html中提取纯文本
//剔出<html>的标签
String txtcontent = html.replaceAll("</?[^>]+>", "");
//去除字符串中的空格,回车,换行符,制表符
txtcontent = txtcontent.replaceAll("<a>\\s*|\t|\r|\n</a>", "");
return txtcontent;
}
}

View File

@@ -0,0 +1,90 @@
package cn.celess.blog.util;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
/**
* @author : xiaohai
* @date : 2019/04/11 15:42
*/
public class VeriCodeUtil {
// 验证码字符集
private static final char[] chars = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
// 字符数量
private static final int SIZE = 4;
// 干扰线数量
private static final int LINES = 5;
// 宽度
private static final int WIDTH = 80;
// 高度
private static final int HEIGHT = 40;
// 字体大小
private static final int FONT_SIZE = 30;
/**
* 生成随机验证码及图片
* Object[0]:验证码字符串;
* Object[1]:验证码图片。
*/
public static Object[] createImage() {
StringBuffer sb = new StringBuffer();
// 1.创建空白图片
BufferedImage image = new BufferedImage(
WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
// 2.获取图片画笔
Graphics graphic = image.getGraphics();
// 3.设置画笔颜色
graphic.setColor(Color.LIGHT_GRAY);
// 4.绘制矩形背景
graphic.fillRect(0, 0, WIDTH, HEIGHT);
// 5.画随机字符
Random ran = new Random();
for (int i = 0; i < SIZE; i++) {
// 取随机字符索引
int n = ran.nextInt(chars.length);
// 设置随机颜色
graphic.setColor(getRandomColor());
// 设置字体大小
graphic.setFont(new Font(
null, Font.BOLD + Font.ITALIC, FONT_SIZE));
// 画字符
graphic.drawString(
chars[n] + "", i * WIDTH / SIZE, HEIGHT * 2 / 3);
// 记录字符
sb.append(chars[n]);
}
// 6.画干扰线
for (int i = 0; i < LINES; i++) {
// 设置随机颜色
graphic.setColor(getRandomColor());
// 随机画线
graphic.drawLine(ran.nextInt(WIDTH), ran.nextInt(HEIGHT),
ran.nextInt(WIDTH), ran.nextInt(HEIGHT));
}
// 7.返回验证码和图片
return new Object[]{sb.toString(), image};
}
/**
* 随机取色
*/
public static Color getRandomColor() {
Random ran = new Random();
Color color = new Color(ran.nextInt(256),
ran.nextInt(256), ran.nextInt(256));
return color;
}
}