一、java特殊字符判断
1. 只能输入中文、字母、空格、数值
// 名称特殊字符判断
String name = ".........";
if (!name.matches("[0-9a-zA-Z\\s\u4E00-\u9FA5]+")) {
System.out.println("只能输入中文、数字和字母,请重新输入!");
}
2. 特殊表情 存入mysql错误
Caused by: java.sql.SQLException: Incorrect string value: ‘\xF0\x9F\x8C\xB8’ for column ‘remark’ at row 1
问题产生原因:某些表情占4个字节,而mysql utf8只能存3个字节导致报错
解决方案:
①.如需要存入mysql 将库和表的字符编码由utf8改为utf8mb4
②.拦截或者过滤
// 特殊字符或表情(例如:🌸)占4个字节,utf-8占3个字节 导致mysql数据库报错
String remark = "............";
if (remark.length() > remark.replaceAll("[\ud800\udc00-\udbff\udfff\ud800-\udfff]", "").length()) {
System.out.println("简介不能输特殊字符(表情),请重新输入!");
}
二、URL地址拼接方法封装
/**
* 拼接URL
*
* @param url 请求地址
* @param paramMap 请求参数Map
* @return
*/
private String joinUrl(String url, Map<String, Object> paramMap) {
// 容错处理
if (paramMap.size() == 0 || StringUtils.isBlank(url)) {
return url;
}
StringBuilder sbUrl = new StringBuilder(url);
// 获取第一个字符
String firstChar = url.contains("?") ? "&" : "?";
sbUrl.append(firstChar);
// 拼接参数
StringBuilder sbParam = new StringBuilder();
for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
sbParam.append("&");
sbParam.append(key);
sbParam.append("=");
sbParam.append(value);
}
return sbUrl.append(sbParam.substring(1)).toString();
}
三、利用RestTemplate发请求封装
1. 公共请求代码
// 相关导包记录
/*
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;
import com.alibaba.fastjson.JSONObject;
import java.util.*;
*/
/**
* 通用请求
*
* @param url
* @param requestParamMap
* @param requestBody
* @param requestHeaderMap
* @param mediaType
* @param requestMethod 请求方式
* @return
*/
public JSONObject commonRequest(String url, Map<String, Object> requestParamMap, String requestBody,
Map<String, Object> requestHeaderMap, MediaType mediaType, HttpMethod requestMethod) {
String requestUrl = joinUrl(url, requestParamMap);
// 设置请求头
HttpHeaders headers = new HttpHeaders();
mediaType = Optional.ofNullable(mediaType).orElse(MediaType.APPLICATION_JSON);
headers.setContentType(mediaType);
for (Map.Entry<String, Object> entry : requestHeaderMap.entrySet()) {
headers.set(entry.getKey(), entry.getValue().toString());
}
// 设置请求参数
requestBody = Optional.ofNullable(requestBody).orElse(new JSONObject().toString());
// 设置请求方式
requestMethod = Optional.ofNullable(requestMethod).orElse(HttpMethod.POST);
// 用HttpEntity封装整个请求报文
HttpEntity<String> request = new HttpEntity<>(requestBody, headers);
// 发送请求
ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(requestUrl, requestMethod, request, JSONObject.class);
// 获取请求体
return responseEntity.getBody();
}
2. 结合海康调试接口使用
这里不是海康安防平台接口,是 “ISAPI开发指南_门禁设备_明眸_2022_04_07” 接口
① 先定义接口地址
import org.springframework.http.HttpMethod;
/**
* 海康接口管理
*/
public enum HikvisionApiEnum {
// 人脸相关
ADD_FDLIB("/ISAPI/Intelligent/FDLib", HttpMethod.POST, "创建人脸库"),
ADD_FACE("/ISAPI/Intelligent/FDLib/FaceDataRecord", HttpMethod.POST, "添加人脸信息"),
// 人员相关
ADD_USER("/ISAPI/AccessControl/UserInfo/Record", HttpMethod.POST, "添加人员"),
MODIFY_USER("/ISAPI/AccessControl/UserInfo/Modify", HttpMethod.PUT, "修改人员"),
DELETE_USER("/ISAPI/AccessControl/UserInfoDetail/Delete", HttpMethod.PUT, "删除人员");
/**
* 海康基础访问地址头
*/
private final static String BASE_URL = "https://open.ys7.com/api/hikvision";
/**
* api访问URL
*/
private String url;
/**
* 请求方式
*/
private HttpMethod requestMethod;
/**
* 简介
*/
private String description;
HikvisionApiEnum(String url, HttpMethod requestMethod, String description) {
this.url = url;
this.requestMethod = requestMethod;
this.description = description;
}
public String getUrl() {
return BASE_URL + url;
}
public String getDescription() {
return description;
}
public HttpMethod getRequestMethod() {
return requestMethod;
}
}
② 编写海康公共请求接口
/**
* 海康请求接口
*
* @param hikvisionApiEnum
* @param deviceSerial
* @param requestBody
* @return
*/
public JSONObject hikvisionRequest(HikvisionApiEnum hikvisionApiEnum, String deviceSerial, String requestBody) {
// 请求参数
Map<String, Object> requestParamMap = new HashMap<>();
requestParamMap.put("format", "json");
// 设置请求头
Map<String, Object> requestHeaderMap = new HashMap<>();
// 获取token(使用萤石云平台的token)
String accessToken = ysyUtils.getAccessToken();
requestHeaderMap.put("EZO-AccessToken", accessToken);
requestHeaderMap.put("EZO-DeviceSerial", deviceSerial);
log.info("输入请求参数:{}", requestBody);
return commonRequest(hikvisionApiEnum.getUrl(), requestParamMap, requestBody, requestHeaderMap, null, hikvisionApiEnum.getRequestMethod());
}
③ 细化的请求
/**
* 添加人脸库
*
* @param deviceSerial
* @param name
* @return
*/
public JSONObject addFdlib(String deviceSerial, String name) {
// 封装请求信息
AddFaceLib addFaceLib = AddFaceLib.builder().name(name).build();
// 响应信息:{"subStatusCode":"ok","statusString":"OK","FDID":"1","statusCode":1}
JSONObject result = hikvisionRequest(HikvisionApiEnum.ADD_FDLIB, deviceSerial, JSONObject.toJSONString(addFaceLib));
// 返回信息可通过反序列化为实体类
return result;
}
四丶时间相关
① 给定一个时间范围,获取时间差字符串列表
/**
* 获取日期差集合
*
* @param type 1 按日 2 按月
* @param dateStartTime yyyy-MM-dd or yyyy-MM
* @param dateEndTime yyyy-MM-dd or yyyy-MM
* @return
*/
private List<String> getDifferenceList(Integer type, String dateStartTime, String dateEndTime) {
Long dateDifference = 0L;
if (Objects.equals(type, 1)) {
// ChronoUnit:jdk8方法
dateDifference = ChronoUnit.DAYS.between(LocalDate.parse(dateStartTime), LocalDate.parse(dateEndTime));
} else if (Objects.equals(type, 2)) {
dateDifference = ChronoUnit.MONTHS.between(YearMonth.parse(dateStartTime), YearMonth.parse(dateEndTime));
}
return getDifferenceList(type, dateEndTime, dateDifference.intValue());
}
/**
* 获取日期差集合
*
* @param type 1 按日 2 按月
* @param dateEndTime yyyy-MM-dd or yyyy-MM
* @param dateDifference 日期差(例如最近15天)
* @return
*/
private List<String> getDifferenceList(Integer type, String dateEndTime, Integer dateDifference) {
// 创建时间日期
LinkedList<String> dateList = new LinkedList<>();
// 获取日期模板
String datePattern = Objects.equals(1, type) ? DatePattern.NORM_DATE_PATTERN : DatePattern.NORM_MONTH_PATTERN;
// 获取截止日期
DateTime initDate = DateUtil.parse(dateEndTime, datePattern);
// 遍历获取每个日期
dateDifference = dateDifference == 1 ? 2 : dateDifference;
for (int i = dateDifference - 1; i > 0; i--) {
DateTime dateTime = Objects.equals(1, type) ? DateUtil.offsetDay(initDate, -1 * i) : DateUtil.offsetMonth(initDate, -1 * i);
dateList.add(DateUtil.format(dateTime, datePattern));
}
dateList.add(dateEndTime);
return dateList;
}
五、JSON数据转换
六、多个时间判断是否有交集
参考文章:https://blog.csdn.net/u012869793/article/details/126508599
// 类
public class ServiceTimeQuery {
/**
* 服务名称
*/
private String serviceName;
/**
* 开始时间
*/
private Time startTime;
/**
* 结束时间
*/
private Time endTime;
}
..........分割线............
// 业务代码
for (int i = 0; i < serviceTimeList.size(); i++) {
ServiceTimeQuery iServiceTime = serviceTimeList.get(i);
Time iStartTime = iServiceTime.getStartTime();
Time iEndTime = iServiceTime.getEndTime();
for (int j = i + 1; j < serviceTimeList.size(); j++) {
ServiceTimeQuery jServiceTime = serviceTimeList.get(j);
Time jStartTime = jServiceTime.getStartTime();
Time jEndTime = jServiceTime.getEndTime();
// 判断是否有交集(无交集情况:1结束时间小于2开始时间或者1开始时间大于2结束时间)
if (!(iEndTime.before(jStartTime) || iStartTime.after(jEndTime))) {
throw RRException.erm("操作失败,'" + iServiceTime.getServiceName() + "'和'" + jServiceTime.getServiceName() + "'有时间交集");
}
}
}