java開發(fā)常用的工具以及配置類
今天接著上一篇博文,聊 java開發(fā)常用的工具以及配置類。
13 日期操作相關(guān)的java類。
比如在開發(fā)預(yù)約旅游 預(yù)約體檢 預(yù)約售票等相關(guān)和日期相關(guān)的業(yè)務(wù),需要獲取日期以及判斷是一周的哪一天等。
/**
* 日期操作工具類
*/
public class DateUtils {
/**
* 日期轉(zhuǎn)換- 字符串時間 轉(zhuǎn)換為Date類型時間;
*
* @param dateString 字符串時間
* @return Date類型信息
* @throws Exception 拋出異常
*/
public static Date parseString2Date(String dateString) throws Exception {
if (dateString == null) {
return null;
}
return parseString2Date(dateString, "yyyy-MM-dd");
}
/**
* 日期轉(zhuǎn)換- String -> Date 轉(zhuǎn)換為指定格式的時間類型;
*
* @param dateString 字符串時間
* @param pattern 格式模板
* @return Date類型信息
* @throws Exception 拋出異常
*/
public static Date parseString2Date(String dateString, String pattern) throws Exception {
if (dateString == null) {
return null;
}
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
Date date = sdf.parse(dateString);
return date;
}
/**
* 日期轉(zhuǎn)換 Date -> 字符串時間
* @param date Date類型信息
* @return 字符串時間
* @throws Exception 拋出異常
*/
public static String parseDate2String(Date date) throws Exception {
if (date == null) {
return null;
}
return parseDate2String(date, "yyyy-MM-dd");
}
/**
* 日期轉(zhuǎn)換 Date -> 字符串時間 指定格式;
*
* @param date Date類型信息
* @param pattern 格式模板
* @return 字符串時間
* @throws Exception 拋出異常
*/
public static String parseDate2String(Date date, String pattern) throws Exception {
if (date == null) {
return null;
}
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
String strDate = sdf.format(date);
return strDate;
}
/**
* 獲取當(dāng)前日期的本周一是幾號
* @return 本周一的日期
*/
public static Date getThisWeekMonday() {
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
// 獲得當(dāng)前日期是一個星期的第幾天
int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
if (1 == dayWeek) {
cal.add(Calendar.DAY_OF_MONTH, -1);
}
// 設(shè)置一個星期的第一天,一個星期的第一天是星期一
cal.setFirstDayOfWeek(Calendar.MONDAY);
// 獲得當(dāng)前日期是一個星期的第幾天
int day = cal.get(Calendar.DAY_OF_WEEK);
// 根據(jù)日歷的規(guī)則,給當(dāng)前日期減去星期幾與一個星期第一天的差值
cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
return cal.getTime();
}
/**
* 獲取當(dāng)前日期周的最后一天
* @return 當(dāng)前日期周的最后一天
*/
public static Date getSundayOfThisWeek() {
Calendar c = Calendar.getInstance();
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
if (dayOfWeek == 0) {
dayOfWeek = 7;
}
c.add(Calendar.DATE, -dayOfWeek + 7);
return c.getTime();
}
/**
* 根據(jù)日期區(qū)間獲取月份列表
* @param minDate 開始時間
* @param maxDate 結(jié)束時間
* @return 月份列表
* @throws Exception
*/
public static List<String> getMonthBetween(String minDate, String maxDate, String format) throws Exception {
ArrayList<String> result = new ArrayList<>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
Calendar min = Calendar.getInstance();
Calendar max = Calendar.getInstance();
min.setTime(sdf.parse(minDate));
min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);
max.setTime(sdf.parse(maxDate));
max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);
SimpleDateFormat sdf2 = new SimpleDateFormat(format);
Calendar curr = min;
while (curr.before(max)) {
result.add(sdf2.format(curr.getTime()));
curr.add(Calendar.MONTH, 1);
}
return result;
}
/**
* 根據(jù)日期獲取年度中的周索引
* @param date 日期
* @return 周索引
* @throws Exception
*/
public static Integer getWeekOfYear(String date) throws Exception {
Date useDate = parseString2Date(date);
Calendar cal = Calendar.getInstance();
cal.setTime(useDate);
return cal.get(Calendar.WEEK_OF_YEAR);
}
/**
* 根據(jù)年份獲取年中周列表
* @param year 年分
* @return 周列表
* @throws Exception
*/
public static Map<Integer, String> getWeeksOfYear(String year) throws Exception {
Date useDate = parseString2Date(year, "yyyy");
Calendar cal = Calendar.getInstance();
cal.setTime(useDate);
//獲取年中周數(shù)量
int weeksCount = cal.getWeeksInWeekYear();
Map<Integer, String> mapWeeks = new HashMap<>(55);
for (int i = 0; i < weeksCount; i++) {
cal.get(Calendar.DAY_OF_YEAR);
mapWeeks.put(i + 1, parseDate2String(getFirstDayOfWeek(cal.get(Calendar.YEAR), i)));
}
return mapWeeks;
}
/**
* 獲取某年的第幾周的開始日期
* @param year 年分
* @param week 周索引
* @return 開始日期
* @throws Exception
*/
public static Date getFirstDayOfWeek(int year, int week) throws Exception {
Calendar c = new GregorianCalendar();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, Calendar.JANUARY);
c.set(Calendar.DATE, 1);
Calendar cal = (GregorianCalendar) c.clone();
cal.add(Calendar.DATE, week * 7);
return getFirstDayOfWeek(cal.getTime());
}
/**
* 獲取某年的第幾周的結(jié)束日期
* @param year 年份
* @param week 周索引
* @return 結(jié)束日期
* @throws Exception
*/
public static Date getLastDayOfWeek(int year, int week) throws Exception {
Calendar c = new GregorianCalendar();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, Calendar.JANUARY);
c.set(Calendar.DATE, 1);
Calendar cal = (GregorianCalendar) c.clone();
cal.add(Calendar.DATE, week * 7);
return getLastDayOfWeek(cal.getTime());
}
/**
* 獲取當(dāng)前時間所在周的開始日期
* @param date 當(dāng)前時間
* @return 開始時間
*/
public static Date getFirstDayOfWeek(Date date) {
Calendar c = new GregorianCalendar();
c.setFirstDayOfWeek(Calendar.SUNDAY);
c.setTime(date);
c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
return c.getTime();
}
/**
* 獲取當(dāng)前時間所在周的結(jié)束日期
* @param date 當(dāng)前時間
* @return 結(jié)束日期
*/
public static Date getLastDayOfWeek(Date date) {
Calendar c = new GregorianCalendar();
c.setFirstDayOfWeek(Calendar.SUNDAY);
c.setTime(date);
c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 6);
return c.getTime();
}
//獲得上周一的日期
public static Date geLastWeekMonday(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(getThisWeekMonday(date));
cal.add(Calendar.DATE, -7);
return cal.getTime();
}
//獲得本周一的日期
public static Date getThisWeekMonday(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
// 獲得當(dāng)前日期是一個星期的第幾天
int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
if (1 == dayWeek) {
cal.add(Calendar.DAY_OF_MONTH, -1);
}
// 設(shè)置一個星期的第一天,一個星期的第一天是星期一
cal.setFirstDayOfWeek(Calendar.MONDAY);
// 獲得當(dāng)前日期是一個星期的第幾天
int day = cal.get(Calendar.DAY_OF_WEEK);
// 根據(jù)日歷的規(guī)則,給當(dāng)前日期減去星期幾與一個星期第一天的差值
cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
return cal.getTime();
}
//獲得下周一的日期
public static Date getNextWeekMonday(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(getThisWeekMonday(date));
cal.add(Calendar.DATE, 7);
return cal.getTime();
}
// 獲得今天日期
public static Date getToday(){
return new Date();
}
// 獲得本月一日的日期
public static Date getFirstDay4ThisMonth(){
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_MONTH,1);
return calendar.getTime();
}
//獲得本月最后一日的日期
public static Date getLastDay4ThisMonth(){
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MONTH, 1);
calendar.set(Calendar.DAY_OF_MONTH, 0);
return calendar.getTime();
}
/**
* 獲取指定月份的最后一天
* @param yearMonth
* @return
*/
public static String getLastDayOfMonth(String yearMonth) {
int year = Integer.parseInt(yearMonth.split("-")[0]); //年
int month = Integer.parseInt(yearMonth.split("-")[1]); //月
Calendar cal = Calendar.getInstance();
// 設(shè)置年份
cal.set(Calendar.YEAR, year);
// 設(shè)置月份
// cal.set(Calendar.MONTH, month - 1);
cal.set(Calendar.MONTH, month); //設(shè)置當(dāng)前月的上一個月
// 獲取某月最大天數(shù)
//int lastDay = cal.getActualMaximum(Calendar.DATE);
int lastDay = cal.getMinimum(Calendar.DATE); //獲取月份中的最小值,即第一天
// 設(shè)置日歷中月份的最大天數(shù)
//cal.set(Calendar.DAY_OF_MONTH, lastDay);
cal.set(Calendar.DAY_OF_MONTH, lastDay - 1); //上月的第一天減去1就是當(dāng)月的最后一天
// 格式化日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(cal.getTime());
}
}
14 處理請求路徑的URL工具類
比如,有時需要根據(jù)傳入的路徑url獲取請求參數(shù)或者參數(shù)值,再進行下一步業(yè)務(wù)。
public class UrlUtil {
/**
* 獲取請求地址中的某個參數(shù)
* @param url
* @param name
* @return
*/
public static String getParam(String url, String name) {
return urlSplit(url).get(name);
}
/**
* 去掉url中的路徑,留下請求參數(shù)部分
* @param url url地址
* @return url請求參數(shù)部分
*/
private static String truncateUrlPage(String url) {
String strAllParam = null;
String[] arrSplit = null;
url = url.trim();
arrSplit = url.split("[?]");
if (url.length() > 1) {
if (arrSplit.length > 1) {
for (int i = 1; i < arrSplit.length; i++) {
strAllParam = arrSplit[i];
}
}
}
return strAllParam;
}
/**
* 將參數(shù)存入map集合
* @param url url地址
* @return url請求參數(shù)部分存入map集合
*/
public static Map<String, String> urlSplit(String url) {
Map<String, String> mapRequest = new HashMap<String, String>();
String[] arrSplit = null;
String strUrlParam = truncateUrlPage(url);
if (strUrlParam == null) {
return mapRequest;
}
arrSplit = strUrlParam.split("[&]");
for (String strSplit : arrSplit) {
String[] arrSplitEqual = null;
arrSplitEqual = strSplit.split("[=]");
//解析出鍵值
if (arrSplitEqual.length > 1) {
//正確解析
mapRequest.put(arrSplitEqual[0], strSplit.substring(arrSplitEqual[0].length()+1));
} else {
if (arrSplitEqual[0] != "") {
//只有參數(shù)沒有值,不加入
mapRequest.put(arrSplitEqual[0], "");
}
}
}
return mapRequest;
}
public static void main(String[] args) {
String param = getParam("http://www.baidu.com/#/liveInfo/4?recommend=1", "recommend");
System.out.println(param); // 1
String s = truncateUrlPage("http://www.baidu.com/#/liveInfo/4?recommend=1");
System.out.println(s); // recommend=1
}
}
測試中一個方法獲取參數(shù)的值,一個方法將參數(shù)和值取出來。
15 生成訂單號 (根據(jù)時間戳和3位隨機數(shù)生成訂單號)
public class OrderNoUtils {
/**
* 獲取訂單號
* @return
*/
public static String getOrderNo() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String newDate = sdf.format(new Date());
String result = "";
Random random = new Random();
for (int i = 0; i < 3; i++) {
result += random.nextInt(10);
}
return newDate + result;
}
public static void main(String[] args) {
String orderNo = getOrderNo();
System.out.println(orderNo); // 20230610210349887
}
}
測試中,生成的訂單號為20230610210349887,前14位為20230610210349,根據(jù)我們指定的時間戳生成。后3位是生成的隨機數(shù)。
16 攔截器配置
對不同的url進行攔截配置,比如,帶/api/是前臺系統(tǒng)的路由,帶/admin/是后臺系統(tǒng)的路由。因此,需要進行攔截處理。
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Bean
LoginInterceptor loginInterceptor(){
return new LoginInterceptor();
}
@Bean
CrossInterceptor crossInterceptor(){
return new CrossInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
/**
* 攔截全部路徑,這個跨域需要放在最上面
*/
registry.addInterceptor(crossInterceptor()).addPathPatterns("/**");
//攔截全部
registry.addInterceptor(loginInterceptor()).addPathPatterns("/api/*/*/**","/admin/*/**")
//不攔截哪些路徑 斜杠一定要加
.excludePathPatterns("/api/user/login","/api/user/register");
WebMvcConfigurer.super.addInterceptors(registry);
}
}
//跨域;
public class CrossInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//表示接受任意域名的請求,也可以指定域名
response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin"));
//該字段可選,是個布爾值,表示是否可以攜帶cookie
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "*");
/**
* 非簡單請求是對那種對服務(wù)器有特殊要求的請求,
* 比如請求方式是PUT或者DELETE,或者Content-Type字段類型是application/json。
* 都會在正式通信之前,增加一次HTTP請求,稱之為預(yù)檢。瀏覽器會先詢問服務(wù)器,當(dāng)前網(wǎng)頁所在域名是否在服務(wù)器的許可名單之中,
* 服務(wù)器允許之后,瀏覽器會發(fā)出正式的XMLHttpRequest請求
*/
if(HttpMethod.OPTIONS.toString().equals(request.getMethod())){
return true;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
// 登錄攔截器;
public class LoginInterceptor implements HandlerInterceptor {
/**
* 進入到controller之前的方法;
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
try{
String accessToken = request.getHeader("token"); //從請求頭獲取token; 因為 一般將jwt生成的token放在請求頭中
if(accessToken == null){
accessToken = request.getParameter("token"); //從請求參數(shù)獲取token;
}
// token不為空;進行校驗;
if(StringUtils.isNotBlank(accessToken)) {
Claims claims = JWTUtils.checkJWT(accessToken);
// claims為空,token錯誤或者token過期;
if (claims == null) {
// 重新登陸;
sendJsonMessage(response, JsonData.buildError("重新登陸"));
return false;
}
Integer id = (Integer) claims.get("id"); //拿到用戶id;
String name = (String) claims.get("name"); //拿到用戶昵稱;
request.setAttribute("user_id", id);
request.setAttribute("name", name);
return true;
}
}catch (Exception e){
e.printStackTrace();
}
return false;
}
/**
* 響應(yīng)json數(shù)據(jù)給前端;
* @param response
* @param object
*/
public static void sendJsonMessage(HttpServletResponse response,Object object){
try{
ObjectMapper objectMapper = new ObjectMapper();
response.setContentType("application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print(objectMapper.writeValueAsString(object));
writer.close();
response.flushBuffer();
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
帶有/api/ 和/admin/都攔截,不過用戶登錄和用戶注冊不用攔截。上面同時給出了跨域的解決配置,在前面的博文在網(wǎng)關(guān)微服務(wù)里面提到過跨域配置,如果網(wǎng)關(guān)沒有配置跨域,那么需要單獨配置跨域。文章來源:http://www.zghlxwxcb.cn/news/detail-479038.html
在 LoginInterceptor類的preHandle方法中,不一定如案例所示。大致的邏輯是,從請求頭獲取jwt生成的token字符串,然后判斷token字符串是否過期或者為空,如果token出錯或者為空,則需要重新登錄。頁面跳轉(zhuǎn)到登錄頁面。
不過在開發(fā),使用到了網(wǎng)關(guān),那么跨域和攔截路由都將在網(wǎng)關(guān)中配置。文章來源地址http://www.zghlxwxcb.cn/news/detail-479038.html
到了這里,關(guān)于java開發(fā)常用的工具以及配置類的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!