工具类汇总
Utils:SqlSessionUtil
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class SqlSessionUtil {
private static SqlSessionFactory factory;
static {
//实例化工厂建造类
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//读取核心配置文件
try (InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml")) {
//创建工厂对象
factory = builder.build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 得到会话对象
*
* @return 会话对象 : 自动提交事务
*/
public static SqlSession getSession() {
return factory.openSession(true);
}
/**
* 得到会话对象
*
* @param isAutoCommit 是否自动提交事务
*/
public static SqlSession getSession(boolean isAutoCommit) {
return factory.openSession(isAutoCommit);
}
/*
* 提交事务并关闭session
* */
public static void commitAndClose(SqlSession session) {
if (session != null) {
session.commit();
session.close();
}
}
/*
* 回滚事务并关闭session
* */
public static void rollbackAndClose(SqlSession session) {
if (session != null) {
session.rollback();
session.close();
}
}
}
Utils:JDBC
/*
1.存放到util包
2.私有化构造方法
3.提供静态方法
*/
public class JDBCUtils {
//2.私有化构造方法
private JDBCUtils() {
}
// 3.提供静态方法
//3.1定义静态方法向外界提供连接对象
public static Connection getConnection() throws Exception {
//1.关联配置文件 getBundle("jdbc")函数的参数只能关联的文件名,不能含有后缀名
ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
//2.根据key获取value
//getString("url"); 该方法的参数url是配置文件中等号左边的key:
//url=jdbc:mysql://localhost:3306/day01_heima130
String url = bundle.getString("url");
//2.获取连接
//2.2连接mysql数据库的用户名
String user = bundle.getString("user");
//2.3连接mysql服务器的密码,这里书写你的mysql密码
String password = bundle.getString("password");
Connection conn = DriverManager.getConnection(url, user, password);
//返回给调用者conn对象
return conn;
}
//3.2定义静态方法释放资源
public static void release(ResultSet rs, Statement st, Connection conn) {
//6.释放资源
try {
if (rs != null) {//防止空指针异常
rs.close();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (st != null) {//防止空指针异常
st.close();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (conn != null) {//防止空指针异常
conn.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
jdbc.propertis
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/DatabaseName
jdbc.username=root
jdbc.password=root
Utils:CommonUtils
该工具类是对BeanUtils工具类的封装,用来将前端页面的数据封装到传递的实体类对象中。
import com.itheima.sh.pojo.User;
import org.apache.commons.beanutils.BeanUtils;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
public class CommonUtils {
/*
该方法用来将页面的数据封装到传递的实体类对象中
说明:
1.public static <T> :尖括号中的T表示在方法上定义泛型,属于自定义泛型方法,调用的时候确定具体类型
2.T populate:这里T表示方法的返回值类型,这里是使用泛型
3.Class<T> clazz:这个T表示参数中的类型,也是使用泛型
4.Class<T> clazz = User.class
5.HttpServletRequest request=request
*/
public static <T> T populate(Class<T> clazz, HttpServletRequest request) throws Exception {
//1.创建实体类对象
T obj = clazz.newInstance();
//2.获取页面所有请求数据
Map<String, String[]> map = request.getParameterMap();
//3.使用BeanUtils工具类封装数据
BeanUtils.populate(obj,map);
//4.返回对象
return obj;
}
}
Utils:AppJwtUtil
该工具类用来生成token令牌以及检查token令牌的有效性
import io.jsonwebtoken.*;
import sun.misc.BASE64Encoder;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.*;
public class AppJwtUtil {
// TOKEN的有效期一小时(S)
private static final int TOKEN_TIME_OUT = 3600;
// 密钥,不能泄露
private static final String TOKEN_ENCRY_KEY = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY";
/*
获取token方法 :
userId 是要存到token的用户信息, 如有需要可以添加更多
*/
public static String getToken(Integer userId){
Map<String, Object> claimMaps = new HashMap<>();
claimMaps.put("userId",userId);
long currentTime = System.currentTimeMillis();
return Jwts.builder()
.setId(UUID.randomUUID().toString()) //jwt编号:随机产生
.setIssuedAt(new Date(currentTime)) //签发时间
.setIssuer("heima") //签发者信息
.setExpiration(new Date(currentTime + TOKEN_TIME_OUT * 1000)) //过期时间戳
.addClaims(claimMaps) //自定义
.signWith(SignatureAlgorithm.HS256, generalKey()) //加密方式
.compact();
}
/**
* 获取token中的claims信息
*
* @param token
* @return
*/
private static Jws<Claims> getJws(String token) {
return Jwts.parser()
.setSigningKey(generalKey())
.parseClaimsJws(token);
}
/**
* 获取payload body信息(指的是tocken中Payload部分)
* @param token
* @return Claims 是Map
*/
public static Claims getClaimsBody(String token) {
try {
return getJws(token).getBody();
}catch (ExpiredJwtException e){
return null;
}
}
public static JwsHeader getClaimsHeader(String token) {
try {
return getJws(token).getHeader();
}catch (ExpiredJwtException e){
return null;
}
}
public static String getClaimsSignature(String token) {
try {
return getJws(token).getSignature();
}catch (ExpiredJwtException e){
return null;
}
}
/**
*
* 检查token
* 1. 检查tocken的完整性和有效期
* 2. 检查失败会报错
* 3. 检查成功返回tocken的playload内容
*/
public static Claims checkToken(String token) {
try {
Claims claims = getClaimsBody(token);
if(claims==null){
throw new RuntimeException("token解析失败");
}
return claims;
} catch (ExpiredJwtException ex) {
throw new RuntimeException("token已经失效");
}catch (Exception e){
throw new RuntimeException("token解析失败");
}
}
/**
* 由字符串生成加密key
*
* @return
*/
public static SecretKey generalKey() {
byte[] encodedKey = Base64.getEncoder().encode(TOKEN_ENCRY_KEY.getBytes());
/*
使用len的第一个len字节构造来自给定字节数组的key ,从offset开始。
构成密钥的字节是key[offset]和key[offset+len-1]之间的字节。
参数
key - 密钥的密钥材料。 将复制以offset开头的数组的第一个len字节,以防止后续修改。
offset - 密钥材料开始的 key中的偏移量。
len - 密钥材料的长度。
algorithm - 与给定密钥材料关联的密钥算法的名称。 AES是一种对称加密算法
*/
SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
return key;
}
//测试
public static void main(String[] args) {
String token = getToken(1);
/*
header: eyJhbGciOiJIUzI1NiJ9.
Payload:eyJqdGkiOiJlNzMxNjk5Mi0yYTk5LTQwOTAtYWMwOS01MGMzZjU5MGUyNGIiLCJpYXQiOjE2MjMyODU2ODYsImlzcyI6ImhlaW1hIiwiZXhwIjoxNjIzMjg5Mjg2LCJ1c2VySWQiOjF9.
Signature:+oIJ-xzz67xGG5Ft5D8XxRjlwIB37RYcsb-I-V6cC-7Y
*/
System.out.println(token);
Claims claims = checkToken(token);
byte[] xx = Base64.getUrlDecoder().decode("eyJhbGciOiJIUzI1NiJ9");
String s = new String(xx);
//{"alg":"HS256"}
System.out.println(s);
//对Payload进行解密
byte[] yy = Base64.getUrlDecoder().decode("eyJqdGkiOiJlNzMxNjk5Mi0yYTk5LTQwOTAtYWMwOS01MGMzZjU5MGUyNGIiLCJpYXQiOjE2MjMyODU2ODYsImlzcyI6ImhlaW1hIiwiZXhwIjoxNjIzMjg5Mjg2LCJ1c2VySWQiOjF9");
/*
{
"jti":"e7316992-2a99-4090-ac09-50c3f590e24b", //表示token的编号,这里使用UUID.randomUUID().toString()生成的
"iat":1623285686, //签发时间,new Date(currentTime) 表示当前系统时间
"iss":"heima", 签发人
"exp":1623289286, 过期时间
"userId":1 自定义的字段
}
*/
String s2 = new String(yy);
System.out.println(s2);
/* Object userId = claims.get("userId");
Object iat = claims.get("iat");
Object exp = claims.get("exp");
Object jti = claims.get("jti");
Object sub = claims.get("sub"); //没有定义的信息是获取不到的
System.out.println(jti);
System.out.println(userId);
System.out.println(iat);
System.out.println(exp);
System.out.println(sub);
JwsHeader header = getClaimsHeader(token);
String algorithm = header.getAlgorithm();
System.out.println(algorithm); // HS256
String claimsSignature = getClaimsSignature(token);
System.out.println(claimsSignature);*/
}
}
Utils:BaseController
用来转换json数据
import com.alibaba.fastjson.JSON;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
* FastJson
* */
public class BaseController {
public static void printResult(HttpServletResponse response, Object obj) throws IOException {
response.setContentType("application/json;charset=utf-8");
JSON.writeJSONString(response.getWriter(),obj);
}
public static <T> T parseJSON2Object(HttpServletRequest request, Class<T> tClass) throws IOException{
// 把json格式的表单数据直接转成T类型的对象
return JSON.parseObject(request.getInputStream(),tClass);
}
}
Util:JedisUtil
redis连接池
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.util.ResourceBundle;
public class JedisUtil {
private static JedisPool jedisPool;
static{
//1. 创建连接池
ResourceBundle bundle = ResourceBundle.getBundle("jedis");
String host = bundle.getString("host");
int maxTotal = Integer.parseInt(bundle.getString("maxTotal"));
int maxWaitMillis = Integer.parseInt(bundle.getString("maxWaitMillis"));
int port = Integer.parseInt(bundle.getString("port"));
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(maxTotal);//配置连接池最大连接数
config.setMaxWaitMillis(maxWaitMillis);//设置最长等待时间
jedisPool = new JedisPool(config, host, port);
}
public static Jedis getResource(){
//2. 从连接池中取出连接
Jedis jedis = jedisPool.getResource();
return jedis;
}
}
jedis.properties
maxTotal=10
maxWaitMillis=2000
host=127.0.0.1
port=6379
Util:MD5Utils
MD5加密
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Utils {
/**
* MD5加密
* @param str
* @return
*/
public final static String encode(String str) {
try {
//创建具有指定算法名称的摘要
MessageDigest md = MessageDigest.getInstance("MD5");
//使用指定的字节数组更新摘要
md.update(str.getBytes());
//进行哈希计算并返回一个字节数组
byte mdBytes[] = md.digest();
String hash = "";
//循环字节数组
for (int i = 0; i < mdBytes.length; i++) {
int temp;
//如果有小于0的字节,则转换为正数
if (mdBytes[i] < 0)
temp = 256 + mdBytes[i];
else
temp = mdBytes[i];
if (temp < 16)
hash += "0";
//将字节转换为16进制后,转换为字符串
hash += Integer.toString(temp, 16);
}
return hash;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
public static void main(String[] args) {
String encode = MD5Utils.encode("123");
System.out.println(encode);
}
}
Util:PageBean
分页工具
import java.util.List;
/*
分页bean,这里使用自定义泛型类,这样可以适合于其他类型不仅仅是User,例如Role(角色) Permission(权限)
*/
public class PageBean<T> {
//1.定义成员变量保存页码上的分页数据
private List<T> list;
//2.定义变量保存当前页码
private int curPage;
//3.定义成员变量保存每页显示条数
private int pageSize;
//4.定义成员变量保存总记录数
private int count;
//定义成员方法计算起始索引
public int getStartIndex(){
int startIndex=(curPage-1)*pageSize;
//返回起始索引
return startIndex;
}
//get set
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
public int getCurPage() {
return curPage;
}
public void setCurPage(int curPage) {
this.curPage = curPage;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
Filter:
处理乱码过滤器
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
对所有POST方法请求参数进行编码
*/
@WebFilter("/*")
public class EncodingFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
//如果是POST方法,就对汉字进行编码的操作
request.setCharacterEncoding("utf-8");
//处理响应乱码
response.setContentType("text/html;charset=utf-8");
chain.doFilter(request, response);
}
public void init(FilterConfig config) throws ServletException {
}
}
FIlter:
解决跨域同源策略限制问题拦截器
import com.itheima.case2.utils.AppJwtUtil;
import com.itheima.case2.utils.BaseController;
import com.itheima.case2.vo.Result;
import io.jsonwebtoken.Claims;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
//拦截所有
@WebFilter(urlPatterns = "/*")
public class LoginFilter implements Filter {
// 白名单 在名单上的路径不需要拦截
// 下面的 / 表示默认访问的页面
List<String> urlList = Arrays.asList(
"/",
"/loginServlet",
"*.html",
"*.js",
"*.css",
"*.png",
"*.jpg",
"/element-ui/*"
);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("登录过滤器 已经启动啦");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 设置允许跨域
setCros(response);
// 查看是否是需要放行的路径,如果是,则放行,如果不是检查用户tocken
boolean isExclude = isFilterExcludeRequest(request);
if (isExclude){
filterChain.doFilter(servletRequest,servletResponse);
return;
}
// 检查用户token
String token = request.getHeader("Authorization");
if(token == null || "".equals(token)){
BaseController.printResult(response,new Result(false,"token不存在!"));
return;
}
// 解析token
try {
Claims claims = AppJwtUtil.checkToken(token);
Integer id = (Integer)claims.get("userId");
System.out.println("用户id:" + id);
filterChain.doFilter(servletRequest,servletResponse);
return;
} catch (Exception e) {
BaseController.printResult(response,new Result(false,"token过期或无效!"));
}
}
//解决跨域同源策略限制问题
private void setCros(HttpServletResponse response) {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
//设置预检有效时间
response.setHeader("Access-Control-Max-Age", "3600");
//自定义Authorization请求头用于发送token
response.setHeader("Access-Control-Allow-Headers", "content-type,Authorization");
}
/**
* 判断是否是 过滤器直接放行的请求
* <br/>主要用于静态资源的放行
* @return
*/
public boolean isFilterExcludeRequest(HttpServletRequest request) {
if(null != urlList && urlList.size() > 0) {
String url = request.getRequestURI();
for (String ecludedUrl : urlList) {
if (ecludedUrl.startsWith("*.")) {
// 如果配置的是后缀匹配, 则把前面的*号干掉,然后用endWith来判断
if(url.endsWith(ecludedUrl.substring(1))){
return true;
}
} else if (ecludedUrl.endsWith("/*")) {
if(!ecludedUrl.startsWith("/")) {
// 前缀匹配,必须要是/开头
ecludedUrl = "/" + ecludedUrl;
}
// 如果配置是前缀匹配, 则把最后的*号干掉,然后startWith来判断
String prffixStr = request.getContextPath() + ecludedUrl.substring(0, ecludedUrl.length() - 1);
if(url.startsWith(prffixStr)) {
return true;
}
} else {
// 如果不是前缀匹配也不是后缀匹配,那就是全路径匹配
if(!ecludedUrl.startsWith("/")) {
// 全路径匹配,也必须要是/开头
ecludedUrl = "/" + ecludedUrl;
}
String targetUrl = request.getContextPath() + ecludedUrl;
if(url.equals(targetUrl)) {
return true;
}
}
}
}
return false;
}
@Override
public void destroy() {
}
}