[新增功能](master): 新增了单个短链的需求

单个短链只有2位随机码;
已经测试;
master
土豆兄弟 3 years ago
parent 02927f3206
commit e7e22fd96b

@ -61,10 +61,14 @@
批量生成短链API : {{host}}:{{ip}}/send
短链兑换真实地址API : {{host}}:{{ip}}/返回的短链
注意事项(原始链接要求)
1. 前期不支持微信小程序内嵌h5页面
2. 跳转后请求地址为 http:://t.p.tuoz.net/短链
#### 部署方式
by-short-server 目录下 mvn clean install 进行打包
上传到服务器
运行 ./script 下的 run-short-server.sh 脚本启动
运行 /home/www/ 下的 run-short-server.sh 脚本启动

@ -6,4 +6,10 @@ public class SymbolConstant {
*
*/
public static final String SPLIT_VERTICAL = "|";
/**
*
*/
public static final String BASE_CHAR_UPCASE_PLUS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
}

@ -2,6 +2,7 @@ package com.by.utils;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.RandomUtil;
import com.by.constants.SymbolConstant;
import java.util.*;
@ -15,6 +16,11 @@ public class ShortUrlUtil {
*/
private static final Integer BASE_LIMIT_LENGTH = 10;
/**
* 3
*/
private static final Integer BASE_SHORT_LIMIT_LENGTH = 2;
private ShortUrlUtil() {
}
@ -23,7 +29,7 @@ public class ShortUrlUtil {
*
* @return
*/
public static Map<String, String> makeShortUrl(List<String> oringinShortUrlList) {
public static Map<String, String> makeShortUrl(List<String> oringinShortUrlList, Boolean tag) {
if (CollectionUtil.isEmpty(oringinShortUrlList)) {
return CollectionUtil.newHashMap();
@ -32,7 +38,18 @@ public class ShortUrlUtil {
oringinShortUrlList.forEach(
each -> {
resultMap.put(RandomUtil.randomString(BASE_LIMIT_LENGTH), each);
if (tag){
resultMap.put(RandomUtil.randomString(
SymbolConstant.BASE_CHAR_UPCASE_PLUS + RandomUtil.BASE_CHAR_NUMBER, BASE_SHORT_LIMIT_LENGTH),
each
);
}else {
resultMap.put(RandomUtil.randomString(
SymbolConstant.BASE_CHAR_UPCASE_PLUS + RandomUtil.BASE_CHAR_NUMBER, BASE_LIMIT_LENGTH),
each
);
}
}
);

@ -15,6 +15,9 @@
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<dependencies>

@ -19,6 +19,7 @@ import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@ -34,7 +35,7 @@ import static com.by.api.constants.RequestInfoConstant.CUSTOMER_IP_ADDR_KEY;
public class ShortServerOpenApiController {
// TODO: 2021/4/14 0014 添加接口限流
// TODO: 2021/4/14 0014 添加接口相关的验证 丰富VO层 加入 appid secret_key 及 时间戳验证
// TODO: 2021/4/14 0014 添加接口相关的验证 丰富VO层 加入 appId secret_key 及 时间戳验证
private final ShortServerService shortServerService;
@ -48,24 +49,28 @@ public class ShortServerOpenApiController {
@ApiOperation("批量生成短链接")
@PostMapping(value = "/trans")
@ResponseBody
public CommonResponse parseContentToShortChain(@Validated @RequestBody ShortChainRequestVO shortChainRequestVO, HttpServletRequest request) {
public CommonResponse<ShortChainResponseVO> parseContentToShortChain(@Validated @RequestBody ShortChainRequestVO shortChainRequestVO, HttpServletRequest request) {
log.info("=== [ShortServerOpenApiController|parseContentToShortChain, one request is coming, request vo is {} ] ===", shortChainRequestVO.toString());
ShortChainDTO shortChainDTO = ShortChainVOToDTOConvert.convertShortChainRequestVOToDTO(shortChainRequestVO);
// 拿到远程请求客户端的Ip信息
String remoteAddr = request.getRemoteAddr();
if (StringUtils.isNotBlank(remoteAddr)){
if (StringUtils.isNotBlank(remoteAddr)) {
ThreadLocalUtil.set(CUSTOMER_IP_ADDR_KEY, remoteAddr);
}else {
} else {
ThreadLocalUtil.set(CUSTOMER_IP_ADDR_KEY, SystemConstant.DEFAULT_IP);
}
shortChainDTO = shortServerService.handleOriginUrlsToShortUrls(shortChainDTO);
// 参数不存在的时候,给一个标识,来缩短短链
if (CollectionUtil.isEmpty(shortChainRequestVO.getVariableList())){
shortChainDTO = shortServerService.handleOriginUrlsToShortUrls(shortChainDTO, true);
}
List<String> shortChainResult = shortChainDTO.getShortChainResult();
ShortChainResponseVO shortChainResponseVO = new ShortChainResponseVO();
if (CollectionUtil.isNotEmpty(shortChainResult)){
if (CollectionUtil.isNotEmpty(shortChainResult)) {
shortChainResponseVO.setShortChainResult(shortChainResult);
}
@ -74,19 +79,36 @@ public class ShortServerOpenApiController {
@ApiOperation("短链接兑换长链接并进行")
@GetMapping(value = "/s/{redeem}")
public ModelAndView redeemShortChainClick(@PathVariable("redeem") String redeem){
@CrossOrigin
public ModelAndView redeemShortChainClick(@PathVariable("redeem") String redeem) {
log.info("=== [ShortServerOpenApiController|redeemShortChainClick, one request is coming, request param is {} ] ===", redeem);
ShortUrl shortUrl = shortServerService.handleOnceShortUrlToRedirectOriginUrlAndRecord(redeem);
String originUrl = "";
if (!Objects.isNull(shortUrl)){
String originUrl = "";
if (!Objects.isNull(shortUrl)) {
// 异步进行更新数据库中的点击记录及推送给之前的调用方(可以走消息)
shortChainTask.doRunTask(shortUrl);
originUrl = StringUtils.substringBefore(shortUrl.getOriginUrl(), SymbolConstant.SPLIT_VERTICAL);
originUrl = shortUrl.getOriginUrl();
// 增加如果是不带参数的url就不调用task进行分发
if (StringUtils.contains(originUrl, SymbolConstant.SPLIT_VERTICAL)){
shortChainTask.doRunTask(shortUrl);
}
originUrl = StringUtils.substringBefore(originUrl, SymbolConstant.SPLIT_VERTICAL);
}
return new ModelAndView("redirect:" + originUrl);
}
@ApiOperation("用于测试转发")
@GetMapping(value = "/t/{redeem}")
@CrossOrigin
@Deprecated
public ModelAndView testRedirect(@PathVariable("redeem") String redeem) {
System.out.println(redeem);
return new ModelAndView(new RedirectView("http://www.baidu.com"));
}
}

@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollectionUtil;
import com.by.api.vo.ShortChainRequestVO;
import com.by.constants.SymbolConstant;
import com.by.dto.ShortChainDTO;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.HashSet;
@ -40,6 +41,11 @@ public class ShortChainVOToDTOConvert {
);
}
// 不带参数的短链支持
if (CollectionUtil.isEmpty(shortChainRequestVO.getVariableList()) && StringUtils.isNotBlank(shortChainRequestVO.getBaseUrlAddr())){
originsUrlSet.add(baseUrlAddr);
}
if (CollectionUtil.isNotEmpty(originsUrlSet)) {
ShortChainDTO shortChainDTO = new ShortChainDTO();
shortChainDTO.setShortChainOrigins(new ArrayList<>(originsUrlSet));

@ -13,9 +13,10 @@ public interface ShortServerService {
*
*
* @param shortChainDTO
* @param tag true 使
* @return
*/
ShortChainDTO handleOriginUrlsToShortUrls(ShortChainDTO shortChainDTO);
ShortChainDTO handleOriginUrlsToShortUrls(ShortChainDTO shortChainDTO, Boolean tag);
/**

@ -40,10 +40,10 @@ public class ShortServerServiceImpl implements ShortServerService {
@Override
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
public ShortChainDTO handleOriginUrlsToShortUrls(ShortChainDTO shortChainDTO) {
public ShortChainDTO handleOriginUrlsToShortUrls(ShortChainDTO shortChainDTO, Boolean tag) {
// 1. 拼接请求调用短链生成器进行所有的短链请求
Map<String, String> makeShortUrlResult = ShortUrlUtil.makeShortUrl(shortChainDTO.getShortChainOrigins());
Map<String, String> makeShortUrlResult = ShortUrlUtil.makeShortUrl(shortChainDTO.getShortChainOrigins(), tag);
// 2. 生成的短链请求批量入库
List<ShortUrl> shortUrls = new ArrayList<>();

@ -39,11 +39,11 @@ public class ShortChainTask {
@Async(value = "shortChainTaskPool")
public void doRunTask(ShortUrl shortUrl) {
Long satrtMilliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
log.info("====== [ task start running, task name is {} ] ======", "ABDownTask");
Long startMilliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
log.info("====== [ task start running, task name is {} ] ======", "shortChainTask");
runTask(shortUrl);
Long endMilliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
log.info("====== [ task start end, task name is {},cost milliSecond is {} ] ======", "ABDownTask", (endMilliSecond - satrtMilliSecond));
log.info("====== [ task start end, task name is {},cost milliSecond is {} ] ======", "shortChainTask", (endMilliSecond - startMilliSecond));
}
private void runTask(ShortUrl shortUrl) {
@ -65,18 +65,19 @@ public class ShortChainTask {
ShortChainPointJsonDTO shortChainPointJsonDTO =
new ShortChainPointJsonDTO(shortUrl.getShortUrl(), DBDefaultConstant.ONE_NUM_TAG);
String jsonSendContent = JSON.toJSONString(shortChainPointJsonDTO);
log.info("=== [pre send msg, the pre json-msg is {} ] ====", jsonSendContent);
// 失败重发请求3次
while (count <= RequestInfoConstant.RETRY_COUNT) {
// 调用HTTP请求发送数据
HttpResponse httpResponse = sendReq(jsonSendContent, uploudPlatformUrl);
if (httpResponse.isOk() && httpResponse.body().contains("0")) {
log.info("========== [liehe request success, response is {} ] ==========", httpResponse.body());
if (httpResponse.isOk() && httpResponse.body().contains("SUCCESS")) {
log.info("========== [shortChainTask update request success, response is {} ] ==========", httpResponse.body());
shortServerService.updateShortUrlToPlatformSendtatus(shortUrl.getId(), Boolean.TRUE);
break;
} else {
count++;
log.error("========== [liehe request fail, response is {} ] ==========", httpResponse.body());
log.error("========== [shortChainTask update request fail, response is {} ] ==========", httpResponse.body());
}
}
if (count > RequestInfoConstant.RETRY_COUNT) {

@ -24,7 +24,7 @@ spring:
test-while-idle: true
test-on-borrow: false
test-on-return: false
# # 检测连接是否有效
# # 检测连接是否有效
validation-query: select 1
# 配置监控统计
webStatFilter:

@ -2,7 +2,7 @@ server:
port: 6666
spring:
profiles:
active: test
active: prod
jackson:
time-zone: GMT+8
@ -39,4 +39,4 @@ short:
# 远程调用地址
upload:
platform:
url: '118.178.137.129:8000/api/tbSendSms/url/callback'
url: 'http://118.178.137.129:8800/api/tbSendSms/url/callback'
Loading…
Cancel
Save