时间
//java获取本月开始时间和结束时间、上个月第一天和最后一天的时间以及当前日期往前推一周、一个月
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import org.junit.Test;
public class TestDateUtil {
//1、获取当月第一天
@Test
public void testForDate(){
//规定返回日期格式
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd");
Calendar calendar=Calendar.getInstance();
Date theDate=calendar.getTime();
GregorianCalendar gcLast=(GregorianCalendar)Calendar.getInstance();
gcLast.setTime(theDate);
//设置为第一天
gcLast.set(Calendar.DAY_OF_MONTH, 1);
String day_first=sf.format(gcLast.getTime());
//打印本月第一天
System.out.println(day_first);
}
//2、获取当月最后一天
@Test
public void testForDatelast(){
//获取Calendar
Calendar calendar=Calendar.getInstance();
//设置日期为本月最大日期
calendar.set(Calendar.DATE, calendar.getActualMaximum(calendar.DATE));
//设置日期格式
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd");
String ss=sf.format(calendar.getTime());
System.out.println(ss+" 23:59:59");
}
//3、非常简单和实用的获取本月第一天和最后一天
@Test
public void testt(){
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
Calendar c = Calendar.getInstance();
c.add(Calendar.MONTH, 0);
c.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天
String first = format.format(c.getTime());
System.out.println("===============本月first day:"+first);
//获取当前月最后一天
Calendar ca = Calendar.getInstance();
ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
String last = format.format(ca.getTime());
System.out.println("===============本月last day:"+last);
}
//4、获取上个月的第一天
@Test
public void getBeforeFirstMonthdate()throws Exception{
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
Calendar calendar=Calendar.getInstance();
calendar.add(Calendar.MONTH, -1);
calendar.set(Calendar.DAY_OF_MONTH, 1);
System.out.println("上个月第一天:"+format.format(calendar.getTime()));
}
//5、获取上个月的最后一天
@Test
public void getBeforeLastMonthdate()throws Exception{
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd");
Calendar calendar=Calendar.getInstance();
int month=calendar.get(Calendar.MONTH);
calendar.set(Calendar.MONTH, month-1);
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
System.out.println("上个月最后一天:"+sf.format(calendar.getTime()));
}
6、获取当前日期的前一周或者前一个月时间
public static String getFirstDate(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
Calendar cl = Calendar.getInstance();
// cl.setTime(dateNow);
// cl.add(Calendar.DAY_OF_YEAR, -1);
//一天
// cl.add(Calendar.WEEK_OF_YEAR, -1);
//一周
cl.add(Calendar.MONTH, -1);
//从现在算,之前一个月,如果是2个月,那么-1-----》改为-2
Date dateFrom = cl.getTime();
return sdf.format(dateFrom);
}
@Test
public void testStartDate(){
System.out.println("当前日期往前推一个月是:"+getFirstDate());
//如果当前日期是2015.11.08,那么打印日期是:20151008
}
}
java获取当天,前天,明天,本周,本月,本年的开始日期时间和结束日期时间
import java.sql.Timestamp;
4 import java.text.ParseException;
5 import java.text.SimpleDateFormat;
6 import java.util.ArrayList;
7 import java.util.Calendar;
8 import java.util.Date;
9 import java.util.GregorianCalendar;
10 import java.util.List;
11
12 public class DateUtils {
13 //获取当天的开始时间
14 public static java.util.Date getDayBegin() {
15 Calendar cal = new GregorianCalendar();
16 cal.set(Calendar.HOUR_OF_DAY, 0);
17 cal.set(Calendar.MINUTE, 0);
18 cal.set(Calendar.SECOND, 0);
19 cal.set(Calendar.MILLISECOND, 0);
20 return cal.getTime();
21 }
22 //获取当天的结束时间
23 public static java.util.Date getDayEnd() {
24 Calendar cal = new GregorianCalendar();
25 cal.set(Calendar.HOUR_OF_DAY, 23);
26 cal.set(Calendar.MINUTE, 59);
27 cal.set(Calendar.SECOND, 59);
28 return cal.getTime();
29 }
30 //获取昨天的开始时间
31 public static Date getBeginDayOfYesterday() {
32 Calendar cal = new GregorianCalendar();
33 cal.setTime(getDayBegin());
34 cal.add(Calendar.DAY_OF_MONTH, -1);
35 return cal.getTime();
36 }
37 //获取昨天的结束时间
38 public static Date getEndDayOfYesterDay() {
39 Calendar cal = new GregorianCalendar();
40 cal.setTime(getDayEnd());
41 cal.add(Calendar.DAY_OF_MONTH, -1);
42 return cal.getTime();
43 }
44 //获取明天的开始时间
45 public static Date getBeginDayOfTomorrow() {
46 Calendar cal = new GregorianCalendar();
47 cal.setTime(getDayBegin());
48 cal.add(Calendar.DAY_OF_MONTH, 1);
49
50 return cal.getTime();
51 }
52 //获取明天的结束时间
53 public static Date getEndDayOfTomorrow() {
54 Calendar cal = new GregorianCalendar();
55 cal.setTime(getDayEnd());
56 cal.add(Calendar.DAY_OF_MONTH, 1);
57 return cal.getTime();
58 }
59 //获取本周的开始时间
60 public static Date getBeginDayOfWeek() {
61 Date date = new Date();
62 if (date == null) {
63 return null;
64 }
65 Calendar cal = Calendar.getInstance();
66 cal.setTime(date);
67 int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
68 if (dayofweek == 1) {
69 dayofweek += 7;
70 }
71 cal.add(Calendar.DATE, 2 - dayofweek);
72 return getDayStartTime(cal.getTime());
73 }
74 //获取本周的结束时间
75 public static Date getEndDayOfWeek(){
76 Calendar cal = Calendar.getInstance();
77 cal.setTime(getBeginDayOfWeek());
78 cal.add(Calendar.DAY_OF_WEEK, 6);
79 Date weekEndSta = cal.getTime();
80 return getDayEndTime(weekEndSta);
81 }
82 //获取本月的开始时间
83 public static Date getBeginDayOfMonth() {
84 Calendar calendar = Calendar.getInstance();
85 calendar.set(getNowYear(), getNowMonth() - 1, 1);
86 return getDayStartTime(calendar.getTime());
87 }
88 //获取本月的结束时间
89 public static Date getEndDayOfMonth() {
90 Calendar calendar = Calendar.getInstance();
91 calendar.set(getNowYear(), getNowMonth() - 1, 1);
92 int day = calendar.getActualMaximum(5);
93 calendar.set(getNowYear(), getNowMonth() - 1, day);
94 return getDayEndTime(calendar.getTime());
95 }
96 //获取本年的开始时间
97 public static java.util.Date getBeginDayOfYear() {
98 Calendar cal = Calendar.getInstance();
99 cal.set(Calendar.YEAR, getNowYear());
100 // cal.set
101 cal.set(Calendar.MONTH, Calendar.JANUARY);
102 cal.set(Calendar.DATE, 1);
103
104 return getDayStartTime(cal.getTime());
105 }
106 //获取本年的结束时间
107 public static java.util.Date getEndDayOfYear() {
108 Calendar cal = Calendar.getInstance();
109 cal.set(Calendar.YEAR, getNowYear());
110 cal.set(Calendar.MONTH, Calendar.DECEMBER);
111 cal.set(Calendar.DATE, 31);
112 return getDayEndTime(cal.getTime());
113 }
114 //获取某个日期的开始时间
115 public static Timestamp getDayStartTime(Date d) {
116 Calendar calendar = Calendar.getInstance();
117 if(null != d) calendar.setTime(d);
118 calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
119 calendar.set(Calendar.MILLISECOND, 0);
120 return new Timestamp(calendar.getTimeInMillis());
121 }
122 //获取某个日期的结束时间
123 public static Timestamp getDayEndTime(Date d) {
124 Calendar calendar = Calendar.getInstance();
125 if(null != d) calendar.setTime(d);
126 calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
127 calendar.set(Calendar.MILLISECOND, 999);
128 return new Timestamp(calendar.getTimeInMillis());
129 }
130 //获取今年是哪一年
131 public static Integer getNowYear() {
132 Date date = new Date();
133 GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
134 gc.setTime(date);
135 return Integer.valueOf(gc.get(1));
136 }
137 //获取本月是哪一月
138 public static int getNowMonth() {
139 Date date = new Date();
140 GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
141 gc.setTime(date);
142 return gc.get(2) + 1;
143 }
144 //两个日期相减得到的天数
145 public static int getDiffDays(Date beginDate, Date endDate) {
146
147 if (beginDate == null || endDate == null) {
148 throw new IllegalArgumentException("getDiffDays param is null!");
149 }
150
151 long diff = (endDate.getTime() - beginDate.getTime())
152 / (1000 * 60 * 60 * 24);
153
154 int days = new Long(diff).intValue();
155
156 return days;
157 }
158 //两个日期相减得到的毫秒数
159 public static long dateDiff(Date beginDate, Date endDate) {
160 long date1ms = beginDate.getTime();
161 long date2ms = endDate.getTime();
162 return date2ms - date1ms;
163 }
164 //获取两个日期中的最大日期
165 public static Date max(Date beginDate, Date endDate) {
166 if (beginDate == null) {
167 return endDate;
168 }
169 if (endDate == null) {
170 return beginDate;
171 }
172 if (beginDate.after(endDate)) {
173 return beginDate;
174 }
175 return endDate;
176 }
177 //获取两个日期中的最小日期
178 public static Date min(Date beginDate, Date endDate) {
179 if (beginDate == null) {
180 return endDate;
181 }
182 if (endDate == null) {
183 return beginDate;
184 }
185 if (beginDate.after(endDate)) {
186 return endDate;
187 }
188 return beginDate;
189 }
190 //返回某月该季度的第一个月
191 public static Date getFirstSeasonDate(Date date) {
192 final int[] SEASON = { 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4 };
193 Calendar cal = Calendar.getInstance();
194 cal.setTime(date);
195 int sean = SEASON[cal.get(Calendar.MONTH)];
196 cal.set(Calendar.MONTH, sean * 3 - 3);
197 return cal.getTime();
198 }
199 //返回某个日期下几天的日期
200 public static Date getNextDay(Date date, int i) {
201 Calendar cal = new GregorianCalendar();
202 cal.setTime(date);
203 cal.set(Calendar.DATE, cal.get(Calendar.DATE) + i);
204 return cal.getTime();
205 }
206 //返回某个日期前几天的日期
207 public static Date getFrontDay(Date date, int i) {
208 Calendar cal = new GregorianCalendar();
209 cal.setTime(date);
210 cal.set(Calendar.DATE, cal.get(Calendar.DATE) - i);
211 return cal.getTime();
212 }
213 //获取某年某月到某年某月按天的切片日期集合(间隔天数的日期集合)
214 public static List getTimeList(int beginYear, int beginMonth, int endYear,
215 int endMonth, int k) {
216 List list = new ArrayList();
217 if (beginYear == endYear) {
218 for (int j = beginMonth; j <= endMonth; j++) {
219 list.add(getTimeList(beginYear, j, k));
220
221 }
222 } else {
223 {
224 for (int j = beginMonth; j < 12; j++) {
225 list.add(getTimeList(beginYear, j, k));
226 }
227
228 for (int i = beginYear + 1; i < endYear; i++) {
229 for (int j = 0; j < 12; j++) {
230 list.add(getTimeList(i, j, k));
231 }
232 }
233 for (int j = 0; j <= endMonth; j++) {
234 list.add(getTimeList(endYear, j, k));
235 }
236 }
237 }
238 return list;
239 }
240 //获取某年某月按天切片日期集合(某个月间隔多少天的日期集合)
241 public static List getTimeList(int beginYear, int beginMonth, int k) {
242 List list = new ArrayList();
243 Calendar begincal = new GregorianCalendar(beginYear, beginMonth, 1);
244 int max = begincal.getActualMaximum(Calendar.DATE);
245 for (int i = 1; i < max; i = i + k) {
246 list.add(begincal.getTime());
247 begincal.add(Calendar.DATE, k);
248 }
249 begincal = new GregorianCalendar(beginYear, beginMonth, max);
250 list.add(begincal.getTime());
251 return list;
252 }
253 }
复制代码
复制代码
1 //获取某年某月的第一天日期
2 public static Date getStartMonthDate(int year, int month) {
3 Calendar calendar = Calendar.getInstance();
4 calendar.set(year, month - 1, 1);
5 return calendar.getTime();
6 }
7
8 //获取某年某月的最后一天日期
9 public static Date getEndMonthDate(int year, int month) {
10 Calendar calendar = Calendar.getInstance();
11 calendar.set(year, month - 1, 1);
12 int day = calendar.getActualMaximum(5);
13 calendar.set(year, month - 1, day);
14 return calendar.getTime();
15 }
根据当前日期获得所在周的日期区间(周一和周日日期)
public String getTimeInterval(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
// 判断要计算的日期是否是周日,如果是则减一天计算周六的,否则会出问题,计算到下一周去了
int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
if (1 == dayWeek) {
cal.add(Calendar.DAY_OF_MONTH, -1);
}
// System.out.println("要计算日期为:" + sdf.format(cal.getTime())); // 输出要计算日期
// 设置一个星期的第一天,按中国的习惯一个星期的第一天是星期一
cal.setFirstDayOfWeek(Calendar.MONDAY);
// 获得当前日期是一个星期的第几天
int day = cal.get(Calendar.DAY_OF_WEEK);
// 根据日历的规则,给当前日期减去星期几与一个星期第一天的差值
cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
String imptimeBegin = sdf.format(cal.getTime());
// System.out.println("所在周星期一的日期:" + imptimeBegin);
cal.add(Calendar.DATE, 6);
String imptimeEnd = sdf.format(cal.getTime());
// System.out.println("所在周星期日的日期:" + imptimeEnd);
return imptimeBegin + "," + imptimeEnd;
}
根据当前日期获得上周的日期区间(上周周一和周日日期)
public String getLastTimeInterval() {
Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
int dayOfWeek = calendar1.get(Calendar.DAY_OF_WEEK) - 1;
int offset1 = 1 - dayOfWeek;
int offset2 = 7 - dayOfWeek;
calendar1.add(Calendar.DATE, offset1 - 7);
calendar2.add(Calendar.DATE, offset2 - 7);
// System.out.println(sdf.format(calendar1.getTime()));// last Monday
String lastBeginDate = sdf.format(calendar1.getTime());
// System.out.println(sdf.format(calendar2.getTime()));// last Sunday
String lastEndDate = sdf.format(calendar2.getTime());
return lastBeginDate + "," + lastEndDate;
}
获取一周开始到结束的list集合
public static List<Date> findDates(Date dBegin, Date dEnd)
{
List lDate = new ArrayList();
lDate.add(dBegin);
Calendar calBegin = Calendar.getInstance();
// 使用给定的 Date 设置此 Calendar 的时间
calBegin.setTime(dBegin);
Calendar calEnd = Calendar.getInstance();
// 使用给定的 Date 设置此 Calendar 的时间
calEnd.setTime(dEnd);
// 测试此日期是否在指定日期之后
while (dEnd.after(calBegin.getTime()))
{
// 根据日历的规则,为给定的日历字段添加或减去指定的时间量
calBegin.add(Calendar.DAY_OF_MONTH, 1);
lDate.add(calBegin.getTime());
}
return lDate;
}
Calendar cal = Calendar.getInstance();
cal.add(cal.DATE, time);
cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 8, 0, 0);
Date beginOfDate = cal.getTime();
SimpleDateFormat formatter = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
return formatter.format(beginOfDate);
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.math.NumberUtils;
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
public DateUtils() {
}
public static Date firstDayOfThisWeek() {
return firstDayOfWeek(new Date());
}
public static Date lastDayOfThisWeek() {
return lastDayOfWeek(new Date());
}
public static Date firstDayOfLastWeek() {
return firstDayOfPreWeek(1);
}
public static Date firstDayOfPreWeek(Integer num) {
LocalDateTime last = LocalDateTime.now().plusWeeks((long)(-1 * num));
return firstDayOfWeek(Date.from(last.atZone(ZoneId.systemDefault()).toInstant()));
}
public static Date lastDayOfLastWeek() {
LocalDateTime last = LocalDateTime.now().plusWeeks(-1L);
return lastDayOfWeek(Date.from(last.atZone(ZoneId.systemDefault()).toInstant()));
}
public static Date firstDayOfNextWeek() {
LocalDateTime next = LocalDateTime.now().plusWeeks(1L);
return firstDayOfWeek(Date.from(next.atZone(ZoneId.systemDefault()).toInstant()));
}
public static Date lastDayOfNextWeek() {
LocalDateTime next = LocalDateTime.now().plusWeeks(1L);
return lastDayOfWeek(Date.from(next.atZone(ZoneId.systemDefault()).toInstant()));
}
public static Date firstDayOfThisMonth() {
return firstDayOfMonth(new Date());
}
public static Date lastDayOfThisMonth() {
return lastDayOfMonth(new Date());
}
public static Date firstDayOfLastMonth() {
return firstDayOfPreMonth(1);
}
public static Date firstDayOfPreMonth(Integer num) {
LocalDateTime last = LocalDateTime.now().plusMonths((long)(-1 * num));
return firstDayOfMonth(Date.from(last.atZone(ZoneId.systemDefault()).toInstant()));
}
public static Date lastDayOfLastMonth() {
LocalDateTime last = LocalDateTime.now().plusMonths(-1L);
return lastDayOfMonth(Date.from(last.atZone(ZoneId.systemDefault()).toInstant()));
}
public static Date firstDayOfNextMonth() {
LocalDateTime last = LocalDateTime.now().plusMonths(1L);
return firstDayOfMonth(Date.from(last.atZone(ZoneId.systemDefault()).toInstant()));
}
public static Date lastDayOfNextMonth() {
LocalDateTime last = LocalDateTime.now().plusMonths(1L);
return lastDayOfMonth(Date.from(last.atZone(ZoneId.systemDefault()).toInstant()));
}
public static Date firstDayOfMonth(Date date) {
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
LocalDateTime dateTime = localDateTime.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
return Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
}
public static Date lastDayOfMonth(Date date) {
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
LocalDateTime dateTime = localDateTime.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
return Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
}
public static Date firstDayOfWeek(Date date) {
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
LocalDateTime dateTime = localDateTime.with(DayOfWeek.MONDAY).with(LocalTime.MIN);
return Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
}
public static Date lastDayOfWeek(Date date) {
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
LocalDateTime dateTime = localDateTime.with(DayOfWeek.SUNDAY).with(LocalTime.MAX);
return Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
}
public static int getWeekDay(Date date) {
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
return localDateTime.getDayOfWeek().getValue();
}
public static Date getYesterdayZeroTime() {
return getZeroTime(NumberUtils.INTEGER_MINUS_ONE);
}
public static Date getPredayZeroTime(Integer num) {
return getZeroTime(NumberUtils.INTEGER_MINUS_ONE * num);
}
public static Date getYesterdayEndTime() {
return getEndTime(NumberUtils.INTEGER_MINUS_ONE);
}
public static Date getTodayZeroTime() {
return getZeroTime(NumberUtils.INTEGER_ZERO);
}
public static Date getTodayEndTime() {
return getEndTime(NumberUtils.INTEGER_ZERO);
}
public static Date getZeroTime(Integer days) {
LocalDateTime dateTime = LocalDateTime.now().plusDays((long)days);
return Date.from(dateTime.with(LocalTime.MIN).atZone(ZoneId.systemDefault()).toInstant());
}
public static Date getEndTime(Integer days) {
LocalDateTime dateTime = LocalDateTime.now().plusDays((long)days);
return Date.from(dateTime.with(LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant());
}
public static Date getZeroTime(Date time) {
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(time.getTime()), ZoneId.systemDefault());
return Date.from(localDateTime.with(LocalTime.MIN).atZone(ZoneId.systemDefault()).toInstant());
}
public static Date getEndTime(Date time) {
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(time.getTime()), ZoneId.systemDefault());
return Date.from(localDateTime.with(LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant());
}
public static List<Date> betweenDate(Date start, Date end) {
LocalDate from = LocalDate.from(start.toInstant().atZone(ZoneId.systemDefault()));
LocalDate to = LocalDate.from(end.toInstant().atZone(ZoneId.systemDefault()));
List<Date> result = new ArrayList();
while(from.isBefore(to)) {
from = from.plusDays((long)NumberUtils.INTEGER_ONE);
result.add(Date.from(Instant.from(from.atStartOfDay(ZoneId.systemDefault()))));
}
return result;
}
public static Date getTruncatedTime(Date time) {
return Date.from(time.toInstant().truncatedTo(ChronoUnit.SECONDS));
}
public static Long getUnixTimeByDate(Date date) {
return date.getTime() / 1000L;
}
public static LocalDateTime toLocalDateTime(Date date) {
return toLocalDateTime(date, DateFormatBoostUtils.EAST_8_TIME_ZONE);
}
public static LocalDateTime toLocalDateTime(Date date, ZoneId zone) {
return date.toInstant().atZone(zone).toLocalDateTime();
}
public static Date getAdjusterTime(Integer days, Integer hours, Integer minutes, Integer second, Integer mills) {
LocalDateTime time = LocalDateTime.now().with(LocalTime.MIN).plusDays((long)days).withHour(hours).withMinute(minutes).withSecond(second).with(ChronoField.MILLI_OF_SECOND, Long.valueOf((long)mills));
return Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
}
}
远程调用
序列化
- 响应
import java.io.Serializable;
/**
* 统一返回值
* Created by songjiawei on 2016/7/25.
*/
public final class Response<T> implements Serializable {
private static final long serialVersionUID = 42L;
/**
* 响应数据
*/
private T data;
/**
* 状态码|com.southcn.common.enums.MsgCode
*/
private Integer code;
/**
* 消息文本
*/
private String msg;
/**
* 请求是否成功
*/
private boolean success;
public T getData() {
return data;
}
public Response<T> setData(T data) {
this.data = data;
return this;
}
public Integer getCode() {
return code;
}
public Response<T> setCode(Integer code) {
this.code = code;
return this;
}
/**
* 返回应答提示消息
*
* @return 消息
*/
public String getMsg() {
return msg;
}
public Response<T> setMsg(String msg) {
this.msg = msg;
return this;
}
public boolean isSuccess() {
return MsgCode.SUCCESS.getCode().equals(this.code) && success;
}
public Response<T> setSuccess(boolean success) {
this.success = success;
return this;
}
@Override
public String toString() {
return "Response{" +
"data=" + data +
", code=" + code +
", msg='" + msg + '\'' +
", success=" + success +
'}';
}
}
- 构建
/**
* 统一返回构建方法
*/
public class ResponseBuilder {
/**
* 构建一个标准的应答报文,data为null
*
* @return 应答报文
*/
public static Response<String> buildSuccess() {
return build(true, MsgCode.SUCCESS.getCode(), null, MsgCode.SUCCESS.getMsg());
}
public static <T> Response<T> buildSuccess(T data) {
return build(true, MsgCode.SUCCESS.getCode(), data, MsgCode.SUCCESS.getMsg());
}
public static <T> Response<T> buildSuccess(String msg, T data) {
return build(true, MsgCode.SUCCESS.getCode(), data, msg);
}
public static <T> Response<T> buildFail() {
return build(false, MsgCode.FAIL.getCode(), null, MsgCode.FAIL.getMsg());
}
public static <T> Response<T> buildFail(T data) {
return build(false, MsgCode.FAIL.getCode(), data, MsgCode.FAIL.getMsg());
}
public static <T> Response<T> buildFail(String msg) {
return build(false, MsgCode.FAIL.getCode(), null, msg);
}
public static <T> Response<T> buildFail(Integer code, String msg) {
return build(false, code, null, msg);
}
public static <T> Response<T> buildFail(Integer code, String msg, T data) {
return build(false, code, data, msg);
}
public static <T> Response<T> build(boolean success, Integer code) {
return build(success, code, null, null);
}
public static <T> Response<T> build(boolean success, Integer code, T data) {
return build(success, code, data, null);
}
public static <T> Response<T> build(boolean success, Integer code, T data, String msg) {
return new Response<T>().setSuccess(success).setCode(code).setData(data).setMsg(msg);
}
}
- 解析
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import java.util.List;
import java.util.Objects;
public class ResponseParse {
/**
* 解析应答数据
*
* @param json json数据
* @return 返回应答数据
*/
public static Response<Object> parseResponse(String json) {
return JSON.parseObject(json, new TypeReference<Response<Object>>() {
});
}
/**
* 解析应答数据
*
* @param json json格式数据
* @param clazz 需要转换的class对象
* @param <T> 泛型
* @return 应答
*/
public static <T> Response<T> parseResponse(String json, Class<T> clazz) {
Response<T> response = JSON.parseObject(json, new TypeReference<Response<T>>() {
});
Object data = response.getData();
if (Objects.nonNull(data) && (data instanceof JSONObject)) {
return ResponseBuilder.build(response.isSuccess(), response.getCode(), JSON.parseObject(((JSONObject) data).toJSONString(), clazz));
}
return response;
}
/**
* 解析成数组对象
*
* @param json json格式数据
* @param clazz 需要转换的class对象
* @param <T> 泛型
* @return 应答
*/
public static <T> Response<List<T>> parseArrayResponse(String json, Class<T> clazz) {
Response<Object> response = JSON.parseObject(json, new TypeReference<Response<Object>>() {
});
Object data = response.getData();
if (Objects.nonNull(data) && (data instanceof JSONArray)) {
return new Response<List<T>>().setCode(response.getCode()).setSuccess(response.isSuccess())
.setMsg(response.getMsg()).setData(JSON.parseArray(((JSONArray) data).toJSONString(), clazz));
} else {
return new Response<List<T>>().setCode(response.getCode()).setSuccess(response.isSuccess())
.setMsg(response.getMsg()).setData(null);
}
}
}
Stream流
- 把集合数据做分页传输
Stream.iterate(0, p -> p + 1)
.limit(pictureDataDTOS.size())
.map(a -> pictureDataDTOS.stream().skip(a * PictureConstant.PAGESIZE).limit(PictureConstant.PAGESIZE)
.collect(Collectors.toList()))
.filter(v -> CollectionUtils.isNotEmpty(v) && result.get())
.forEach(m -> {
boolean b = this.sendHttp(m);
if (!b) {
//如果有一次失败,结束之后的发送,缓存中存的时间不变(最后成功时)
result.set(false);
}
});
2.基本练习
import java.lang.reflect.Array;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class test {
public static void main(String[] args) throws InterruptedException {
// one();
//two();
// three();
String[] arr1 = { "a", "b", "c", "d" };
String[] arr2 = { "d", "e", "f", "g" };
Stream<String> stream1 = Stream.of(arr1);
Stream<String> stream2 = Stream.of(arr2);
// List<String> collect = Stream.concat(stream1, stream2).collect(Collectors.toList());
//System.out.println("合并没去重:"+collect);
List<String> collect1 = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());
System.out.println("合并去重:"+collect1);
//无限流,需要搭配limit做上限
List<Integer> collect = Stream.iterate(1, n -> n + 2).limit(10).collect(Collectors.toList());
System.out.println(collect);
//跳过前面10个
List<Integer> collect2 = Stream.iterate(1, n -> n + 2).skip(10).limit(10).collect(Collectors.toList());
System.out.println(collect2);
}
private static void three() {
//map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
//flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
List<String> list = Arrays.asList("m,k,l,a", "1,3,5,7");
List<String> collect = list.stream().flatMap(x -> {
//将每个元素转换成一个stream
String[] split = x.split(",");
Stream<String> stream = Arrays.stream(split);
System.out.println(stream);
return stream;
}).collect(Collectors.toList());
System.out.println("修改之前:"+list);
System.out.println("修改之后:"+collect);
List<Stream<String>> collect1 = list.stream().map(x -> {
String[] split = x.split(",");
Stream<String> stream = Arrays.stream(split);
System.out.println(stream);
return stream;
}).collect(Collectors.toList());
System.out.println("修改之后:"+collect1);
}
private static void two() {
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900,20, "male", "New York"));
personList.add(new Person("Jack", 7000,30, "male", "Washington"));
personList.add(new Person("Lily", 7800,22, "female", "Washington"));
personList.add(new Person("Anni", 8200,24, "female", "New York"));
personList.add(new Person("Owen", 9500,25, "male", "New York"));
personList.add(new Person("Alisa", 7900,28, "female", "New York"));
//可以将stream中的元素用特定的连接符(没有的话,则直接连接)连接成一个字符串。
String collect9 = personList.stream().map(x -> x.getName()).collect(Collectors.joining(","));
System.out.println("员工姓名为:"+collect9);
String collect10 = personList.stream().map(Person::getSalary).sorted().map(x -> x + "").collect(Collectors.joining("-"));
System.out.println("结果:"+collect10);
List<String> collect11 = personList.stream().sorted(Comparator.comparing(Person::getSalary).reversed()).map(Person::getName).collect(Collectors.toList());
System.out.println("反序排列:"+collect11);
List<String> collect12 = personList.stream().sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getAge)).map(Person::getName).collect(Collectors.toList());
System.out.println("先按什么在按什么排序:"+collect12);
List<String> collect13 = personList.stream().sorted((v1, v2) -> {
if (v1.getSalary() == v2.getSalary()) {
return v1.getAge() - v2.getAge();
} else {
return v2.getSalary() - v1.getSalary();
}
}).map(Person::getName).collect(Collectors.toList());
System.out.println("自定义排序:"+collect13);
//分组
Map<String, List<Person>> collect6 = personList.stream().collect(Collectors.groupingBy(Person::getSex));
System.out.println("按性别分组:"+collect6);
Map<Boolean, List<Person>> collect7 = personList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000));
System.out.println("按条件分组:"+collect7);
Map<String, Map<String, List<Person>>> collect8 = personList.stream().collect(Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea)));
System.out.println("按性别在按年龄分组:"+collect8);
Long collect2 = personList.stream().collect(Collectors.counting());
System.out.println("总员工数:"+collect2);
Double collect3 = personList.stream().collect(Collectors.averagingDouble(Person::getSalary));
System.out.println("平均数:"+collect3);
Integer collect4 = personList.stream().collect(Collectors.summingInt(Person::getSalary));
System.out.println("总数为:"+collect4);
DoubleSummaryStatistics collect5 = personList.stream().collect(Collectors.summarizingDouble(Person::getSalary));
System.out.println("所有信息:"+collect5);
//求工资合
Integer integer = personList.stream().map(Person::getSalary).reduce(Integer::sum).get();
System.out.println("工资之和:"+integer);
//工资大于8000的员工信息
Map<Integer, String> collect1 = personList.stream().filter(x -> x.getSalary() > 8000).collect(Collectors.toMap(Person::getSalary, p -> p.getName()));
System.out.println("信息为:"+collect1);
//晒取员工工资高于8千的员工姓名
List<String> collect = personList.stream().filter(x -> x.getSalary() > 8000).map(Person::getName).collect(Collectors.toList());
System.out.println(collect);
//获取工资最高的员
Person person1 = personList.stream().max(Comparator.comparing(Person::getSalary)).get();
System.out.println(person1);
List<Person> personListNew = personList.stream().map(person -> {
Person personNew = new Person(person.getName(), 0, 0, null, null);
personNew.setSalary(person.getSalary() + 10000);
return personNew;
}).collect(Collectors.toList());
System.out.println("第二次修改:"+personListNew);
//给每个员工工资加一万
List<Integer> col = personList.stream().map(per -> per.getSalary() + 10000).collect(Collectors.toList());
System.out.println("修改之前:"+personList);
System.out.println("修改之后:"+col);
}
private static void one() {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
List<String> Stringlist = Arrays.asList("ca", "ava", "bython", "dcala","byz");
Optional<Integer> min = list.stream().sorted().findFirst();
System.out.println(list.stream().min(Comparator.comparing(Integer::intValue)).get());
System.out.println("最小值为;"+min.get());
Integer max = list.stream().sorted().sorted((a, b) -> b - a).findFirst().get();
System.out.println(list.stream().max(Comparator.comparing(Integer::intValue)).get());
System.out.println("最大值为:"+max);
//字符串排序并打印
//Stringlist.stream().sorted().forEach(System.out::println);
//字符串按照长度排序
//Stringlist.stream().sorted((s1, s2) -> s2.length()-s1.length()).forEach(System.out::println);
//打印20-30的数字
// Stream.iterate(1, i->i+1).skip(20).limit(10).forEach(System.out::println);
//把字符串转数字并计算和
String str="11,22,33,44,55";
System.out.println(Stream.of(str.split(",")).mapToInt(value -> Integer.parseInt(value)).sum());
System.out.println(Stream.of(str.split(",")).peek(System.out::println).mapToInt(Integer::parseInt).sum());
boolean b = list.stream().anyMatch(x -> x > 6);
System.out.println(b);
Optional<Integer> any = list.parallelStream().filter(x -> x > 6).findAny();
System.out.println(any.get());
}
}
AOP
- 实现日志功能
- 自定义注解
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface AopAnnotation {
String arg()default "OK";
}
- 切面,切点,通知
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
@Slf4j
@Aspect
@Component
public class AspectController {
@Pointcut("@annotation(com.yepeiqiang.video.annotation.AopAnnotation)")
// @Pointcut("execution(* com.yepeiqiang.video.controller.*.*(..))")
public void method(){
};
@Before("method()")
public void before (JoinPoint pointcut){
log.info("参数为:{}",pointcut.getArgs());
// method-execution
log.info("Kind:{}",pointcut.getKind());
//返回值 方法全类名参数
log.info("Signature:{}",pointcut.getSignature());
//org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint$SourceLocationImpl@686e02d5
log.info("SourceLocation:{}",pointcut.getSourceLocation());
//execution(R com.yepeiqiang.video.controller.MediaUserController.findById(String))
log.info("StaticPart:{}",pointcut.getStaticPart());
//com.yepeiqiang.video.controller.MediaUserController@1fea214e
log.info("Target:{}",pointcut.getTarget());
//com.yepeiqiang.video.controller.MediaUserController@1fea214e
log.info("This:{}",pointcut.getThis());
System.out.println("执行前置方法");
}
@After("method()")
public void after(JoinPoint point){
log.info("参数为:{}",point.getArgs());
System.out.println("执行后置方法");
}
@Around("method()")
public Object around(ProceedingJoinPoint point) throws Throwable {
System.out.println("执行前置环绕方法");
log.info("参数为:{}",point.getArgs());
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//请求端口路径
String serverName = request.getServerName();
//请求参数
String queryString = request.getQueryString();
log.info("serverName:{},queryString:{}",serverName,queryString);
Object proceed = point.proceed();
System.out.println("执行后置环绕方法"+proceed);
return proceed;
}
@AfterReturning(value = "method()",returning = "ret")
public void afterReturning(JoinPoint point,Object ret){
log.info("参数为:{},{}",point.getArgs(),ret);
System.out.println("执行后置成功方法");
}
@AfterThrowing(value = "method()",throwing = "ex")
public void throwing(JoinPoint point,Throwable ex){
log.info("参数为:{},{}",point.getArgs(),ex);
System.out.println("执行后置异常方法");
}
}
3.方法/类上加注解
@AopAnnotation
@GetMapping("/message")
public R getVideoMessage( String path){
log.info("开始查询,参数为:{}",path);
Map<String, Object> videoMsg = VideoCom.getVideoMsg(path);
log.info("查询完成");
return R.success("成功",200,JSON.toJSONString(videoMsg));
}
过滤器和拦截器
- 拦截器
- 继承HandlerInterceptor
import com.yepeiqiang.video.constant.UserLocal;
import com.yepeiqiang.video.entry.MediaUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Slf4j
public class MyIntercept implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//进行用户权限判断
String contextPath = request.getContextPath();
//获取 token 解析用户密码
//根据用户名查询用户是否存在
//在对密码解密解盐判断密码是否存储
//正确则存入本地线程变量
UserLocal.setMediaUser(new MediaUser());
//放行
log.info("ContextPath:{}",contextPath);
System.out.println("preHandle执行了");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//handler方法执行后
log.info("模板和视图:{}",modelAndView);
System.out.println("postHandle执行了");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
UserLocal.clear();
//在postHandle之后执行
System.out.println("afterComletion执行了");
}
}
2.编写配置文件
import com.yepeiqiang.video.intercept.MyIntercept;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@EnableTransactionManagement
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyIntercept())
.addPathPatterns("/**")
.excludePathPatterns("");
}
}
实现定时任务
- 开启一个线程搭配循环
private static void run() {
Runnable ru = new Runnable() {
int count = 0;
@Override
public void run() {
while (true){
count++;
try {
Thread.sleep(1000);
System.out.println("执行了任务:"+count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread thread = new Thread(ru);
thread.start();
}
- 用系统自带的
private static void task() {
TimerTask task = new TimerTask() {
int count =0;
@Override
public void run() {
count++;
System.out.println("执行了任务:"+count);
}
};
Timer timer = new Timer();
/**
* 第一个参数为执行的任务
* 第二个参数为执行的时间
* 第三个参数为间隔时间
*/
timer.schedule(task,new Date(),1000);
}
- 定时线程池
private static void executors() {
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
int count = 0;
@Override
public void run() {
count++;
System.out.println("执行了任务:"+count);
}
},0,1,TimeUnit.SECONDS);
}
4.用spring带的schedule加cron表达式
//启动类上加这个注解
@EnableScheduling
public class NfplusMediaApiApplication {
public static void main(String[] args) {
SpringApplication.run(NfplusMediaApiApplication.class,args);
}
}
@Slf4j
@Component
public class PictureListScheduleTask {
@Autowired
private PictureListService pictureListService;
//每天上午8点推送
@Scheduled(cron = "0 0 8 * * ?")
public void PicturePushNew() {
Boolean result = pictureListService.pushPicture();
log.info("同步图片到版权系统结果为:{}",result);
}
}
5.通过xxx-job分布式管理
全局异常处理
- 创建自己的异常
import lombok.Data;
public class MyException extends RuntimeException {
private Integer code;
private String message;
public MyException(Integer code,String message){
super(message);
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
- 编写异常处理器
import com.yepeiqiang.video.exception.MyException;
import com.yepeiqiang.video.untils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
@Slf4j
@ControllerAdvice
@ResponseBody
public class GlobalDeafultExceptionHandler {
@ExceptionHandler(value = MyException.class)
public R getMyException(HttpServletResponse response,Exception e){
log.info("错误信息:{}",e);
return R.fail(e.getMessage(),400);
}
}
- 手动抛出异常
throw new MyException(400,"参数为空");
问题
- 解决tomcat高版本接受路径参数出现乱码问题
@Configuration
public class TomcatConfig {
/**
* 高版本tomcat中的新特性:就是严格按照 RFC 3986规范进行访问解析,
* 而 RFC 3986规范定义了Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及
* 所有保留字符(RFC3986中指定了以下字符为保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ])。
*
* @return
*/
@Bean
public TomcatServletWebServerFactory webServerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.addConnectorCustomizers((Connector connector) -> {
connector.setProperty("relaxedPathChars", "\"<>[\\]^`{|}");
connector.setProperty("relaxedQueryChars", "\"<>[\\]^`{|}");
});
return factory;
}
}
maven坐标
仓库地址:https://mvnrepository.com/
可以根据下面的包去上面仓库搜索对应的坐标
1.数据分页
package com.github.pagehelper;
配置文件
- 启动日志
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;
import java.net.InetAddress;
@Slf4j
@Component
public class ApiRunner implements ApplicationRunner {
@Autowired
private ConfigurableApplicationContext context;
@Value("${server.port}")
private String port;
@Value("${server.servlet.context-path}")
private String contextPath;
@Override
public void run(ApplicationArguments args) throws Exception {
try {
// 检测Redis,MySQL等连接
} catch (Exception e) {
log.error(" _____ _ ___ _ ");
log.error(" | ___| / \\ |_ _| | |");
log.error(" | |_ / _ \\ | | | | ");
log.error(" | _| / ___ \\ | | | |___ ");
log.error(" |_| /_/ \\_\\ |___| |_____|");
log.error("启动失败", e);
context.close();
}
if (context.isActive()) {
InetAddress localHost = InetAddress.getLocalHost();
String url = String.format("http://%s:%s%s", localHost.getHostAddress(), port,contextPath);
log.info("启动成功,访问地址:{}", url);
}
}
}
- redis配置
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@Configuration
public class RedisTemplateConfiguration {
@Autowired
private ObjectMapper objectMapper;
@Bean
public RedisTemplate getRedisTemplate(RedisTemplate redisTemplate) {
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(objectMapper.copy().enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL));
redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
return redisTemplate;
}
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
public CacheManager CacheManager(RedisTemplate redisTemplate) {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(60));
return new RedisCacheManager(
RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory()),
redisCacheConfiguration, // 默认策略,未配置的 key 会使用这个
getRedisCacheConfigurationMap()
);
}
private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() {
Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
RedisCacheConfiguration value = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(5));
redisCacheConfigurationMap.put("videoCache", value);
redisCacheConfigurationMap.put("pictureCache", value);
redisCacheConfigurationMap.put("audioCache", value);
return redisCacheConfigurationMap;
}
@Bean
public KeyGenerator simpleKeyGenerator() {
return (o, method, objects) -> {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(method.getName()).append("[");
for (Object obj : objects) {
if (Objects.nonNull(obj)){
stringBuilder.append(obj.toString());
}
}
stringBuilder.append("]");
return stringBuilder.toString();
};
}
}
- 线程池配置
import cn.hutool.core.util.IdUtil;
import com.southcn.nfplus.media.common.constant.Constant;
import org.slf4j.MDC;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
/**
* Title: com.southcn.nfplus.media.admin.config
* Description: 线程池
* Copyright: Copyright (c) 2008
* Company: nfplus
*
* @author zengwen
* @version 1.0
* @date 2019/7/26
*/
@EnableAsync
@Configuration
public class ThreadPoolConfiguration {
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor() {
@Override
public <T> Future<T> submit(Callable<T> task) {
// 传入线程池之前先复制当前线程的MDC
return super.submit(wrap(task, MDC.getCopyOfContextMap()));
}
@Override
public void execute(Runnable task) {
// 执行前先复制当前线程的MDC
super.execute(wrap(task, MDC.getCopyOfContextMap()));
}
};
//线程池维护线程的最少数量
taskExecutor.setCorePoolSize(10);
//线程池维护线程所允许的空闲时间
taskExecutor.setKeepAliveSeconds(2000);
//线程池维护线程的最大数量
taskExecutor.setMaxPoolSize(1000);
//线程池所使用的缓冲队列
taskExecutor.setQueueCapacity(100);
return taskExecutor;
}
public static <T> Callable<T> wrap(final Callable<T> callable, final Map<String, String> context) {
return () -> {
if (context == null) {
MDC.clear();
} else {
MDC.setContextMap(context);
}
setTraceIdIfAbsent();
try {
return callable.call();
} finally {
MDC.clear();
}
};
}
public static Runnable wrap(final Runnable runnable, final Map<String, String> context) {
return () -> {
if (context == null) {
MDC.clear();
} else {
MDC.setContextMap(context);
}
setTraceIdIfAbsent();
try {
runnable.run();
} finally {
MDC.clear();
}
};
}
public static void setTraceIdIfAbsent() {
if (MDC.get(Constant.LOG_TRACE_ID) == null) {
MDC.put(Constant.LOG_TRACE_ID, IdUtil.fastSimpleUUID());
}
}
}
枚举
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
* @author chendk
* @date 2022/1/27 17:31
*/
@Getter
@RequiredArgsConstructor
public enum AiVideoTemplateEnum {
/**
* 通用
*/
COMMON(0, "简易合成"),
/**
* 新模板
*/
NEW(1, "高级合成");
private final Integer type;
private final String name;
public static AiVideoTemplateEnum getInstance(Integer type) {
for (AiVideoTemplateEnum templateEnum : values()) {
if (templateEnum.getType().equals(type)) {
return templateEnum;
}
}
return COMMON;
}
}
编写sdk和starter
- sdk
- 编写配置文件,指定读取文件路径
import com.southcn.common.utils.ResourceUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import java.io.File;
import java.util.Properties;
/**
* 位置服务配置
*
* @author Caspar
* @since 2022/7/12 11:13
*/
public class PositionConfig {
/**
* 位置服务地址
*/
private String serverUrl;
/**
* 渠道:1-南方+,2-南都,3-N视频
*/
private Integer channel;
/**
* 系统名称
*/
private String systemName;
private static final PositionConfig INSTANCE;
/**
* 配置文件路径
*/
private static final String POSITION_RESOURCE_NAME = "position.properties";
private static final String POSITION_RESOURCE_PATH = "classpath:configs" + File.separator + POSITION_RESOURCE_NAME;
private static final String POSITION_RESOURCE_PATH1 = "classpath:" + POSITION_RESOURCE_NAME;
static {
Properties properties = ResourceUtils.readProperties(POSITION_RESOURCE_PATH);
if (properties.size() <= 0) {
properties = ResourceUtils.readProperties(POSITION_RESOURCE_PATH1);
}
String serverUrl = properties.getProperty("position.server-url");
Integer channel = NumberUtils.toInt(properties.getProperty("position.channel"));
String systemName = properties.getProperty("position.system-name");
INSTANCE = new PositionConfig(serverUrl, channel, systemName);
}
public PositionConfig() {
}
public static PositionConfig newInstance(String serverUrl, Integer channel, String systemName) {
if (StringUtils.isBlank(INSTANCE.getServerUrl())) {
synchronized (PositionConfig.class) {
if (StringUtils.isBlank(INSTANCE.getServerUrl())) {
INSTANCE.init(serverUrl, channel, systemName);
}
}
}
return INSTANCE;
}
public void init(String serverUrl, Integer channel, String systemName) {
if (StringUtils.isNotBlank(serverUrl)) {
serverUrl = StringUtils.appendIfMissing(serverUrl, "/", "/");
}
this.serverUrl = serverUrl;
this.channel = channel;
this.systemName = systemName;
}
public PositionConfig(String serverUrl, Integer channel, String systemName) {
this.serverUrl = serverUrl;
this.channel = channel;
this.systemName = systemName;
}
public String getServerUrl() {
return serverUrl;
}
public static PositionConfig getConfig() {
return INSTANCE;
}
public String getSystemName() {
return systemName;
}
public Integer getChannel() {
return channel;
}
}
- 编写api,获取参数实现代码逻辑
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
/**
* IP地址
*
* @author Caspar
* @since 2022/7/12 11:12
*/
public class IpAddressApi {
private static final Logger log = LoggerFactory.getLogger(IpAddressApi.class);
/**
* 获取IP属地
*
* @param ipAddress IP地址
* @return
*/
public static IpLocationVO ipLocation(String ipAddress) {
if (StringUtils.isBlank(ipAddress)) {
return IpLocationVO.unknown(ipAddress);
}
PositionConfig config = PositionConfig.getConfig();
String url = new StringBuilder()
.append(config.getServerUrl())
.append(RestConst.IP_LOCATION)
.toString();
Map<String, String> params = new HashMap<>(3);
params.put("ip", ipAddress);
params.put("channel", config.getChannel().toString());
params.put("system", config.getSystemName());
String result = OkHttpUtil.post(url, params, OkHttpBuilder.getOkHttpClient());
if (StringUtils.isBlank(result)) {
log.error("IP属地:请求异常,url={}", url);
return IpLocationVO.unknown(ipAddress);
}
Response<IpLocationVO> response = ResponseParse.parseResponse(result, IpLocationVO.class);
if (response.isSuccess()) {
return response.getData();
} else {
log.error("IP属地:请求失败,url={},response={}", url, result);
return IpLocationVO.unknown(ipAddress);
}
}
}
- pom文件指定坐标名称
名称 - 在deploy到远程仓库
- starter
- 编写自动配置类
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author Caspar
* @since 2022/7/12 16:40
*/
@Configuration
@EnableConfigurationProperties(PositionConfigure.class)
public class PositionAutoConfigure {
}
-
pom文件导入sdk坐标
-
编写配置文件,初始化sdk里面的配置文件
/**
* @author Caspar
* @since 2022/7/12 16:40
*/
@ConfigurationProperties("southcn.springboot.position")//填写配置文件路径,需要从这里获取值
public class PositionConfigure implements InitializingBean {
/**
* 位置服务地址(参数)
*/
private String serverUrl;
public String getServerUrl() {
return serverUrl;
}
public void setServerUrl(String serverUrl) {
this.serverUrl = serverUrl;
}
@Override
public void afterPropertiesSet() throws Exception {
PositionConfig.newInstance(serverUrl);
}
}
- 编写META-INF下面spring.factories文件
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.southcn.nfapp.position.spring.boot.PositionAutoConfigure
- pom文件指定坐标名称
名称 - 在deploy到远程仓库
或者这个命令 mvn clean compile package install deploy -U -pl southcn-ip-spring-boot-starter -am