/**
-
Cookie 工具类
*/
public final class CookieUtils {
protected static final Logger logger = LoggerFactory.getLogger(CookieUtils.class);
/**
-
得到Cookie的值, 不编码
-
@param request
-
@param cookieName
-
@return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName) {
return getCookieValue(request, cookieName, false);
}
/**
-
得到Cookie的值,
-
@param request
-
@param cookieName
-
@return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName, boolean isDecoder) {
Cookie[] cookieList = request.getCookies();
if (cookieList == null || cookieName == null){
return null;
}
String retValue = null;
try {
for (int i = 0; i < cookieList.length; i++) {
if (cookieList[i].getName().equals(cookieName)) {
if (isDecoder) {
retValue = URLDecoder.decode(cookieList[i].getValue(), “UTF-8”);
} else {
retValue = cookieList[i].getValue();
}
break;
}
}
} catch (UnsupportedEncodingException e) {
logger.error(“Cookie Decode Error.”, e);
}
return retValue;
}
/**
-
得到Cookie的值,
-
@param request
-
@param cookieName
-
@return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName, String encodeString) {
Cookie[] cookieList = request.getCookies();
if (cookieList == null || cookieName == null){
return null;
}
String retValue = null;
try {
for (int i = 0; i < cookieList.length; i++) {
if (cookieList[i].getName().equals(cookieName)) {
retValue = URLDecoder.decode(cookieList[i].getValue(), encodeString);
break;
}
}
} catch (UnsupportedEncodingException e) {
logger.error(“Cookie Decode Error.”, e);
}
return retValue;
}
/**
- 设置Cookie的值 不设置生效时间默认浏览器关闭即失效,也不编码
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue) {
setCookie(request, response, cookieName, cookieValue, -1);
}
/**
- 设置Cookie的值 在指定时间内生效,但不编码
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, int cookieMaxage) {
setCookie(request, response, cookieName, cookieValue, cookieMaxage, false);
}
/**
- 设置Cookie的值 不设置生效时间,但编码
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, boolean isEncode) {
setCookie(request, response, cookieName, cookieValue, -1, isEncode);
}
/**
- 设置Cookie的值 在指定时间内生效, 编码参数
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) {
doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, isEncode);
}
/**
- 设置Cookie的值 在指定时间内生效, 编码参数(指定编码)
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, int cookieMaxage, String encodeString) {
doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, encodeString);
}
/**
- 删除Cookie带cookie域名
*/
public static void deleteCookie(HttpServletRequest request, HttpServletResponse response, String cookieName) {
doSetCookie(request, response, cookieName, “”, -1, false);
}
/**
-
设置Cookie的值,并使其在指定时间内生效
-
@param cookieMaxage
-
cookie生效的最大秒数
*/
private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) {
try {
if (cookieValue == null) {
cookieValue = “”;
} else if (isEncode) {
cookieValue = URLEncoder.encode(cookieValue, “utf-8”);
}
Cookie cookie = new Cookie(cookieName, cookieValue);
if (cookieMaxage > 0)
cookie.setMaxAge(cookieMaxage);
if (null != request)// 设置域名的cookie
cookie.setDomain(getDomainName(request));
cookie.setPath(“/”);
response.addCookie(cookie);
} catch (Exception e) {
logger.error(“Cookie Encode Error.”, e);
}
}
/**
-
设置Cookie的值,并使其在指定时间内生效
-
@param cookieMaxage
-
cookie生效的最大秒数
*/
private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, int cookieMaxage, String encodeString) {
try {
if (cookieValue == null) {
cookieValue = “”;
} else {
cookieValue = URLEncoder.encode(cookieValue, encodeString);
}
Cookie cookie = new Cookie(cookieName, cookieValue);
if (cookieMaxage > 0)
cookie.setMaxAge(cookieMaxage);
if (null != request)// 设置域名的cookie
cookie.setDomain(getDomainName(request));
cookie.setPath(“/”);
response.addCookie(cookie);
} catch (Exception e) {
logger.error(“Cookie Encode Error.”, e);
}
}
/**
- 得到cookie的域名
*/
private static final String getDomainName(HttpServletRequest request) {
String domainName = null;
String serverName = request.getRequestURL().toString();
if (serverName == null || serverName.equals(“”)) {
domainName = “”;
} else {
serverName = serverName.toLowerCase();
serverName = serverName.substring(7);
final int end = serverName.indexOf(“/”);
serverName = serverName.substring(0, end);
final String[] domains = serverName.split(“\.”);
int len = domains.length;
if (len > 3) {
// www.xxx.com.cn
domainName = domains[len - 3] + “.” + domains[len - 2] + “.” + domains[len - 1];
} else if (len <= 3 && len > 1) {
// xxx.com or xxx.cn
domainName = domains[len - 2] + “.” + domains[len - 1];
} else {
domainName = serverName;
}
}
if (domainName != null && domainName.indexOf(“:”) > 0) {
String[] ary = domainName.split(“\:”);
domainName = ary[0];
}
return domainName;
}
}
(2)IdWorker
package com.leyou.common.utils;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.NetworkInterface;
/**
-
名称:IdWorker.java
-
描述:分布式自增长ID
-
Twitter的 Snowflake JAVA实现方案
-
核心代码为其IdWorker这个类实现,其原理结构如下,我分别用一个0表示一位,用—分割开部分的作用:
-
1||0—0000000000 0000000000 0000000000 0000000000 0 — 00000 —00000 —000000000000
-
在上面的字符串中,第一位为未使用(实际上也可作为long的符号位),接下来的41位为毫秒级时间,
-
然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标识),
-
然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。
-
这样的好处是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和机器ID作区分),
-
并且效率较高,经测试,snowflake每秒能够产生26万ID左右,完全满足需要。
-
-
64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加))
-
@author Polim
*/
public class IdWorker {
// 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)
private final static long twepoch = 1288834974657L;
// 机器标识位数
private final static long workerIdBits = 5L;
// 数据中心标识位数
private final static long datacenterIdBits = 5L;
// 机器ID最大值
private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);
// 数据中心ID最大值
private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
// 毫秒内自增位
private final static long sequenceBits = 12L;
// 机器ID偏左移12位
private final static long workerIdShift = sequenceBits;
// 数据中心ID左移17位
private final static long datacenterIdShift = sequenceBits + workerIdBits;
// 时间毫秒左移22位
private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
private final static long sequenceMask = -1L ^ (-1L << sequenceBits);
/* 上次生产id时间戳 */
private static long lastTimestamp = -1L;
// 0,并发控制
private long sequence = 0L;
private final long workerId;
// 数据标识id部分
private final long datacenterId;
public IdWorker(){
this.datacenterId = getDatacenterId(maxDatacenterId);
this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
}
/**
-
@param workerId
-
工作机器ID
-
@param datacenterId
-
序列号
*/
public IdWorker(long workerId, long datacenterId) {
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(String.format(“worker Id can’t be greater than %d or less than 0”, maxWorkerId));
}
if (datacenterId > maxDatacenterId || datacenterId < 0) {
throw new IllegalArgumentException(String.format(“datacenter Id can’t be greater than %d or less than 0”, maxDatacenterId));
}
this.workerId = workerId;
this.datacenterId = datacenterId;
}
/**
-
获取下一个ID
-
@return
*/
public synchronized long nextId() {
long timestamp = timeGen();
if (timestamp < lastTimestamp) {
throw new RuntimeException(String.format(“Clock moved backwards. Refusing to generate id for %d milliseconds”, lastTimestamp - timestamp));
}
if (lastTimestamp == timestamp) {
// 当前毫秒内,则+1
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
// 当前毫秒内计数满了,则等待下一秒
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
// ID偏移组合生成最终的ID,并返回ID
long nextId = ((timestamp - twepoch) << timestampLeftShift)
| (datacenterId << datacenterIdShift)
| (workerId << workerIdShift) | sequence;
return nextId;
}
private long tilNextMillis(final long lastTimestamp) {
long timestamp = this.timeGen();
while (timestamp <= lastTimestamp) {
timestamp = this.timeGen();
}
return timestamp;
}
private long timeGen() {
return System.currentTimeMillis();
}
/**
-
-
获取 maxWorkerId
*/
protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
StringBuffer mpid = new StringBuffer();
mpid.append(datacenterId);
String name = ManagementFactory.getRuntimeMXBean().getName();
if (!name.isEmpty()) {
/*
- GET jvmPid
*/
mpid.append(name.split(“@”)[0]);
}
/*
- MAC + PID 的 hashcode 获取16个低位
*/
return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
}
/**
-
-
数据标识id部分
*/
protected static long getDatacenterId(long maxDatacenterId) {
long id = 0L;
try {
InetAddress ip = InetAddress.getLocalHost();
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
if (network == null) {
id = 1L;
} else {
byte[] mac = network.getHardwareAddress();
id = ((0x000000FF & (long) mac[mac.length - 1])
| (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6;
id = id % (maxDatacenterId + 1);
}
} catch (Exception e) {
System.out.println(" getDatacenterId: " + e.getMessage());
}
return id;
}
}
(3)JsonUtils
package com.leyou.common.utils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.istack.internal.Nullable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public class JsonUtils {
public static final ObjectMapper mapper = new ObjectMapper();
private static final Logger logger = LoggerFactory.getLogger(JsonUtils.class);
@Nullable
public static String serialize(Object obj) {
if (obj == null) {
return null;
}
if (obj.getClass() == String.class) {
return (String) obj;
}
try {
return mapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
logger.error(“json序列化出错:” + obj, e);
return null;
}
}
@Nullable
public static String toString(Object obj) {
if (obj == null) {
return null;
}
if (obj.getClass() == String.class) {
return (String) obj;
}
try {
return mapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
logger.error(“json序列化出错:” + obj, e);
return null;
}
}
@Nullable
public static T parse(String json, Class tClass) {
try {
return mapper.readValue(json, tClass);
} catch (IOException e) {
logger.error(“json解析出错:” + json, e);
return null;
}
}
@Nullable
public static T toBean(String json, Class tClass) {
try {
return mapper.readValue(json, tClass);
} catch (IOException e) {
logger.error(“json解析出错:” + json, e);
return null;
}
}
@Nullable
public static List parseList(String json, Class eClass) {
try {
return mapper.readValue(json, mapper.getTypeFactory().constructCollectionType(List.class, eClass));
} catch (IOException e) {
logger.error(“json解析出错:” + json, e);
return null;
}
}
@Nullable
public static List toList(String json, Class eClass) {
try {
return mapper.readValue(json, mapper.getTypeFactory().constructCollectionType(List.class, eClass));
} catch (IOException e) {
logger.error(“json解析出错:” + json, e);
return null;
}
}
@Nullable
public static <K, V> Map<K, V> parseMap(String json, Class kClass, Class vClass) {
try {
return mapper.readValue(json, mapper.getTypeFactory().constructMapType(Map.class, kClass, vClass));
} catch (IOException e) {
logger.error(“json解析出错:” + json, e);
return null;
}
}
@Nullable
public static <K, V> Map<K, V> toMap(String json, Class kClass, Class vClass) {
try {
return mapper.readValue(json, mapper.getTypeFactory().constructMapType(Map.class, kClass, vClass));
} catch (IOException e) {
logger.error(“json解析出错:” + json, e);
return null;
}
}
@Nullable
public static T nativeRead(String json, TypeReference type) {
try {
return mapper.readValue(json, type);
} catch (IOException e) {
logger.error(“json解析出错:” + json, e);
return null;
}
}
}
(4)NumberUtils
package com.leyou.common.utils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
-
@author: HuYi.Zhang
-
@create: 2018-04-25 09:13
**/
public class NumberUtils {
public static boolean isInt(Double num) {
return num.intValue() == num;
}
/**
-
判断字符串是否是数值格式
-
@param str
-
@return
*/
public static boolean isDigit(String str){
if(str == null || str.trim().equals(“”)){
return false;
}
return str.matches(“^\d+$”);
}
/**
-
将一个小数精确到指定位数
-
@param num
-
@param scale
-
@return
*/
public static double scale(double num, int scale) {
BigDecimal bd = new BigDecimal(num);
return bd.setScale(scale, RoundingMode.HALF_UP).doubleValue();
}
// 从字符串中根据正则表达式寻找,返回找到的数字数组
public static Double[] searchNumber(String value, String regex){
List doubles = new ArrayList<>();
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(value);
if(matcher.find()) {
MatchResult result = matcher.toMatchResult();
for (int i = 1; i <= result.groupCount(); i++) {
doubles.add(Double.valueOf(result.group(i)));
}
}
return doubles.toArray(new Double[doubles.size()]);
}
/**
-
生成指定位数的随机数字
-
@param len
-
@return
*/
public static String generateCode(int len){
len = Math.min(len, 8);
int min = Double.valueOf(Math.pow(10, len - 1)).intValue();
int num = new Random().nextInt(Double.valueOf(Math.pow(10, len + 1)).intValue() - 1) + min;
return String.valueOf(num).substring(0,len);
}
}
(5)引入上述所有需要的依赖
<project xmlns=“http://maven.apache.org/POM/4.0.0”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>
leyou
com.leyou.parent
1.0.0-SNAPSHOT
4.0.0
com.leyou.common
ly-common
org.apache.tomcat.embed
tomcat-embed-core
org.springframework.boot
spring-boot-starter-logging
com.fasterxml.jackson.core
jackson-databind
2.9.6
(6)JSON方法的测试
public static void main(String[] args) {
User user = new User(“Jack”,21);
//序列化
String struser = toString(user);
System.out.println(struser);
//反序列化
User usertobean = toBean(struser,User.class);
System.out.println(usertobean);
//toList
String json = “[20 , -10 , 5 , 15]”;
List list = toList(json,Integer.class);
System.out.println(“list:”+list);
//toMap
String json2 = “{“name”: “Jack”,“age”: “21”}”;
Map<String,String> map = toMap(json2,String.class,String.class);
System.out.println(“Map:”+map);
System.out.println(“===============================”);
String json3 = “[{“name”: “Jack”,“age”: “21”},{“name”: “zhangsan”,“age”: “18”}]”;
List<Map<String,String>> maps = nativeRead(json3, new TypeReference<List<Map<String,String>>>() {});
for (Map<String, String> stringStringMap : maps) {
System.out.println(“stringStringMap:”+stringStringMap);
}
}
运行结果
在项日中出现异常是在所难免的,但是出现异常后怎么处理,这就很有学问了。
1、场景预设
(1)场景
我们预设这样一个场景,假如我们做新增商品,需要接收下面的参数;
price:价格
nane:名称
然后对数据做简单校验;
价格不能为空
新增时,白动形成lD,后随商品对象一起返回
(2)创建实体类
package com.leyou.item.pojo;
import lombok.Data;
@Data
public class Item {
private Integer id;
private String name;
private Long price;
}
(3)创建实体类
package com.leyou.item.service;
import com.leyou.item.pojo.Item;
import org.springframework.stereotype.Service;
import java.util.Random;
@Service
public class ItemService {
public Item saveItem(Item item){
int id = new Random().nextInt();
item.setId(id);
return item;
}
}
package com.leyou.item.web;
import com.leyou.item.pojo.Item;
import com.leyou.item.service.ItemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController //声明当前类是控制层,服务请求相当于Servlet
@RequestMapping(“item”) //设置其对应的访问的映射名称,也就是当前Servlet的别名
public class itemController {
//注入Service
@Autowired
private ItemService itemService;
@PostMapping //拦截post请求,可以设置其对应的映射方法的路径
public ResponseEntity saveItem(Item item){//ResponseEntity设置返回状态码类型
//业务逻辑做校验
//校验价格
if(item.getPrice() == null){
//请求失败返回状态码400,设置其内容是空
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
}
item = itemService.saveItem(item);
//设置返回的是状态码类型的是201以及其类型是item类型
return ResponseEntity.status(HttpStatus.CREATED).body(item);
}
}
a、启动测试项目
b、使用Insomnia用于测试发送网络请求
链接:https://pan.baidu.com/s/1_aqtJRIAGmPF83CUh4CWQA
提取码:kr9h
下载并安装
起个名字
选择请求访问和访问路径,设置提交方式
返回正确结果
删除价格再次发送请求
请求失败并返回状态码
c、上述出现异常没有友好提示设置对应其提示
if(item.getPrice() == null){
//请求失败返回状态码400,设置其内容是空
throw new RuntimeException(“价格不能为空”);
}
重新启动测试并运行
上述返回方式不正确
2、统一异常处理(统一拦截Controller)
(1)创建CommonExceptionHandler
修改一下包路径
(2)完善CommonExceptionHandler类前,先在这里引入SpringMVC的依赖
<project xmlns=“http://maven.apache.org/POM/4.0.0”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>
leyou
com.leyou.parent
1.0.0-SNAPSHOT
4.0.0
com.leyou.common
ly-common
org.apache.tomcat.embed
tomcat-embed-core
org.springframework.boot
spring-boot-starter-logging
com.fasterxml.jackson.core
jackson-databind
org.springframework
spring-web
(3)完善CommonExceptionHandler类
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
leyou
com.leyou.parent
1.0.0-SNAPSHOT
4.0.0
com.leyou.common
ly-common
org.apache.tomcat.embed
tomcat-embed-core
org.springframework.boot
spring-boot-starter-logging
com.fasterxml.jackson.core
jackson-databind
org.springframework
spring-web
(3)完善CommonExceptionHandler类
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-LGAlbybW-1715532776037)]
[外链图片转存中…(img-G0ECfjCw-1715532776038)]
[外链图片转存中…(img-KxQHpM6k-1715532776038)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!