From 1f438655f509763e112978446778b5c34326f5cf Mon Sep 17 00:00:00 2001 From: qyx <565485304@qq.com> Date: Wed, 14 Apr 2021 18:03:59 +0800 Subject: [PATCH] =?UTF-8?q?[=E5=85=B6=E4=BB=96=E6=8F=90=E4=BA=A4](master):?= =?UTF-8?q?=20=E7=BB=93=E6=9E=84=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更改项目工程框架设计; 完成视图层代码设计; 完成流程逻辑框架编写; --- pom.xml | 63 ++++-- short-server-api/.gitignore | 189 ------------------ short-server-common/pom.xml | 12 ++ .../java/com/by/constants/SystemConstant.java | 7 + .../pom.xml | 22 +- .../main/java/com/by/dto/ShortChainDTO.java | 23 +++ short-server-service/pom.xml | 16 ++ .../by/api/ShortServerOpenApiController.java | 63 ++++++ .../com/by/api/common/CommonResponse.java | 132 ++++++++++++ .../java/com/by/api/common/ResponseCode.java | 48 +++++ .../api/constants/RequestDetailConstant.java | 11 + .../api/convert/ShortChainVOToDTOConvert.java | 51 +++++ .../api/exception/GlobalExceptionHandle.java | 34 ++++ .../com/by/api/vo/ShortChainRequestVO.java | 30 +++ .../com/by/api/vo/ShortChainResponseVO.java | 19 ++ .../java/com/by/dao/ShortUrlRepository.java | 11 + .../src/main/java/com/by/entity/ShortUrl.java | 75 +++++++ .../com/by/service/ShortServerService.java | 25 +++ .../service/impl/ShortServerServiceImpl.java | 41 ++++ .../main/java/com/by/task/ShortChainTask.java | 30 +++ .../com/by/task/conf/ThreadPoolConfig.java | 54 +++++ .../src/main/resources/application-dev.yml | 2 +- .../src/main/resources/application-prod.yml | 2 +- .../src/main/resources/application.yml | 9 + sql/t_short_url.sql | 28 +++ 25 files changed, 763 insertions(+), 234 deletions(-) delete mode 100644 short-server-api/.gitignore create mode 100644 short-server-common/src/main/java/com/by/constants/SystemConstant.java rename {short-server-api => short-server-pojo}/pom.xml (57%) create mode 100644 short-server-pojo/src/main/java/com/by/dto/ShortChainDTO.java create mode 100644 short-server-service/src/main/java/com/by/api/ShortServerOpenApiController.java create mode 100644 short-server-service/src/main/java/com/by/api/common/CommonResponse.java create mode 100644 short-server-service/src/main/java/com/by/api/common/ResponseCode.java create mode 100644 short-server-service/src/main/java/com/by/api/constants/RequestDetailConstant.java create mode 100644 short-server-service/src/main/java/com/by/api/convert/ShortChainVOToDTOConvert.java create mode 100644 short-server-service/src/main/java/com/by/api/exception/GlobalExceptionHandle.java create mode 100644 short-server-service/src/main/java/com/by/api/vo/ShortChainRequestVO.java create mode 100644 short-server-service/src/main/java/com/by/api/vo/ShortChainResponseVO.java create mode 100644 short-server-service/src/main/java/com/by/dao/ShortUrlRepository.java create mode 100644 short-server-service/src/main/java/com/by/entity/ShortUrl.java create mode 100644 short-server-service/src/main/java/com/by/service/ShortServerService.java create mode 100644 short-server-service/src/main/java/com/by/service/impl/ShortServerServiceImpl.java create mode 100644 short-server-service/src/main/java/com/by/task/ShortChainTask.java create mode 100644 short-server-service/src/main/java/com/by/task/conf/ThreadPoolConfig.java create mode 100644 sql/t_short_url.sql diff --git a/pom.xml b/pom.xml index 6bb2cbc..d8cda14 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ short-server-common short-server-service - short-server-api + short-server-pojo @@ -31,31 +31,50 @@ 1.1.22 1.5.21 5.3.4 + 1.2.73 + 1.18.16 + 3.8.1 - + + + + + io.swagger + swagger-annotations + ${swagger.version} + + + io.swagger + swagger-models + ${swagger.version} + + + + + cn.hutool + hutool-all + ${hutool.version} + + + com.alibaba + fastjson + ${fastjson.version} + + + org.projectlombok + lombok + ${lombok.version} + + + org.apache.commons + commons-lang3 + ${common-lang3.version} + + + - - - io.swagger - swagger-annotations - ${swagger.version} - - - io.swagger - swagger-models - ${swagger.version} - - - - - - cn.hutool - hutool-all - ${hutool.version} - - diff --git a/short-server-api/.gitignore b/short-server-api/.gitignore deleted file mode 100644 index 864e6e2..0000000 --- a/short-server-api/.gitignore +++ /dev/null @@ -1,189 +0,0 @@ -# Created by .ignore support plugin (hsz.mobi) - -### project -log/ - -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# Generated files -.idea/**/contentModel.xml - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -# .idea/artifacts -# .idea/compiler.xml -# .idea/jarRepositories.xml -# .idea/modules.xml -# .idea/*.iml -# .idea/modules -# *.iml -# *.ipr - -# CMake -cmake-build-*/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests - -# Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser - -### Maven template -target/ -pom.xml.tag -pom.xml.releaseBackup -pom.xml.versionsBackup -pom.xml.next -release.properties -dependency-reduced-pom.xml -buildNumber.properties -.mvn/timing.properties -# https://github.com/takari/maven-wrapper#usage-without-binary-jar -.mvn/wrapper/maven-wrapper.jar - -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# Generated files -.idea/**/contentModel.xml - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -# .idea/artifacts -# .idea/compiler.xml -# .idea/jarRepositories.xml -# .idea/modules.xml -# .idea/*.iml -# .idea/modules -# *.iml -# *.ipr - -# CMake -cmake-build-*/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests - -# Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser - -### Java template -# 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 - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* - diff --git a/short-server-common/pom.xml b/short-server-common/pom.xml index a4c5cc4..b5217e5 100644 --- a/short-server-common/pom.xml +++ b/short-server-common/pom.xml @@ -23,6 +23,18 @@ cn.hutool hutool-all + + com.alibaba + fastjson + + + org.projectlombok + lombok + + + org.apache.commons + commons-lang3 + \ No newline at end of file diff --git a/short-server-common/src/main/java/com/by/constants/SystemConstant.java b/short-server-common/src/main/java/com/by/constants/SystemConstant.java new file mode 100644 index 0000000..845e8d4 --- /dev/null +++ b/short-server-common/src/main/java/com/by/constants/SystemConstant.java @@ -0,0 +1,7 @@ +package com.by.constants; + +/** + * 系统常量声明 + */ +public class SystemConstant { +} diff --git a/short-server-api/pom.xml b/short-server-pojo/pom.xml similarity index 57% rename from short-server-api/pom.xml rename to short-server-pojo/pom.xml index 1612c02..c181009 100644 --- a/short-server-api/pom.xml +++ b/short-server-pojo/pom.xml @@ -7,10 +7,9 @@ com.by 1.0-SNAPSHOT - 4.0.0 - short-server-api + short-server-pojo 8 @@ -18,29 +17,10 @@ - com.by short-server-common 1.0-SNAPSHOT - - - - org.springframework.boot - spring-boot-starter-web - - - - - io.swagger - swagger-annotations - - - io.swagger - swagger-models - - - \ No newline at end of file diff --git a/short-server-pojo/src/main/java/com/by/dto/ShortChainDTO.java b/short-server-pojo/src/main/java/com/by/dto/ShortChainDTO.java new file mode 100644 index 0000000..554f00f --- /dev/null +++ b/short-server-pojo/src/main/java/com/by/dto/ShortChainDTO.java @@ -0,0 +1,23 @@ +package com.by.dto; + +import lombok.Data; + +import java.util.List; +import java.util.Set; + +/** + * @author q + */ +@Data +public class ShortChainDTO { + + /** + * 原始短链集合 + */ + private Set shortChainOrigins; + + /** + * 短链生成结果 + */ + private List shortChainResult; +} diff --git a/short-server-service/pom.xml b/short-server-service/pom.xml index b682dd1..369fc6d 100644 --- a/short-server-service/pom.xml +++ b/short-server-service/pom.xml @@ -24,6 +24,22 @@ short-server-common 1.0-SNAPSHOT + + com.by + short-server-pojo + 1.0-SNAPSHOT + + + + + io.swagger + swagger-annotations + + + io.swagger + swagger-models + + diff --git a/short-server-service/src/main/java/com/by/api/ShortServerOpenApiController.java b/short-server-service/src/main/java/com/by/api/ShortServerOpenApiController.java new file mode 100644 index 0000000..7212f91 --- /dev/null +++ b/short-server-service/src/main/java/com/by/api/ShortServerOpenApiController.java @@ -0,0 +1,63 @@ +package com.by.api; + +import cn.hutool.core.collection.CollectionUtil; +import com.by.api.common.CommonResponse; +import com.by.api.convert.ShortChainVOToDTOConvert; +import com.by.api.vo.ShortChainRequestVO; +import com.by.api.vo.ShortChainResponseVO; +import com.by.dto.ShortChainDTO; +import com.by.service.ShortServerService; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Controller; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; + +import java.util.List; + +/** + * @author q + */ +@Controller +@Slf4j +public class ShortServerOpenApiController { + + // TODO: 2021/4/14 0014 添加接口限流 + // TODO: 2021/4/14 0014 添加接口相关的验证 丰富VO层 加入 appid secret_key 及 时间戳验证 + + private final ShortServerService shortServerService; + + public ShortServerOpenApiController(ShortServerService shortServerService) { + this.shortServerService = shortServerService; + } + + @ApiOperation("批量生成短链接") + @PostMapping(value = "/trans") + @ResponseBody + public CommonResponse parseContentToShortChain(@Validated @RequestBody ShortChainRequestVO shortChainRequestVO) { + log.info("=== [ShortServerOpenApiController|parseContentToShortChain, one request is coming, request vo is {} ] ===", shortChainRequestVO.toString()); + + ShortChainDTO shortChainDTO = ShortChainVOToDTOConvert.convertShortChainRequestVOToDTO(shortChainRequestVO); + + shortChainDTO = shortServerService.handleOriginUrlsToShortUrls(shortChainDTO); + + List shortChainResult = shortChainDTO.getShortChainResult(); + + ShortChainResponseVO shortChainResponseVO = new ShortChainResponseVO(); + if (CollectionUtil.isNotEmpty(shortChainResult)){ + shortChainResponseVO.setShortChainResult(shortChainResult); + } + + return CommonResponse.createBySuccess(shortChainResponseVO); + } + + @ApiOperation("短链接兑换长链接并进行") + @GetMapping(value = "/redeem") + public ModelAndView redeemShortChainClick(@RequestParam(value = "a")String param){ + log.info("=== [ShortServerOpenApiController|redeemShortChainClick, one request is coming, request param is {} ] ===", param); + + return shortServerService.handleOnceShortUrlToRedirectOriginUrlAndRecord(param); + } + +} diff --git a/short-server-service/src/main/java/com/by/api/common/CommonResponse.java b/short-server-service/src/main/java/com/by/api/common/CommonResponse.java new file mode 100644 index 0000000..4e77014 --- /dev/null +++ b/short-server-service/src/main/java/com/by/api/common/CommonResponse.java @@ -0,0 +1,132 @@ +package com.by.api.common; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + + +/** + * + * JsonInclude.Include.NON_EMPTY 属性为 空("") 或者为 NULL 都不序列化,则返回的json是没有这个字段的。这样对移动端会更省流量 + * + * @param 返回的对象实体 + * @author q + */ +@JsonSerialize +@JsonInclude(JsonInclude.Include.NON_EMPTY) +@NoArgsConstructor +public class CommonResponse implements Serializable { + + /** + * 成功还是失败的状态标识 0,成功 1,失败 + */ + private int status; + + /** + * 返回信息 + */ + private String msg; + + /** + * 返回的结果数据 + */ + private T data; + + + /* + * 封装所有的构造器为私有的 + */ + + private CommonResponse(int status) { + this.status = status; + } + + private CommonResponse(int status, T data) { // ps: 当调用T为String类型时候,会默认调用下面的ServerResponse(int status, String msg)类型的构造器 + this.status = status; + this.data = data; + } + + private CommonResponse(int status, String msg, T data) { + this.status = status; + this.msg = msg; + this.data = data; + } + + private CommonResponse(int status, String msg) { + this.status = status; + this.msg = msg; + } + + + /* + * 对外开放调用的静态方法,用来调用私有构造器,来返回成功结果给前台 + */ + + /** + * @return 返回成功码和默认的成功信息 + */ + public static CommonResponse createBySuccess() { + return new CommonResponse(ResponseCode.SUCCESS.getCode(),ResponseCode.SUCCESS.getDesc()); + } + + /** + * + * @param msg 定义的成功信息 + * @return 返回成功码和成功信息 + */ + public static CommonResponse createBySuccessMessage(String msg) { + return new CommonResponse(ResponseCode.SUCCESS.getCode(), msg); + } + + /** + * + * @param data 传入实体 + * @return 返回成功码和数据 + */ + public static CommonResponse createBySuccess(T data) { + return new CommonResponse(ResponseCode.SUCCESS.getCode(), data); + } + + /** + * + * @param msg 传入信息 + * @param data 传入实体 + * @return 返回成功码和成功信息和数据 + */ + public static CommonResponse createBySuccess(String msg, T data) { + return new CommonResponse(ResponseCode.SUCCESS.getCode(), msg, data); + } + + /* + 对外开放调用的静态方法,用来调用私有构造器,来返回失败结果给前台 + */ + + /** + * + * @return 返回错误码和默认的错误 + */ + public static CommonResponse createByError(){ + return new CommonResponse(ResponseCode.ERROR.getCode(),ResponseCode.ERROR.getDesc()); + } + + /** + * + * @param errorMessage 定义的错误信息 + * @return 返回错误码和错误信息(传入) + */ + public static CommonResponse createByErrorMessage(String errorMessage){ + return new CommonResponse(ResponseCode.ERROR.getCode(),errorMessage); + } + + /** + * + * @param errorCode 错误码 + * @param errorMessage 错误信息 + * @return 返回错误码(传入)和错误信息(传入) + */ + public static CommonResponse createByErrorCodeMessage(int errorCode,String errorMessage){ + return new CommonResponse(errorCode,errorMessage); + } +} diff --git a/short-server-service/src/main/java/com/by/api/common/ResponseCode.java b/short-server-service/src/main/java/com/by/api/common/ResponseCode.java new file mode 100644 index 0000000..158a161 --- /dev/null +++ b/short-server-service/src/main/java/com/by/api/common/ResponseCode.java @@ -0,0 +1,48 @@ +package com.by.api.common; + +/** + * Description: 自定义Response响应返回体 -> 这边采用的是 + * @author q + */ +public enum ResponseCode { + + /** + * 成功 + */ + SUCCESS(0,"SUCCESS"), + /** + * 失败 + */ + ERROR(1,"ERROR"), + + + /* + * 请求参数校验 + */ + ILLEGAL_ARGUMENT(1,"请求参数格式错误"), + EMPTY_ARGUMENT(1,"请求参数为空"), + + /* + * 请求结果性的错误 + */ + NO_REASON_ERROR(1,"未知异常错误发生"), + SYSTEM_ERROR(1,"系统异常"), + DECRYPT_ERROR(1,"解密错误,请联系相关人员"); + + private final int code; + private final String desc; + + ResponseCode(int code, String desc){ + this.code = code; + this.desc = desc; + } + + public int getCode() { + return code; + } + + public String getDesc() { + return desc; + } + +} diff --git a/short-server-service/src/main/java/com/by/api/constants/RequestDetailConstant.java b/short-server-service/src/main/java/com/by/api/constants/RequestDetailConstant.java new file mode 100644 index 0000000..3c11d6c --- /dev/null +++ b/short-server-service/src/main/java/com/by/api/constants/RequestDetailConstant.java @@ -0,0 +1,11 @@ +package com.by.api.constants; + +/** + * 详细的请求参数验证 - 错误信息 + */ +public class RequestDetailConstant { + + public static final String REQUEST_ADDR_EMPTY = "请求的地址为空"; + + public static final String REQUEST_PARAMS_EMPTY = "请求参数为空"; +} diff --git a/short-server-service/src/main/java/com/by/api/convert/ShortChainVOToDTOConvert.java b/short-server-service/src/main/java/com/by/api/convert/ShortChainVOToDTOConvert.java new file mode 100644 index 0000000..1b3aaa6 --- /dev/null +++ b/short-server-service/src/main/java/com/by/api/convert/ShortChainVOToDTOConvert.java @@ -0,0 +1,51 @@ +package com.by.api.convert; + +import cn.hutool.core.collection.CollectionUtil; +import com.by.api.vo.ShortChainRequestVO; +import com.by.dto.ShortChainDTO; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashSet; +import java.util.Set; + +/** + * VO -> DTO + */ +public class ShortChainVOToDTOConvert { + + + + + /** + * 短链 请求 vo -> dto + */ + public static ShortChainDTO convertShortChainRequestVOToDTO(ShortChainRequestVO shortChainRequestVO) { + + Set originsUrlSet = new HashSet<>(1000); + + String baseUrlAddr = shortChainRequestVO.getBaseUrlAddr(); + shortChainRequestVO.getVariableList().forEach( + each -> { + originsUrlSet.add(checkUrlAllowed(baseUrlAddr) + each); + } + + ); + + if (CollectionUtil.isNotEmpty(originsUrlSet)){ + ShortChainDTO shortChainDTO = new ShortChainDTO(); + shortChainDTO.setShortChainOrigins(originsUrlSet); + return shortChainDTO; + } + + return new ShortChainDTO(); + } + + private static String checkUrlAllowed(String baseUrlAddr) { + if (!StringUtils.endsWith(baseUrlAddr.trim(), "//")){ + return baseUrlAddr.trim() + "//"; + } + return baseUrlAddr.trim(); + } + + +} diff --git a/short-server-service/src/main/java/com/by/api/exception/GlobalExceptionHandle.java b/short-server-service/src/main/java/com/by/api/exception/GlobalExceptionHandle.java new file mode 100644 index 0000000..b132d69 --- /dev/null +++ b/short-server-service/src/main/java/com/by/api/exception/GlobalExceptionHandle.java @@ -0,0 +1,34 @@ +package com.by.api.exception; + +import com.by.api.common.CommonResponse; +import com.by.api.common.ResponseCode; +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; + +/** + * 全局异常处理类 + */ +@ControllerAdvice +@Slf4j +public class GlobalExceptionHandle { + + + /** + * 捕获异常级别是Exception级别的异常 + * + * @param exception 异常入参 + * + * @return 统一的业务异常封装 + */ + @ExceptionHandler(Exception.class) + @ResponseBody + public CommonResponse customException(Exception exception) { + if (exception != null){ + log.error(" =============== [ERROR , exception is {} , {}] ===============", exception.getMessage() ,exception); + return CommonResponse.createByErrorMessage(ResponseCode.SYSTEM_ERROR.getDesc()); + } + return CommonResponse.createByErrorMessage(ResponseCode.NO_REASON_ERROR.getDesc()); + } +} diff --git a/short-server-service/src/main/java/com/by/api/vo/ShortChainRequestVO.java b/short-server-service/src/main/java/com/by/api/vo/ShortChainRequestVO.java new file mode 100644 index 0000000..7bdad74 --- /dev/null +++ b/short-server-service/src/main/java/com/by/api/vo/ShortChainRequestVO.java @@ -0,0 +1,30 @@ +package com.by.api.vo; + +import com.by.api.constants.RequestDetailConstant; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import java.util.List; + + +/** + * 短链请求结构体 + * + * @author q + */ +@Data +public class ShortChainRequestVO { + + /** + * 请求的统一地址 + */ + @NotBlank(message = RequestDetailConstant.REQUEST_ADDR_EMPTY) + private String baseUrlAddr; + + /** + * 每一个需要进行短链拼接的变量内容集合 + */ + @NotEmpty(message = RequestDetailConstant.REQUEST_PARAMS_EMPTY) + private List variableList; +} diff --git a/short-server-service/src/main/java/com/by/api/vo/ShortChainResponseVO.java b/short-server-service/src/main/java/com/by/api/vo/ShortChainResponseVO.java new file mode 100644 index 0000000..a4048df --- /dev/null +++ b/short-server-service/src/main/java/com/by/api/vo/ShortChainResponseVO.java @@ -0,0 +1,19 @@ +package com.by.api.vo; + +import lombok.Data; + +import java.util.List; + +/** + * 短链返回结构体 + * + * @author q + */ +@Data +public class ShortChainResponseVO { + + /** + * 短链生成结果 + */ + private List shortChainResult; +} diff --git a/short-server-service/src/main/java/com/by/dao/ShortUrlRepository.java b/short-server-service/src/main/java/com/by/dao/ShortUrlRepository.java new file mode 100644 index 0000000..f62e785 --- /dev/null +++ b/short-server-service/src/main/java/com/by/dao/ShortUrlRepository.java @@ -0,0 +1,11 @@ +package com.by.dao; + +import com.by.entity.ShortUrl; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +@Repository +public interface ShortUrlRepository extends JpaRepository, JpaSpecificationExecutor { + +} \ No newline at end of file diff --git a/short-server-service/src/main/java/com/by/entity/ShortUrl.java b/short-server-service/src/main/java/com/by/entity/ShortUrl.java new file mode 100644 index 0000000..ce3d5aa --- /dev/null +++ b/short-server-service/src/main/java/com/by/entity/ShortUrl.java @@ -0,0 +1,75 @@ +package com.by.entity; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import lombok.Data; + +import javax.persistence.*; +import java.io.Serializable; +import java.sql.Timestamp; + +@Entity +@Data +@Table(name = "t_short_url") +public class ShortUrl implements Serializable { + + /** + * id + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + /** + * 创建时间 + */ + @Column(name = "gmt_create", nullable = false) + private Timestamp gmtCreate; + + /** + * 修改时间 + */ + @Column(name = "gmt_modified", nullable = false) + private Timestamp gmtModified; + + /** + * 最后一次操作人的IP地址 + */ + @Column(name = "operator_ip", nullable = false) + private String operatorIp; + + /** + * 原始链接 + */ + @Column(name = "origin_url", nullable = false) + private String originUrl; + + /** + * 生成短链 + */ + @Column(name = "short_url") + private String shortUrl; + + /** + * 点击标识 0-未点击 1-点击 + */ + @Column(name = "point_tag", nullable = false) + private Integer pointTag; + + /** + * 失效倒计时时间(day) + */ + @Column(name = "expiration_day", nullable = false) + private Integer expirationDay; + + /** + * 有效标识 0-无效 1-有效 + */ + @Column(name = "valid_tag") + private Integer validTag; + + public void copy(ShortUrl source) { + BeanUtil.copyProperties(source, this, CopyOptions.create().setIgnoreNullValue(true)); + } +} diff --git a/short-server-service/src/main/java/com/by/service/ShortServerService.java b/short-server-service/src/main/java/com/by/service/ShortServerService.java new file mode 100644 index 0000000..786f0ca --- /dev/null +++ b/short-server-service/src/main/java/com/by/service/ShortServerService.java @@ -0,0 +1,25 @@ +package com.by.service; + +import com.by.dto.ShortChainDTO; +import org.springframework.web.servlet.ModelAndView; + +/** + * 短链信息处理接口 + */ +public interface ShortServerService { + + + /** + * 原始链接处理成短链 + * + * @param shortChainDTO + * @return + */ + ShortChainDTO handleOriginUrlsToShortUrls(ShortChainDTO shortChainDTO); + + + /** + * 兑换短链跳转并更新点击记录及回传点击记录 + */ + ModelAndView handleOnceShortUrlToRedirectOriginUrlAndRecord(String param); +} diff --git a/short-server-service/src/main/java/com/by/service/impl/ShortServerServiceImpl.java b/short-server-service/src/main/java/com/by/service/impl/ShortServerServiceImpl.java new file mode 100644 index 0000000..61a5bd0 --- /dev/null +++ b/short-server-service/src/main/java/com/by/service/impl/ShortServerServiceImpl.java @@ -0,0 +1,41 @@ +package com.by.service.impl; + +import com.by.dto.ShortChainDTO; +import com.by.service.ShortServerService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.web.servlet.ModelAndView; + +/** + * 短链服务实现Service + * + * @author q + */ +@Service +@Slf4j +public class ShortServerServiceImpl implements ShortServerService { + + + @Override + public ShortChainDTO handleOriginUrlsToShortUrls(ShortChainDTO shortChainDTO) { + + // TODO: 2021/4/14 0014 + // 1. 拼接请求调用短链生成器进行所有的短链请求 + + // 2. 生成的短链请求批量入库 + + // 3. 把短链请求 return 给调用方 + return null; + } + + @Override + public ModelAndView handleOnceShortUrlToRedirectOriginUrlAndRecord(String param) { + // 1. 查询库中的短链请求 + + // 2. 拿出真实请求进行跳转 + + // 3. 异步进行更新数据库中的点击记录及推送给之前的调用方(可以走消息) + + return new ModelAndView("redirect:https://www.baidu.com/"); + } +} diff --git a/short-server-service/src/main/java/com/by/task/ShortChainTask.java b/short-server-service/src/main/java/com/by/task/ShortChainTask.java new file mode 100644 index 0000000..d3391e8 --- /dev/null +++ b/short-server-service/src/main/java/com/by/task/ShortChainTask.java @@ -0,0 +1,30 @@ +package com.by.task; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Scope; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.time.ZoneOffset; + +@Component +@Scope("prototype") +@Slf4j +public class ShortChainTask { + + @Async(value = "abTaskExecutor") + public void doRunTask(){ + Long satrtMilliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli(); + log.info("====== [ task start running, task name is {} ] ======", "ABDownTask"); + runTask(); + Long endMilliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli(); + log.info("====== [ task start end, task name is {},cost milliSecond is {} ] ======", "ABDownTask", (endMilliSecond-satrtMilliSecond)); + } + + private void runTask() { + + } + + +} diff --git a/short-server-service/src/main/java/com/by/task/conf/ThreadPoolConfig.java b/short-server-service/src/main/java/com/by/task/conf/ThreadPoolConfig.java new file mode 100644 index 0000000..1fd08d1 --- /dev/null +++ b/short-server-service/src/main/java/com/by/task/conf/ThreadPoolConfig.java @@ -0,0 +1,54 @@ +package com.by.task.conf; + + +import org.apache.tomcat.util.threads.ThreadPoolExecutor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableAsync; + +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.TimeUnit; + +/** + * 线程池配置总类,用于配置线程池 + */ +@Configuration +@EnableAsync +public class ThreadPoolConfig { + + /** + * 从配置文件中加载线程池相关的配置 + */ + @Value(value = "${short.chain.task.corePoolSize}") + private int corePoolSize = 4; + @Value(value = "${short.chain.task.maxPoolSize}") + private int maxPoolSize = 32; + @Value(value = "${short.chain.task.queueCapacity}") + private int queueCapacity = 100; + @Value(value = "${short.chain.task.ThreadNamePrefix}") + private String ThreadNamePrefix = "MyThreadPoolExecutor-"; + + + /** + * AB 单的异步线程池的配置类 + * @return + */ + @Bean + public Executor shortChainTaskExecutor() { + + ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( + corePoolSize, + maxPoolSize, + 3, + TimeUnit.SECONDS, + new LinkedBlockingDeque<>(queueCapacity), + Executors.defaultThreadFactory(), + new ThreadPoolExecutor.DiscardOldestPolicy() + ); + + return threadPoolExecutor; + } +} diff --git a/short-server-service/src/main/resources/application-dev.yml b/short-server-service/src/main/resources/application-dev.yml index 77f14e2..37cb887 100644 --- a/short-server-service/src/main/resources/application-dev.yml +++ b/short-server-service/src/main/resources/application-dev.yml @@ -4,7 +4,7 @@ spring: druid: db-type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://localhost:3306/db-short-server?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&rewriteBatchedStatements=true + url: jdbc:mysql://localhost:3306/db_short_server?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&rewriteBatchedStatements=true username: root password: root # 初始连接数 diff --git a/short-server-service/src/main/resources/application-prod.yml b/short-server-service/src/main/resources/application-prod.yml index aab779e..462ec02 100644 --- a/short-server-service/src/main/resources/application-prod.yml +++ b/short-server-service/src/main/resources/application-prod.yml @@ -4,7 +4,7 @@ spring: druid: db-type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://localhost:3306/eladmin-plat2?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&rewriteBatchedStatements=true + url: jdbc:mysql://localhost:3306/db_short_server?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&rewriteBatchedStatements=true username: root password: Yuyou@2020 # 初始连接数 diff --git a/short-server-service/src/main/resources/application.yml b/short-server-service/src/main/resources/application.yml index 54d64c2..867a41c 100644 --- a/short-server-service/src/main/resources/application.yml +++ b/short-server-service/src/main/resources/application.yml @@ -26,3 +26,12 @@ spring: # 配置日志 logging: config: classpath:logback.xml + +# 线程池配置 +short: + chain: + task: + corePoolSize: 4 + maxPoolSize: 32 + queueCapacity: 100 + ThreadNamePrefix: 'shortChainTaskExecutor-' \ No newline at end of file diff --git a/sql/t_short_url.sql b/sql/t_short_url.sql new file mode 100644 index 0000000..f8a5e14 --- /dev/null +++ b/sql/t_short_url.sql @@ -0,0 +1,28 @@ + +-- ---------------------------- +-- TODO please create database first +-- ---------------------------- + + + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for t_short_url +-- ---------------------------- +DROP TABLE IF EXISTS `t_short_url`; +CREATE TABLE `t_short_url` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', + `gmt_create` datetime(0) NOT NULL COMMENT '创建时间', + `gmt_modified` datetime(0) NOT NULL COMMENT '修改时间', + `operator_ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '最后一次操作人的IP地址', + `origin_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '原始链接', + `short_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '生成短链', + `point_tag` tinyint(1) NOT NULL DEFAULT 0 COMMENT '点击标识 0-未点击 1-点击', + `expiration_day` int(5) NOT NULL COMMENT '失效倒计时时间(day)', + `valid_tag` tinyint(1) NULL DEFAULT NULL COMMENT '有效标识 0-无效 1-有效', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +SET FOREIGN_KEY_CHECKS = 1;