海量数据处理商用短链接生成器平台 - 2

第二章 短链平台项目创建+git代码管理+开发分层规范

第1集 短链平台实战-Maven聚合工程创建微服务项目

**简介:Maven聚合工程创建微服务项目实战 **

  • Maven聚合工程拆分

    • dcloud-common
      • 公共依赖包
    • dcloud-app
      • Flink+Kafka实时计算
    • dcloud-account
      • 账号+流量包微服务
    • dcloud-data
      • 数据可视化微服务
    • dcloud-gateway
      • 业务网关
    • dcloud-link
      • 短链微服务
    • dcloud-shop
      • 流量包商品+支付微服务
  • 创建项目(记得删除聚合工程src目录)

  • 添加依赖

  <properties><!--JDK版本,如果是jdk8则这里是 1.8--><java.version>11</java.version><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target><spring.boot.version>2.5.5</spring.boot.version><spring.cloud.version>2020.0.4</spring.cloud.version><alibaba.cloud.version>2021.1</alibaba.cloud.version><mybatisplus.boot.starter.version>3.4.0</mybatisplus.boot.starter.version><lombok.version>1.18.16</lombok.version><commons.lang3.version>3.9</commons.lang3.version><commons.codec.version>1.15</commons.codec.version><xxl-job.version>2.3.0</xxl-job.version><aliyun.oss.version>3.10.2</aliyun.oss.version><captcha.version>1.1.0</captcha.version><docker.image.prefix>dcloud</docker.image.prefix><redission.version>3.10.1</redission.version><jwt.version>0.7.0</jwt.version><sharding-jdbc.version>4.1.1</sharding-jdbc.version><!--跳过单元测试--><skipTests>true</skipTests><junit.version>4.12</junit.version><druid.version>1.1.16</druid.version></properties><!--锁定版本--><dependencyManagement><dependencies><!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-dependencies/2.3.3.RELEASE--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring.boot.version}</version><type>pom</type><scope>import</scope></dependency><!--https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies/Hoxton.SR8--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring.cloud.version}</version><type>pom</type><scope>import</scope></dependency><!--https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-alibaba-dependencies/2.2.1.RELEASE--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${alibaba.cloud.version}</version><type>pom</type><scope>import</scope></dependency><!--mybatis plus和springboot整合--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatisplus.boot.starter.version}</version></dependency><!--https://mvnrepository.com/artifact/org.projectlombok/lombok/1.18.16--><!--scope=provided,说明它只在编译阶段生效,不需要打入包中, Lombok在编译期将带Lombok注解的Java文件正确编译为完整的Class文件--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version><!--<scope>provided</scope>--></dependency><!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>${commons.lang3.version}</version></dependency><!-- https://mvnrepository.com/artifact/commons-codec/commons-codec --><!--用于加密--><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>${commons.codec.version}</version></dependency><!--验证码kaptcha依赖包--><dependency><groupId>com.baomidou</groupId><artifactId>kaptcha-spring-boot-starter</artifactId><version>${captcha.version}</version></dependency><!--阿里云oss--><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>${aliyun.oss.version}</version></dependency><!-- JWT相关 --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>${jwt.version}</version></dependency><!--分布式锁--><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>${redission.version}</version></dependency><!--https://mvnrepository.com/artifact/org.apache.shardingsphere/sharding-jdbc-spring-boot-starter--><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>${sharding-jdbc.version}</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version></dependency><!-- https://mvnrepository.com/artifact/com.xuxueli/xxl-job-core --><dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>${xxl-job.version}</version></dependency></dependencies></dependencyManagement><!-- 代码库 --><repositories><repository><id>maven-ali</id><url>http://maven.aliyun.com/nexus/content/groups/public//</url><releases><enabled>true</enabled></releases><snapshots><enabled>true</enabled><updatePolicy>always</updatePolicy><checksumPolicy>fail</checksumPolicy></snapshots></repository></repositories><pluginRepositories><pluginRepository><id>public</id><name>aliyun nexus</name><url>http://maven.aliyun.com/nexus/content/groups/public/</url><releases><enabled>true</enabled></releases><snapshots><enabled>false</enabled></snapshots></pluginRepository></pluginRepositories><!--module不用添加打包版本信息--><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>2.1</version><configuration><skip>true</skip></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring.boot.version}</version><configuration><fork>true</fork><addResources>true</addResources></configuration></plugin></plugins></build>

第2集 Gitee仓库介绍和项目纳入版本管理+ignore文件配置

简介:开源中国Gitee仓库-介绍和项目纳入版本管理+ignore文件配置置

  • Git介绍

    • 是一个版本管理工具, 其作用就是可以让你更好的管理你的程序,比如你原来提交过的内容,以后虽然修改了,但是通过git这个工具,可以把你原来提交的内容重现出来,这样对于你后来才意识到的一些错误的更改,可以进行还原
  • 基于git协议的代码仓库

    • github 全球最大同性交友社区
    • gitee 开源中国
    • gitlab 开源的git仓库平台,阿里等大厂就是基于这个搭建
    • codeup 阿里云上的免费git仓库
  • gitee仓库地址

    • https://gitee.com/
  • 大课项目必须用git吗?

    • 如果是因为不会git,而不用则不行,因为这个是互联网公司必备的
    • 可以看联系客服看小滴课堂 git+gitlab专题视频
  • 本地安装文档

    • https://www.runoob.com/git/git-install-setup.html
    • https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A3%85-Git
  • 大课项目加入git管理(是公钥设置,不是秘钥设置)

    • 本地生成公钥 ssh-keygen -t rsa -C “794666918@qq.com”
      • 生成公钥文档:https://gitee.com/help/articles/4181
      • 设置公钥文档:https://gitee.com/help/articles/4191#article-header0
    • 进入项目目录
  • 配置gitignore文件

    • 根目录创建文件 .gitignore
# Compiled class file
*.class# Log file
*.log# BlueJ files
*.ctxt# Mobile Tools for Java (J2ME)
.mtj.tmp/# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
.DS_Store
.idea
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

在这里插入图片描述

第3集 阿里编码规范里面Manager分层介绍-和开发规范说明

简介:阿里编码规范里面Manager分层介绍-专用名词和POJO实体类约定

  • 开发人员:张三、李四、王五

  • 一定要避免单点故障

    • 一个微服务起码两个人熟悉:一个是主程一个是技术leader ,推荐是团队里面两个开发人员
  • N方库说明

一方库: 本工程内部子项目模块依赖的库(jar 包)二方库: 公司内部发布到中央仓库,可供公司内部其它应用依赖的库(jar包)三方库: 公司之外的开源库(jar 包)
  • POJO实体类
POJO(Plain Ordinary Java Object): 在手册中,POJO 专指只有 setter / getter / toString的简单类,包括DO/DTO/BO/VO等, 禁止命名成xxxPOJO
  • 各个层级约束规范
A) Service/DAO层方法命名规约1) 获取单个对象的方法用get做前缀。2) 获取多个对象的方法用list做前缀,复数形式结尾如:listObjects。 3) 获取统计值的方法用count做前缀。4) 插入的方法用save/insert做前缀。5) 删除的方法用remove/delete做前缀。6) 修改的方法用update做前缀。B) 领域模型命名规约1) 数据对象:xxxDO,xxx即为数据表名。2) 一般数据传输对象:xxxDTO,xxx为业务领域相关的名称,项目里面也用VO。 3) 展示对象:xxxVO,也就是响应给前端的实体包装类。4) 接收前端json对象请求的命名为 XXXRequest
  • Manager分层说明 通用业务处理层,它有如下特征
    • 对第三方平台封装的层,预处理返回结果及转化异常信息
    • 对Service层通用能力的下沉,如缓存方案、中间件通用处理;
    • 与DAO层交互,对多个DAO的组合复用。

在这里插入图片描述

  • 更多开发规范,可以参考阿里巴巴编码手册(资料里面有 第6章第3集资料里面)
    • 有兴趣也可以安装IDEA编码扫描插件,不过前期可以先不用开启,会影响电脑卡顿和强迫症

第4集 dcloud-common通用模块配置使用实战和新版改动

简介:短链平台dcloud-common通用模块配置使用实战

  • pom文件配置
    <dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--项目中添加 spring-boot-starter--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--数据库连接--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--mybatis plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!--单元测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><!--redis客户端--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusions><exclusion><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId></exclusion></exclusions></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency><!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency><!--用于加密--><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId></dependency><!-- JWT相关 --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId></dependency><!--redisson分布式锁--><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId></dependency><!--Hoxton.M2版本之后不再使用Ribbon而是使用spring-cloud-loadbalancer,所以不引入spring-cloud-loadbalancer会报错,所以加入spring-cloud-loadbalancer依赖 并且在nacos中排除ribbon依赖,不然loadbalancer无效 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><exclusions><exclusion><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency><!--配置中心, 留坑,后续用的时候再讲--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!--Feign远程调用--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!--限流依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><!--限流持久化到nacos--><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId></dependency><!--Springboot项目整合spring-kafka依赖包配置--><dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId></dependency><!--引入AMQP--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><!--spring cache依赖包--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId></dependency><!-- https://mvnrepository.com/artifact/com.xuxueli/xxl-job-core --><!--分布式调度--><dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency></dependencies>

第5集 统一接口响应协议-响应工具类封装

简介:统一接口响应协议和响应工具类封装

  • 统一业务状态码 BizCodeEnum开发
    • 状态码定义约束,共6位数,前三位代表服务,后3位代表接口
    • 比如 商品服务210
/*** ** @Description 状态码定义约束,共6位数,前三位代表服务,后3位代表接口*  比如 商品服务210,购物车是220、用户服务230,403代表权限***/
public enum BizCodeEnum {/*** 短链分组*/GROUP_REPEAT(23001,"分组名重复"),GROUP_OPER_FAIL(23503,"分组名操作失败"),GROUP_NOT_EXIST(23404,"分组不存在"),/***验证码*/CODE_TO_ERROR(240001,"接收号码不合规"),CODE_LIMITED(240002,"验证码发送过快"),CODE_ERROR(240003,"验证码错误"),CODE_CAPTCHA_ERROR(240101,"图形验证码错误"),/*** 账号*/ACCOUNT_REPEAT(250001,"账号已经存在"),ACCOUNT_UNREGISTER(250002,"账号不存在"),ACCOUNT_PWD_ERROR(250003,"账号或者密码错误"),ACCOUNT_UNLOGIN(250004,"账号未登录"),/*** 短链*/SHORT_LINK_NOT_EXIST(260404,"短链不存在"),/*** 订单*/ORDER_CONFIRM_PRICE_FAIL(280002,"创建订单-验价失败"),ORDER_CONFIRM_REPEAT(280008,"订单恶意-重复提交"),ORDER_CONFIRM_TOKEN_EQUAL_FAIL(280009,"订单令牌缺少"),ORDER_CONFIRM_NOT_EXIST(280010,"订单不存在"),/*** 支付*/PAY_ORDER_FAIL(300001,"创建支付订单失败"),PAY_ORDER_CALLBACK_SIGN_FAIL(300002,"支付订单回调验证签失败"),PAY_ORDER_CALLBACK_NOT_SUCCESS(300003,"支付宝回调更新订单失败"),PAY_ORDER_NOT_EXIST(300005,"订单不存在"),PAY_ORDER_STATE_ERROR(300006,"订单状态不正常"),PAY_ORDER_PAY_TIMEOUT(300007,"订单支付超时"),/*** 流控操作*/CONTROL_FLOW(500101,"限流控制"),CONTROL_DEGRADE(500201,"降级控制"),CONTROL_AUTH(500301,"认证控制"),/*** 流量包操作*/TRAFFIC_FREE_NOT_EXIST(600101,"免费流量包不存在,联系客服"),TRAFFIC_REDUCE_FAIL(600102,"流量不足,扣减失败"),TRAFFIC_EXCEPTION(600103,"流量包数据异常,用户无流量包"),/*** 通用操作码*/OPS_REPEAT(110001,"重复操作"),OPS_NETWORK_ADDRESS_ERROR(110002,"网络地址错误"),/*** 文件相关*/FILE_UPLOAD_USER_IMG_FAIL(700101,"用户头像文件上传失败");@Getterprivate String message;@Getterprivate int code;private BizCodeEnum(int code, String message){this.code = code;this.message = message;}
}
  • 接口统一协议 JsonData工具类开发
@Data
@AllArgsConstructor
@NoArgsConstructor
public class JsonData {/*** 状态码 0 表示成功*/private Integer code;/*** 数据*/private Object data;/*** 描述*/private String msg;/***  获取远程调用数据*  注意事项:*      支持多单词下划线专驼峰(序列化和反序列化)*** @param typeReference* @param <T>* @return*/public <T> T getData(TypeReference<T> typeReference){return JSON.parseObject(JSON.toJSONString(data),typeReference);}/*** 成功,不传入数据* @return*/public static JsonData buildSuccess() {return new JsonData(0, null, null);}/***  成功,传入数据* @param data* @return*/public static JsonData buildSuccess(Object data) {return new JsonData(0, data, null);}/*** 失败,传入描述信息* @param msg* @return*/public static JsonData buildError(String msg) {return new JsonData(-1, null, msg);}/*** 自定义状态码和错误信息* @param code* @param msg* @return*/public static JsonData buildCodeAndMsg(int code, String msg) {return new JsonData(code, null, msg);}/*** 传入枚举,返回信息* @param codeEnum* @return*/public static JsonData buildResult(BizCodeEnum codeEnum){return JsonData.buildCodeAndMsg(codeEnum.getCode(),codeEnum.getMessage());}
}

第6集 微服务自定义全局异常+处理器handler开发

简介:自定义全局异常+处理器开发

  • 自定义全局异常
/*** 全局异常处理*/
@Data
public class BizException extends RuntimeException {private Integer code;private String msg;public BizException(Integer code, String message) {super(message);this.code = code;this.msg = message;}public BizException(BizCodeEnum bizCodeEnum) {super(bizCodeEnum.getMsg());this.code = bizCodeEnum.getCode();this.msg = bizCodeEnum.getMsg();}}
  • 自定义异常处理器
@ControllerAdvice
@Slf4j
public class ExceptionHandle {@ExceptionHandler(value = Exception.class)@ResponseBodypublic JsonData handle(Exception e) {if (e instanceof BizException) {BizException bizException = (BizException) e;log.info("[业务异常]{}", e);return JsonData.buildError(bizException.getMsg(), bizException.getCode());} else {log.info("[系统异常]{}", e);return JsonData.buildError("全局异常,未知错误");}}
}

第7集 common通用工具和时间格式化工具类

简介:common通用工具和时间格式化工具类讲解

  • 时间格式化工具类封装
public class TimeUtil {/*** 默认日期格式*/private static final String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss";/*** 默认日期格式*/private static final DateTimeFormatter DEFAULT_DATE_TIME_FORMATTER  = DateTimeFormatter.ofPattern(DEFAULT_PATTERN);private static final  ZoneId DEFAULT_ZONE_ID = ZoneId.systemDefault();/*** LocalDateTime 转 字符串,指定日期格式* @param time* @param pattern* @return*/public static String format(LocalDateTime localDateTime,String pattern){DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);String timeStr = formatter.format(localDateTime.atZone(DEFAULT_ZONE_ID));return timeStr;}/*** Date 转 字符串, 指定日期格式* @param time* @param pattern* @return*/public static String format(Date time,String pattern){DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);String timeStr = formatter.format(time.toInstant().atZone(DEFAULT_ZONE_ID));return timeStr;}/***  Date 转 字符串,默认日期格式* @param time* @return*/public static String format(Date time){String timeStr = DEFAULT_DATE_TIME_FORMATTER.format(time.toInstant().atZone(DEFAULT_ZONE_ID));return timeStr;}/*** timestamp 转 字符串,默认日期格式** @param time* @return*/public static String format(long timestamp) {String timeStr = DEFAULT_DATE_TIME_FORMATTER.format(new Date(timestamp).toInstant().atZone(DEFAULT_ZONE_ID));return timeStr;}/*** 字符串 转 Date** @param time* @return*/public static Date strToDate(String time) {LocalDateTime localDateTime = LocalDateTime.parse(time, DEFAULT_DATE_TIME_FORMATTER);return Date.from(localDateTime.atZone(DEFAULT_ZONE_ID).toInstant());}/*** 获取当天剩余的秒数,用于流量包过期配置* @param currentDate* @return*/public static Integer getRemainSecondsOneDay(Date currentDate) {LocalDateTime midnight = LocalDateTime.ofInstant(currentDate.toInstant(),ZoneId.systemDefault()).plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);LocalDateTime currentDateTime = LocalDateTime.ofInstant(currentDate.toInstant(),ZoneId.systemDefault());long seconds = ChronoUnit.SECONDS.between(currentDateTime, midnight);return (int) seconds;}
}
  • Json序列化工具类封装
public class JsonUtil {private static final ObjectMapper mapper = new ObjectMapper();static {//设置可用单引号mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);//序列化的时候序列对象的所有属性mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);//反序列化的时候如果多了其他属性,不抛出异常mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);//如果是空对象的时候,不抛异常mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);//取消时间的转化格式,默认是时间戳,可以取消,同时需要设置要表现的时间格式mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));}/*** 对象转为Json字符串* @param data* @return*/public static String obj2Json(Object obj) {String jsonStr = null;try {jsonStr = mapper.writeValueAsString(obj);} catch (JsonProcessingException e) {e.printStackTrace();}return jsonStr;}/*** json字符串转为对象* @param str* @param valueType* @return*/public static <T> T json2Obj(String jsonStr, Class<T> beanType) {T obj = null;try {obj = mapper.readValue(jsonStr, beanType);} catch (Exception e){e.printStackTrace();}return obj;}/*** json数据转换成pojo对象list* @param jsonData* @param beanType* @return*/public static <T> List<T> json2List(String jsonData, Class<T> beanType) {JavaType javaType = mapper.getTypeFactory().constructParametricType(List.class, beanType);try {List<T> list = mapper.readValue(jsonData, javaType);return list;} catch (Exception e) {e.printStackTrace();}return null;}/*** 对象转为byte数组* @param data* @return*/public static byte[] obj2Bytes(Object obj) {byte[] byteArr = null;try {byteArr = mapper.writeValueAsBytes(obj);} catch (JsonProcessingException e) {e.printStackTrace();}return byteArr;}/*** byte数组转为对象* @param byteArr* @param valueType* @return*/public static <T> T bytes2Obj(byte[] byteArr, Class<T> beanType) {T obj = null;try {obj = mapper.readValue(byteArr, beanType);} catch (Exception e) {e.printStackTrace();}return obj;}}
  • common工具大集合
@Slf4j
public class CommonUtil {/*** 获取ip** @param request* @return*/public static String getIpAddr(HttpServletRequest request) {String ipAddress = null;try {ipAddress = request.getHeader("x-forwarded-for");if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("WL-Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getRemoteAddr();if (ipAddress.equals("127.0.0.1")) {// 根据网卡取本机配置的IPInetAddress inet = null;try {inet = InetAddress.getLocalHost();} catch (UnknownHostException e) {e.printStackTrace();}ipAddress = inet.getHostAddress();}}// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割if (ipAddress != null && ipAddress.length() > 15) {// "***.***.***.***".length()// = 15if (ipAddress.indexOf(",") > 0) {ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));}}} catch (Exception e) {ipAddress = "";}return ipAddress;}/*** 获取全部请求头* @param request* @return*/public static Map<String, String> getAllRequestHeader(HttpServletRequest request){Enumeration<String> headerNames = request.getHeaderNames();Map<String, String> map = new HashMap<>();while (headerNames.hasMoreElements()) {String key = (String)headerNames.nextElement();//根据名称获取请求头的值String value = request.getHeader(key);map.put(key,value);}return map;}/*** MD5加密** @param data* @return*/public static String MD5(String data) {try {MessageDigest md = MessageDigest.getInstance("MD5");byte[] array = md.digest(data.getBytes("UTF-8"));StringBuilder sb = new StringBuilder();for (byte item : array) {sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));}return sb.toString().toUpperCase();} catch (Exception exception) {}return null;}/*** 获取验证码随机数** @param length* @return*/public static String getRandomCode(int length) {String sources = "0123456789";Random random = new Random();StringBuilder sb = new StringBuilder();for (int j = 0; j < length; j++) {sb.append(sources.charAt(random.nextInt(9)));}return sb.toString();}/*** 获取当前时间戳** @return*/public static long getCurrentTimestamp() {return System.currentTimeMillis();}/*** 生成uuid** @return*/public static String generateUUID() {return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);}/*** 获取随机长度的串** @param length* @return*/private static final String ALL_CHAR_NUM = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";public static String getStringNumRandom(int length) {//生成随机数字和字母,Random random = new Random();StringBuilder saltString = new StringBuilder(length);for (int i = 1; i <= length; ++i) {saltString.append(ALL_CHAR_NUM.charAt(random.nextInt(ALL_CHAR_NUM.length())));}return saltString.toString();}/*** 响应json数据给前端** @param response* @param obj*/public static void sendJsonMessage(HttpServletResponse response, Object obj) {response.setContentType("application/json; charset=utf-8");try (PrintWriter writer = response.getWriter()) {writer.print(JsonUtil.obj2Json(obj));response.flushBuffer();} catch (IOException e) {log.warn("响应json数据给前端异常:{}",e);}}}

c String generateUUID() {
return UUID.randomUUID().toString().replaceAll(“-”, “”).substring(0, 32);
}

/*** 获取随机长度的串** @param length* @return*/
private static final String ALL_CHAR_NUM = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";public static String getStringNumRandom(int length) {//生成随机数字和字母,Random random = new Random();StringBuilder saltString = new StringBuilder(length);for (int i = 1; i <= length; ++i) {saltString.append(ALL_CHAR_NUM.charAt(random.nextInt(ALL_CHAR_NUM.length())));}return saltString.toString();
}/*** 响应json数据给前端** @param response* @param obj*/
public static void sendJsonMessage(HttpServletResponse response, Object obj) {response.setContentType("application/json; charset=utf-8");try (PrintWriter writer = response.getWriter()) {writer.print(JsonUtil.obj2Json(obj));response.flushBuffer();} catch (IOException e) {log.warn("响应json数据给前端异常:{}",e);}}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/666209.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一分钟了解电脑关机快捷键是什么!

在日常使用电脑的过程中&#xff0c;了解一些基本的快捷键是提高效率的关键之一。其中&#xff0c;电脑关机快捷键是一个方便且迅速的操作&#xff0c;使您可以在不用通过烦琐的菜单操作的情况下&#xff0c;快速关机电脑。在本文中&#xff0c;我们将探讨电脑关机快捷键是什么…

C++初阶:适合新手的手撕string类(模拟实现string类)

上次讲了常用的接口&#xff1a;C初阶&#xff1a;初识STL、String类接口详细讲解&#xff08;万字解析&#xff09; 今天就来进行模拟实现啦 文章目录 1.基本结构与文件规划2.构造函数&#xff08;constructor)2.1构造函数2.1.1无参有参分开2.1.2利用缺省参数合起来 2.2拷贝构…

Pyecharts炫酷散点图构建指南【第50篇—python:炫酷散点图】

文章目录 Pyecharts炫酷散点图构建指南引言安装Pyecharts基础散点图自定义散点图样式渐变散点图动态散点图高级标注散点图多系列散点图3D散点图时间轴散点图笛卡尔坐标系下的极坐标系散点图 总结&#xff1a; Pyecharts炫酷散点图构建指南 引言 在数据可视化领域&#xff0c;…

[C++]:15.继承

继承 一.继承&#xff1a;1.继承的概念和基本操作&#xff1a;1.概念&#xff1a;2.基本操作&#xff1a; 2.继承格式和多种继承方法&#xff1a;1.基本继承格式&#xff1a;2.继承关系访问限定符 3.子类对象和父类对象之间的赋值&#xff1a;1.为什么存在赋值兼容转换&#xf…

第十二篇【传奇开心果系列】Python的OpenCV技术点案例示例:视频流处理

传奇开心果短博文系列 系列短博文目录Python的OpenCV技术点案例示例短博文系列短博文目录一、前言二、视频流处理介绍三、实时视频流处理示例代码四、视频流分析示例代码五、归纳总结系列短博文目录 Python的OpenCV技术点案例示例短博文系列 短博文目录 一、前言 OpenCV视频…

程序报错无法打开源文件stdafx.h

在运行代码时&#xff0c;代码中头文件突然报错程序无法打开源文件stdafx.h include “stdafx.h”,编译器就说无法打开源文件&#xff0c;直接上干货解决方法是&#xff1a; 1.打开项目 ->项目属性&#xff08;最后一个&#xff09;-> C/C ->常规&#xff0c; 2在附…

【工作周志】240129-240204

本周学习了AXI相关的内容 AMBA &#xff08;Advanced Microcontroller Bus Architecture&#xff09; AXI &#xff08;Advanced eXtensible Interface&#xff09; ARM公司提出&#xff0c;AMBA3.0协议中重要组成部分&#xff0c;是一种面向高性能、高带宽、低延迟的片内总线…

【c++】vector用法详解

vector用法详解 vector定义vector容器的构造函数vector容器内元素的访问1.通过下标 [ ]来访问2.通过迭代器来访问3.通过范围for来访问 vector常用函数的用法解析1.size()2.clear()3.capacity()4.reserve()5.resize()6.shrink_to_fit()7.pop_back()8.push_back()9.erase()10.in…

python基于django的公交线路查询系统mf383

1.个人信息的管理&#xff1a;对用户名&#xff0c;密码的增加、删除等 2.线路信息的管理&#xff1a;对线路的增加、修改、删除等 3.站点信息的管理&#xff1a;对站点的增加、修改、删除等 4.车次信息的管理&#xff1a;对车次的增加、修改、删除等 5.线路查询、站点查询 …

已解决: ModuleNotFoundError: No module named ‘tensorflow‘ 问题

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

nba2k24 球魁面补【23-24通用】

nba2k24 球魁面补 nba2k23-nba2k24通用 球魁面补 下载地址&#xff1a; https://www.changyouzuhao.cn/9841.html

蓝桥杯省赛无忧 课件91 高斯消元

01 算法概述 02 问题引入 03 算法分析 04 例题

Linux 多线程 | 线程的概念

线程的概念 线程是一个执行分支&#xff0c;执行粒度比进程更细&#xff0c;调度成本更低&#xff1b; 线程是进程内部的一个执行流&#xff1b; 线程是CPU调度的基本单位&#xff0c;进程是承担分配系统资源的基本实体。 之前我们学习过虚拟地址空间的知识&#xff0c;知道…

NetSuite 权限不足用户如何查询完整数据

假设我们做了一个Saved Search&#xff0c;用于统计所有涉及库存的事务类型&#xff0c;包括出入库、库存调整、生产报工、拆解、Standalone Invoice和Bill&#xff0c;等等。通过合计这些事务类型&#xff0c;我们就可以得到一个存货报表&#xff0c;能够得到任一时间点的库存…

线程同步解析

一 线程同步 1 同步的意义 现实中抢票可能没票了还在抢票&#xff0c;然后线程就会一直在加锁解锁&#xff0c;就会导致其它线程抢不到锁而产生饥饿问题&#xff0c;我们前面也提过usleep就是让线程被切换&#xff0c;能让其它线程去申请锁&#xff0c;这种方式并不好&#xf…

蓝桥杯备战——13.PCF8591芯片的使用

目录 1.芯片简介2.读写时序3.控制字4.代码封装库5.原理图分析6.使用示例 1.芯片简介 截取自NXP的PCF8591芯片数据手册&#xff0c;我把重点关注部分划出来了&#xff0c;请务必自行阅读一遍数据手册&#xff01; 2.读写时序 ①器件地址&#xff1a; Bit0决定是读还是写操作&…

最新GPT4.0使用教程,AI绘画,GPT语音对话使用,DALL-E3文生图

一、前言 ChatGPT3.5、GPT4.0、GPT语音对话、Midjourney绘画&#xff0c;文档对话总结DALL-E3文生图&#xff0c;相信对大家应该不感到陌生吧&#xff1f;简单来说&#xff0c;GPT-4技术比之前的GPT-3.5相对来说更加智能&#xff0c;会根据用户的要求生成多种内容甚至也可以和…

优质成长:新生儿补充维生素B6的关键注意事项

引言&#xff1a; 维生素B6&#xff0c;作为B族维生素的一员&#xff0c;对于新生儿的神经系统发育和代谢功能至关重要。本文将深入探讨维生素B6的作用、新生儿补充的必要性&#xff0c;以及在补充维生素B6时应该注意的事项&#xff0c;为父母提供科学、全面的育儿指南。 第一…

WebChat——一个开源的聊天应用

Web Chat 是开源的聊天系统&#xff0c;支持一键免费部署私人Chat网页的应用程序。 目录树 TOC &#x1f44b;&#x1f3fb; 开始使用 & 交流&#x1f6f3; 开箱即用 A 使用 Docker 部署B 使用 Docker-compose 部署C 使用 Jar包 本地部署 ⌨️ 本地开发&#x1f91d; 参与…

开源浏览器Firefox:使用Docker本地部署并远程访问进行测试

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;网络奇遇记、数据结构 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. 部署Firefox二. 本地访问Firefox三. Linux安装Cpolar四. 配置Firefox公网地址…