[代码完善](master): 功能完善

完善了README.md的说明
修改完善非签验证和签验证2种短链模式
增加了启动脚本
增加定时定时检查删除过期短链的逻辑
master
土豆兄弟 3 years ago
parent d86a19cb21
commit adcdb02589

@ -21,9 +21,50 @@
short-server-common - 公共模块 short-server-common - 公共模块
short-server-pojo - dto/bo 用于模块之间的传输实体/领域模型定义 short-server-pojo - dto/bo 用于模块之间的传输实体/领域模型定义
short-server-service - 短链生成服务 short-server-service - 短链生成服务
#### 调用方式及API
#### 附加功能说明
支持默认定时30天的清除短链(默认开启)
支持带签名区分的短链形式,例如:
request:
{
"baseUrlAddr": "htttps://www.baidu.com/xxdsd/sdsdsds?sadsads=xxxx",
"variableList": [
13111112211,
12111112222
]
}
response:
{
"status": 0,
"data": {
"shortChainResult": [
"e4ig5miu1n|13111112211",
"rtyt8vhx6l|12111112222"
]}
}
也支持不带签名的短链(这里只支持单条调用)
request:
{
"baseUrlAddr": "htttps://www.baidu.com/xxdsd/sdsdsds?sadsads=xxxx"
}
response:
{
"status": 0,
"data": {
"shortChainResult": [
"e4ig5miu1n"
]}
}
#### 调用方式及API
批量生成短链API : {{host}}:{{ip}}/send
短链兑换真实地址API : {{host}}:{{ip}}/返回的短链
#### 部署方式 #### 部署方式
by-short-server 目录下 mvn clean install 进行打包
上传到服务器
运行 ./script 下的 run-short-server.sh 脚本启动

@ -34,6 +34,7 @@
<fastjson.version>1.2.73</fastjson.version> <fastjson.version>1.2.73</fastjson.version>
<lombok.version>1.18.16</lombok.version> <lombok.version>1.18.16</lombok.version>
<common-lang3.version>3.8.1</common-lang3.version> <common-lang3.version>3.8.1</common-lang3.version>
<quarz.version>2.3.2</quarz.version>
</properties> </properties>
<!-- 相关依赖管理 --> <!-- 相关依赖管理 -->
@ -72,6 +73,11 @@
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
<version>${common-lang3.version}</version> <version>${common-lang3.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>${quarz.version}</version>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>

@ -0,0 +1,4 @@
#!/bin/bash
source stop-short-server.sh
source start-short-server.sh

@ -0,0 +1,5 @@
#!/bin/bash
echo "Start run short-server-service-1.0 Application..."
nohup java -jar short-server-service-1.0-SNAPSHOT.jar 1> short-Log.log 2>log/short-errorLog.log &

@ -0,0 +1,12 @@
#!/bin/bash
pid=`ps -ef | grep short-server-service-1.0-SNAPSHOT | grep -v grep| awk '{print $2}'`
if [ -z "$pid" ];
then
echo "Application is already stopped" $pid
else
echo $pid is killed
kill -9 $pid
fi

@ -35,6 +35,10 @@
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

@ -0,0 +1,125 @@
package com.by.utils;
import org.quartz.CronExpression;
import java.text.ParseException;
/**
* Cron
* <p>
*
*
* @author q 使,,
*/
public class CronUtil {
/**
*
* @param cronExp
* @return
*/
public static String translateToChinese(String cronExp) {
if (cronExp == null || cronExp.length() < 1) {
return "cron表达式为空";
}
CronExpression exp = null;
// 初始化cron表达式解析器
try {
exp = new CronExpression(cronExp);
} catch (ParseException e) {
return "corn表达式不正确";
}
String[] tmpCorns = cronExp.split(" ");
StringBuffer sBuffer = new StringBuffer();
if (tmpCorns.length == 6) {
//解析月
if (!tmpCorns[4].equals("*")) {
sBuffer.append(tmpCorns[4]).append("月");
} else {
sBuffer.append("每月");
}
//解析周
if (!tmpCorns[5].equals("*") && !tmpCorns[5].equals("?")) {
char[] tmpArray = tmpCorns[5].toCharArray();
for (char tmp : tmpArray) {
switch (tmp) {
case '1':
sBuffer.append("星期天");
break;
case '2':
sBuffer.append("星期一");
break;
case '3':
sBuffer.append("星期二");
break;
case '4':
sBuffer.append("星期三");
break;
case '5':
sBuffer.append("星期四");
break;
case '6':
sBuffer.append("星期五");
break;
case '7':
sBuffer.append("星期六");
break;
case '-':
sBuffer.append("至");
break;
default:
sBuffer.append(tmp);
break;
}
}
}
//解析日
if (!tmpCorns[3].equals("?")) {
if (!"*".equals(tmpCorns[3]) && !(tmpCorns[3]).contains("/")) {
sBuffer.append(tmpCorns[3]).append("日");
}else if(!tmpCorns[3].equals("*") && (tmpCorns[3]).contains("/")){
String[] split = tmpCorns[3].split("/");
if(split.length == 2 ){
sBuffer.append("从第").append(split[0]).append("天开始,每").append(split[1]).append("天,");
}
}
else {
sBuffer.append("每日");
}
}
//解析时
if (!tmpCorns[2].equals("*")) {
sBuffer.append(tmpCorns[2]).append("时");
} else {
sBuffer.append("每时");
}
//解析分
if (!tmpCorns[1].equals("*")) {
sBuffer.append(tmpCorns[1]).append("分");
} else {
sBuffer.append("每分");
}
//解析秒
if (!tmpCorns[0].equals("*")) {
sBuffer.append(tmpCorns[0]).append("秒");
} else {
sBuffer.append("每秒");
}
}
return sBuffer.append("执行").toString();
}
public static void main(String[] args) {
String CRON_EXPRESSION = "0 0 0 1/1 * ?";
System.out.println(CRON_EXPRESSION +" - "+CronUtil.translateToChinese(CRON_EXPRESSION));
}
}

@ -4,6 +4,7 @@ package com.by;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
/** /**
* *
@ -11,6 +12,7 @@ import org.springframework.scheduling.annotation.EnableAsync;
* @author q * @author q
*/ */
@EnableAsync @EnableAsync
@EnableScheduling
@SpringBootApplication @SpringBootApplication
public class ShortServerApplication { public class ShortServerApplication {
public static void main(String[] args) { public static void main(String[] args) {

@ -30,12 +30,15 @@ public class ShortChainVOToDTOConvert {
Set<String> originsUrlSet = new HashSet<>(1000); Set<String> originsUrlSet = new HashSet<>(1000);
String baseUrlAddr = shortChainRequestVO.getBaseUrlAddr(); String baseUrlAddr = shortChainRequestVO.getBaseUrlAddr();
shortChainRequestVO.getVariableList().forEach(
each -> {
originsUrlSet.add(baseUrlAddr + SymbolConstant.SPLIT_VERTICAL + each);
}
); if (CollectionUtil.isNotEmpty(shortChainRequestVO.getVariableList())){
shortChainRequestVO.getVariableList().forEach(
each -> {
originsUrlSet.add(baseUrlAddr + SymbolConstant.SPLIT_VERTICAL + each);
}
);
}
if (CollectionUtil.isNotEmpty(originsUrlSet)) { if (CollectionUtil.isNotEmpty(originsUrlSet)) {
ShortChainDTO shortChainDTO = new ShortChainDTO(); ShortChainDTO shortChainDTO = new ShortChainDTO();

@ -6,7 +6,6 @@ import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List; import java.util.List;
@ -29,6 +28,5 @@ public class ShortChainRequestVO {
/** /**
* *
*/ */
@NotEmpty(message = RequestDetailConstant.REQUEST_PARAMS_EMPTY)
private List<String> variableList; private List<String> variableList;
} }

@ -7,6 +7,8 @@ import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.List;
/** /**
* @author q * @author q
*/ */
@ -22,4 +24,51 @@ public interface ShortUrlRepository extends JpaRepository<ShortUrl, Long>, JpaSp
@Modifying @Modifying
@Query("update ShortUrl t set t.sendTag = ?1 where t.id = ?2") @Query("update ShortUrl t set t.sendTag = ?1 where t.id = ?2")
void updateSendStatus(Integer sendStatus, Long recId); void updateSendStatus(Integer sendStatus, Long recId);
/**
* @param expirationDay
* @return
*/
@Query
List<ShortUrl> findAllByExpirationDayAfter(Integer expirationDay);
/**
* @param expirationDay
* @return
*/
@Query
List<ShortUrl> findAllByExpirationDay(Integer expirationDay);
/**
*
*
* @param ids id
* @return
*/
@Modifying
@Query( value = "UPDATE ShortUrl t set t.expirationDay = t.expirationDay-1 WHERE t.id IN (?1)")
Integer batchUpdateExpirationDay(List<Long> ids);
/**
* ()day -
*
* @param ids
* @return ()
*/
@Modifying
@Query( value = "UPDATE ShortUrl t set t.validTag = 1 WHERE t.id IN (?1)")
Integer batchSoftDeleteExpirationDayIs(List<Long> ids);
/**
* ()day -
*
* @param expirationDay
* @return ()
*/
@Modifying
@Query( value = "DELETE FROM ShortUrl t WHERE t.expirationDay = ?1")
Integer batchDeleteExpirationDayIs(Integer expirationDay);
} }

@ -15,6 +15,12 @@ public class DBDefaultConstant {
*/ */
public static final int ZERO_NUM_TAG = 0; public static final int ZERO_NUM_TAG = 0;
/**
* 0L
*/
public static final Long LONG_ZERO_NUM_TAG = 0L;
/** /**
* 1 * 1
*/ */

@ -31,4 +31,9 @@ public interface ShortServerService {
* @return * @return
*/ */
boolean updateShortUrlToPlatformSendtatus(Long recId, boolean sucess); boolean updateShortUrlToPlatformSendtatus(Long recId, boolean sucess);
/**
* 30
*/
Integer updateShortUrlRecOnDay();
} }

@ -1,5 +1,6 @@
package com.by.service.impl; package com.by.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import com.by.constants.SymbolConstant; import com.by.constants.SymbolConstant;
import com.by.dao.ShortUrlDAO; import com.by.dao.ShortUrlDAO;
import com.by.dao.ShortUrlRepository; import com.by.dao.ShortUrlRepository;
@ -16,10 +17,8 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList; import java.util.*;
import java.util.List; import java.util.stream.Collectors;
import java.util.Map;
import java.util.Objects;
/** /**
* Service * Service
@ -52,7 +51,13 @@ public class ShortServerServiceImpl implements ShortServerService {
makeShortUrlResult.forEach( makeShortUrlResult.forEach(
(shortUrl, originUrl) -> { (shortUrl, originUrl) -> {
shortUrls.add(new ShortUrl(originUrl, shortUrl, DBDefaultConstant.ZERO_NUM_TAG, DBDefaultConstant.ZERO_NUM_TAG)); shortUrls.add(new ShortUrl(originUrl, shortUrl, DBDefaultConstant.ZERO_NUM_TAG, DBDefaultConstant.ZERO_NUM_TAG));
resultShortUrls.add(shortUrl + SymbolConstant.SPLIT_VERTICAL + StringUtils.substringAfterLast(originUrl, SymbolConstant.SPLIT_VERTICAL)); String orginSplit = StringUtils.substringAfterLast(originUrl, SymbolConstant.SPLIT_VERTICAL);
if (StringUtils.isNotBlank(orginSplit)){
resultShortUrls.add(shortUrl + SymbolConstant.SPLIT_VERTICAL + orginSplit);
}else {
resultShortUrls.add(shortUrl);
}
} }
); );
@ -94,4 +99,24 @@ public class ShortServerServiceImpl implements ShortServerService {
} }
return Boolean.TRUE; return Boolean.TRUE;
} }
@Override
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
public Integer updateShortUrlRecOnDay() {
Integer deleteCount = shortUrlRepository.batchDeleteExpirationDayIs(DBDefaultConstant.ZERO_NUM_TAG);
if (!Objects.isNull(deleteCount) && deleteCount > 0){
log.info(" === [ShortServerServiceImpl|handleOriginUrlsToShortUrls, success delete expiration count is {} ] === ", deleteCount);
}
List<ShortUrl> allByExpirationDayAfter = shortUrlRepository.findAllByExpirationDayAfter(DBDefaultConstant.ZERO_NUM_TAG);
if (CollectionUtil.isEmpty(allByExpirationDayAfter)){
return DBDefaultConstant.ZERO_NUM_TAG;
}
return shortUrlRepository.batchUpdateExpirationDay(allByExpirationDayAfter.stream()
.map(ShortUrl::getId)
.collect(Collectors.toList()));
}
} }

@ -0,0 +1,41 @@
package com.by.task;
import com.by.service.ShortServerService;
import com.by.utils.CronUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* Task
*
* @author q
*/
@Component
@Slf4j
public class CheckShortUrlScheduleTask {
public static final String EXECUTE_CRON = "0 0 0 1/1 * ? ";
private final ShortServerService shortServerService;
public CheckShortUrlScheduleTask(ShortServerService shortServerService) {
this.shortServerService = shortServerService;
}
/**
* Task
*/
@Scheduled(cron = EXECUTE_CRON)
public void execute() {
log.info("=== [CheckShortUrlScheduleTask|execute is running. Cron rule is {}, Chinese translated to {} Thread is {} ] ===",
EXECUTE_CRON,
CronUtil.translateToChinese(EXECUTE_CRON),
Thread.currentThread().getName()
);
Integer updateRecCount = shortServerService.updateShortUrlRecOnDay();
log.info("=== [CheckShortUrlScheduleTask|execute update rec is {} . Thread is {} ] ===", updateRecCount, Thread.currentThread().getName());
}
}

@ -0,0 +1,23 @@
package com.by;
import com.by.service.ShortServerService;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class DaoTest {
@Autowired
private ShortServerService shortServerService;
@Test
public void test1(){
System.out.println(shortServerService.updateShortUrlRecOnDay());
}
}
Loading…
Cancel
Save