Commit 3c4eedfa authored by 赵啸非's avatar 赵啸非

Initial commit

parents
Pipeline #2665 canceled with stages
*.iml
node_modules/
.idea/
*.class
target/
dist/
\ No newline at end of file
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>release</id>
<formats>
<format>tar.gz</format>
</formats>
<fileSets>
<fileSet>
<directory>target/bin</directory>
<outputDirectory>bin</outputDirectory>
<fileMode>0755</fileMode>
</fileSet>
<fileSet>
<directory>${project.basedir}/dist/${project.parent.artifactId}/boot</directory>
<outputDirectory>boot</outputDirectory>
<fileMode>0755</fileMode>
</fileSet>
<fileSet>
<directory>./db</directory>
<includes>
<include>*.sql</include>
</includes>
<outputDirectory>db</outputDirectory>
<fileMode>0755</fileMode>
</fileSet>
</fileSets>
<files>
<file>
<source>target/${project.artifactId}-${project.version}.jar</source>
<outputDirectory>boot</outputDirectory>
</file>
</files>
</assembly>
\ No newline at end of file
################### api配置 ###################
api:
xss-open: true #是否开启xss跨站脚本攻击防护支持 (true/false)
requestLimit: 30 #接口每秒请求限制
baseUrl: http://10.225.128.55 #审批系统地址
ocrUrl: http://rocr.egovrobot.com #ocr地址
apiUrl: http://rapi.egovrobot.com #api地址
env: pro #审批系统接口环境 test 测试; pro 正式
mq: sanya #mq监听队列名称
scheduled: #定时任务推送
monitorCron: 0 0/5 * * * ?
monitorOpen: true
################### 项目启动端口 ################### ocrUrl: https://api.egovrobot.com/rocr/ http://192.168.2.180:8099
server:
port: 8090 #端口
tomcat:
max-threads: 800 #tomcat最大线程数,默认为200
uri-encoding: utf-8
max-http-form-post-size: 10MB
servlet:
context-path: /
################### 日志配置 ###################
logging:
level:
com.lilosoft: debug
org.springframework: warn
################### spring配置 ###################
spring:
http:
encoding:
force: true
charset: UTF-8
enabled: true
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
serialization:
write-dates-as-timestamps: false
jms:
pub-sub-domain: false #false点对点队列模式 true订阅模式
template:
delivery-mode: persistent #持久化
activemq:
brokerUrl: tcp://proxy.egovrobot.com:62818
user: root
password: lilo!@#2020@lilosoft!@#2021
close-timeout: 15s # 在考虑结束之前等待的时间
in-memory: false # 默认代理URL是否应该在内存中。如果指定了显式代理,则忽略此值。
pool:
enabled: false
# max-connections: 10
packages:
trust-all: true
################### api配置 ###################
api:
xss-open: true #是否开启xss跨站脚本攻击防护支持 (true/false)
requestLimit: 30 #接口每秒请求限制
baseUrl: http://10.225.128.55 #审批系统地址
ocrUrl: http://rocrt.egovrobot.com #ocr地址
apiUrl: http://api.egovrobot.com #api地址
env: test #审批系统接口环境 test 测试; pro 正式
mq: sanya #mq监听队列名称
scheduled: #定时任务推送
monitorCron: 0 0/5 * * * ?
monitorOpen: true
################### 项目启动端口 ################### ocrUrl: https://api.egovrobot.com/rocr/ http://192.168.2.180:8099
server:
port: 8090 #端口
tomcat:
max-threads: 800 #tomcat最大线程数,默认为200
uri-encoding: utf-8
max-http-form-post-size: 10MB
servlet:
context-path: /
################### 日志配置 ###################
logging:
level:
com.lilosoft: debug
org.springframework: warn
################### spring配置 ###################
spring:
http:
encoding:
force: true
charset: UTF-8
enabled: true
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
serialization:
write-dates-as-timestamps: false
jms:
pub-sub-domain: false #false点对点队列模式 true订阅模式
template:
delivery-mode: persistent #持久化
activemq:
brokerUrl: tcp://59.175.148.30:62818
user: root
password: lilo!@#2020@lilosoft!@#2021
close-timeout: 15s # 在考虑结束之前等待的时间
in-memory: false # 默认代理URL是否应该在内存中。如果指定了显式代理,则忽略此值。
pool:
enabled: false
# max-connections: 10
packages:
trust-all: true
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#!/bin/sh
RETVAL=$?
SHELL_NAME="deploy"
BASEDIR=$(dirname $0)
BASEDIR=$( (
cd "$BASEDIR"
pwd
))
LOCK_FILE="/tmp/deploy.lock"
# 时间变量
CDATE=$(date "+%Y-%m-%d")
CTIME=$(date "+%H:%M:%S")
SHELL_LOG="${BASEDIR}/${SHELL_NAME}.log"
JAVA_HOME="/usr/local/java/jdk1.8"
SERVICE_PATH="/usr/lib/systemd/system"
PUBLISH_PATH="@profiles.publish.path@"
PROJECT_NAME="@project.artifactId@"
PROJECT_EXECPATH="${PUBLISH_PATH}/${PROJECT_NAME}"
PROJECT_UI_EXECPATH="${PUBLISH_PATH}/${PROJECT_NAME}-ui/dist"
PROJECT_FILENAME="${PROJECT_NAME}.tar.gz"
PROJECT_UI_FILENAME="${PROJECT_NAME}-ui.tar.gz"
PROJECT_SERVICE="${SERVICE_PATH}/${PROJECT_NAME}.service"
#写日志
writelog() {
LOGINFO=$1
echo "${CDATE} ${CTIME}: ${SHELL_NAME} : ${LOGINFO}" >>${SHELL_LOG}
echo ${LOGINFO}
}
#清理目标
clear_deploy() {
SERVICE=$1
EXECPATH=$2
#清理后台自启服务
rm -rf ${SERVICE}
#清理执行文件目录
rm -rf ${EXECPATH}
}
#清理ui
clear_ui_deploy() {
EXEC_UI_PATH=$1
rm -rf ${EXEC_UI_PATH}
mkdir -p ${EXEC_UI_PATH}
}
build_service() {
SERVICE=$1
EXECPATH=$2
echo "" >${SERVICE}
echo "[Unit]" >>${SERVICE}
echo "Description=${PROJECT_NAME}" >>${SERVICE}
echo "After=network.target" >>${SERVICE}
echo "" >>${SERVICE}
echo "[Service]" >>${SERVICE}
echo "Environment=\"JAVA_HOME=$JAVA_HOME\"" >>${SERVICE}
echo "Type=forking" >>${SERVICE}
echo "ExecStart=${EXECPATH}/bin/start.sh" >>${SERVICE}
echo "ExecStop=${EXECPATH}/bin/shutdown.sh" >>${SERVICE}
echo "PrivateTmp=true" >>${SERVICE}
echo "" >>${SERVICE}
echo "[Install]" >>${SERVICE}
echo "WantedBy=multi-user.target" >>${SERVICE}
writelog "${PROJECT_NAME}服务创建完成!"
}
#启动服务与nginx
start_service() {
systemctl enable ${PROJECT_NAME}
systemctl daemon-reload
writelog "${PROJECT_NAME}服务启动..."
systemctl stop ${PROJECT_NAME} && systemctl start ${PROJECT_NAME}
project_status=$(systemctl status "${PROJECT_NAME}"|grep Active |awk '{print $2}')
jcpid=$(ps -ef | grep -v "grep" | grep "${PROJECT_NAME} " | awk '{print $2}')
writelog "${PROJECT_NAME}服务启动,PID is ${jcpid} ,status:${project_status}"
}
#部署后台服务
project_deploy() {
writelog "${PROJECT_NAME}_deploy"
systemctl stop ${PROJECT_NAME}
clear_deploy ${PROJECT_SERVICE} ${PROJECT_EXECPATH}
writelog "${PROJECT_NAME}_clear_finish"
tar -zvxf ./${PROJECT_FILENAME} -C ${PUBLISH_PATH}
build_service ${PROJECT_SERVICE} ${PROJECT_EXECPATH}
start_service
writelog "${PROJECT_NAME}_deploy_finish"
}
#部署前台服务
project_ui_deploy() {
writelog "${PROJECT_NAME}_ui_deploy"
clear_ui_deploy ${PROJECT_UI_EXECPATH}
tar -zvxf ./${PROJECT_UI_FILENAME} -C ${PUBLISH_PATH}
writelog "${PROJECT_NAME}_ui_deploy_finish"
}
#主函数
main() {
echo "后台服务部署"
project_deploy
exit ${RETVAL}
}
main $1
if not exist "%JAVA_HOME%\bin\jps.exe" echo Please set the JAVA_HOME variable in your environment, We need java(x64)! jdk8 or later is better! & EXIT /B 1
setlocal
set "PATH=%JAVA_HOME%\bin;%PATH%"
echo killing server
for /f "tokens=1" %%i in ('jps -m ^| find "@project.artifactId@"') do ( taskkill /F /PID %%i )
echo Done!
#! /bin/sh
PORT="@profiles.server.port@"
BASEDIR=$(dirname $0)
BASEDIR=$( (
cd "$BASEDIR"
pwd
))
PROJECT_NAME="@project.artifactId@"
MAIN_CLASS="$PROJECT_NAME"
if [ ! -n "$PORT" ]; then
echo $"Usage: $0 {port}"
exit $FAIL
fi
pid=$(ps ax | grep -i "$MAIN_CLASS" | grep java | grep -v grep | awk '{print $1}')
if [ -z "$pid" ]; then
echo "No Server running."
exit 1
fi
echo "stoping application $PROJECT_NAME......"
kill -15 ${pid}
echo "Send shutdown request to Server $PROJECT_NAME OK"
echo off
if not exist "%JAVA_HOME%\bin\java.exe" echo Please set the JAVA_HOME variable in your environment, We need java(x64)! jdk8 or later is better! & EXIT /B 1
set "JAVA=%JAVA_HOME%\bin\java.exe"
set BASEDIR=%~dp0
set BASEDIR="%BASEDIR:~0,-5%"
set PROJECT_NAME=@project.artifactId@
set APP_NAME=%PROJECT_NAME%-@project.version@.jar
set LOG_PATH="%BASEDIR%@profiles.log.path@/%PROJECT_NAME%"
if not exist "%LOG_PATH%" md "%LOG_PATH%"
set GC_PATH=%LOG_PATH%/gc.log
set HS_ERR_PATH=%LOG_PATH%PORT%-hs_err.log
set HEAP_DUMP_PATH=%LOG_PATH%/heap_dump.hprof
set TEMP_PATH=%LOG_PATH%/temp/
if not exist "%TEMP_PATH%" md "%TEMP_PATH%"
rem jvm启动参数
set JAVA_OPTS=-Xms512M -Xmx512M -Xss256K -XX:+UseAdaptiveSizePolicy -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:GCTimeRatio=39 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError
set JAVA_OPTS=%JAVA_OPTS% -XX:+PrintGCDateStamps -Xloggc:%GC_PATH%
set JAVA_OPTS=%JAVA_OPTS% -XX:ErrorFile=%HS_ERR_PATH%
set JAVA_OPTS=%JAVA_OPTS% -XX:HeapDumpPath=%HEAP_DUMP_PATH%
rem jvm config
set JVM_CONFIG=%JVM_CONFIG% -Dapp.name=%PROJECT_NAME%
set JVM_CONFIG=%JVM_CONFIG% -Dapp.port=%PORT%
set JVM_CONFIG=%JVM_CONFIG% -Djava.io.tmpdir=%TEMP_PATH%
set JVM_CONFIG=%JVM_CONFIG% -Dbasedir=%BASEDIR%
set JVM_CONFIG=%JVM_CONFIG% -Dloader.path=file://%BASEDIR%/conf,file://%BASEDIR%/lib
set DEBUG_OPTS=
if ""%1"" == ""debug"" (
set DEBUG_OPTS= -Xloggc:../logs/gc.log -verbose:gc -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=../logs
goto debug
)
set JMX_OPTS=
if ""%1"" == ""jmx"" (
set JMX_OPTS= -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9888 -Dcom.sun.management.jmxremote.ssl=FALSE -Dcom.sun.management.jmxremote.authenticate=FALSE
goto jmx
)
set "LOG_OPTS=--logging.config=%BASEDIR%/conf/logback-spring.xml"
echo "Starting the %APP_NAME%"
"%JAVA%" %JAVA_OPTS% -server %JVM_CONFIG% -jar %BASEDIR%/boot/%APP_NAME%
echo ""%JAVA%" %JAVA_OPTS% -server %JVM_CONFIG% -jar %BASEDIR%/boot/%APP_NAME% "
goto end
:debug
echo "debug"
"%JAVA%" -Xms512m -Xmx512m -server %DEBUG_OPTS% %JVM_CONFIG% -jar ../boot/%APP_NAME%
goto end
:jmx
"%JAVA%" -Xms512m -Xmx512m -server %JMX_OPTS% %JVM_CONFIG% -jar ../boot/%APP_NAME%
goto end
:end
pause
#!/bin/sh
PORT="@profiles.server.port@"
BASEDIR=`dirname $0`/..
BASEDIR=`(cd "$BASEDIR"; pwd)`
PROJECT_NAME="@project.artifactId@";
MAIN_CLASS="$PROJECT_NAME-@project.version@.jar";
LOG_PATH="@profiles.log.path@/$PROJECT_NAME"
GC_PATH=$LOG_PATH/PROJECT_NAME"-gc.log"
HS_ERR_PATH=$LOG_PATH/PROJECT_NAME"-hs_err.log"
HEAP_DUMP_PATH=$LOG_PATH/PROJECT_NAME"-heap_dump.hprof"
TEMP_PATH=$LOG_PATH/temp/
SUCCESS=0
FAIL=9
if [ ! -n "$PORT" ]; then
echo $"Usage: $0 {port}"
exit $FAIL
fi
if [ ! -d $LOG_PATH ];
then
mkdir -p $LOG_PATH;
fi
if [ ! -d $TEMP_PATH ];
then
mkdir -p $TEMP_PATH;
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD=`which java`
echo "Error: JAVA_HOME is $JAVACMD"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "We cannot execute $JAVACMD"
exit $ERR_NO_JAVA
fi
if [ -e "$BASEDIR" ]
then
JAVA_OPTS="-Xms512M -Xmx1024M -Xss256K -XX:+UseAdaptiveSizePolicy -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:GCTimeRatio=39 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:$GC_PATH -XX:+HeapDumpOnOutOfMemoryError -XX:ErrorFile=$HS_ERR_PATH -XX:HeapDumpPath=$HEAP_DUMP_PATH"
fi
CLASSPATH=$CLASSPATH_PREFIX:
EXTRA_JVM_ARGUMENTS=""
cd "$BASEDIR/boot";
echo "starting application $PROJECT_NAME......"
exec "$JAVACMD" $JAVA_OPTS \
$EXTRA_JVM_ARGUMENTS \
-Dapp.name="$PROJECT_NAME" \
-Dapp.port="$PORT" \
-Dbasedir="$BASEDIR" \
-Djava.io.tmpdir=$TEMP_PATH \
-Dloader.path="file://$BASEDIR/conf,file://$BASEDIR/lib" \
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=41043 \
-jar $MAIN_CLASS \
> /dev/null &
for i in {1..60}
do
jcpid=`ps -ef | grep -v "grep" | grep "$MAIN_CLASS" | grep "app.port=$PORT" | sed -n '1P' | awk '{print $2}'`
if [ $jcpid ]; then
echo "The $PROJECT_NAME start finished, PID is $jcpid"
exit $SUCCESS
else
echo "starting the application .. $i"
sleep 1
fi
done
echo "$PROJECT_NAME start failure!"
#! /bin/sh
PORT="@profiles.server.port@"
BASEDIR=`dirname $0`
BASEDIR=`(cd "$BASEDIR"; pwd)`
PROJECT_NAME="@project.artifactId@"
MAIN_CLASS="$PROJECT_NAME";
if [ ! -n "$PORT" ]; then
echo $"Usage: $0 {port}"
exit $FAIL
fi
echo "stoping application $PROJECT_NAME......"
jcpid=`ps -ef | grep -v "grep" | grep "$MAIN_CLASS" | grep "app.port=$PORT" | sed -n '1P' | awk '{print $2}'`
if [ -z $jcpid ]; then
echo "$PROJECT_NAME is not started or has been stopped!"
else
curl -X POST -i -u $SECURITY_USERNAME:$SECURITY_PASSWORD http://127.0.0.1:$PORT/xxx_manager/shutdown
for i in {1..60}
do
jcpid=`ps -ef | grep -v "grep" | grep "$MAIN_CLASS" | grep "app.port=$PORT" | sed -n '1P' | awk '{print $2}'`
if [ -z $jcpid ]; then
echo "$PROJECT_NAME has been stopped!"
break
else
echo "stoping the application .. $i"
sleep 1
fi
done
jcpid=`ps -ef | grep -v "grep" | grep "$MAIN_CLASS" | grep "app.port=$PORT" | sed -n '1P' | awk '{print $2}'`
if [ $jcpid ]; then
[ -z $jcpid ] || kill -15 $jcpid
for i in {1..30}
do
jcpid=`ps -ef | grep -v "grep" | grep "$MAIN_CLASS" | grep "app.port=$PORT" | sed -n '1P' | awk '{print $2}'`
if [ -z $jcpid ]; then
echo "$PROJECT_NAME has been stopped!"
break
else
echo "stoping the application .. $i"
sleep 1
fi
done
fi
jcpid=`ps -ef | grep -v "grep" | grep "$MAIN_CLASS" | grep "app.port=$PORT" | sed -n '1P' | awk '{print $2}'`
if [ $jcpid ]; then
[ -z $jcpid ] || kill -9 $jcpid
[ $? -eq 0 ] && echo "Stop $PROJECT_NAME OK!" || echo "Stop $PROJECT_NAME Fail!"
fi
fi
package com.lilosoft;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling
@SpringBootApplication
public class RdsmsApiApplication {
private final static Logger logger = LoggerFactory.getLogger(RdsmsApiApplication.class);
public static void main(String[] args) {
SpringApplication app = new SpringApplication(RdsmsApiApplication.class);
app.setBannerMode(Banner.Mode.CONSOLE);
app.run(args);
//standard字体生成
String str = "";
str= " 88 \n" +
" \"\" \n" +
",adPPYYba, 8b,dPPYba, 88 \n" +
"\"\" `Y8 88P' \"8a 88 \n" +
",adPPPPP88 88 d8 88 \n" +
"88, ,88 88b, ,a8\" 88 \n" +
"`\"8bbdP\"Y8 88`YbbdP\"' 88 \n" +
" 88 \n" +
" 88 \n";
logger.info("ヾ(@°^°@)ヾ 启动成功 ヾ(@°^°@)ヾ\n" +str);
logger.info("ApiApplication is success!");
}
}
\ No newline at end of file
package com.lilosoft;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
public class RdsmsApiServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(RdsmsApiApplication.class);
}
}
package com.lilosoft.api.api;
import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import org.springframework.stereotype.Component;
import retrofit2.http.*;
import java.util.HashMap;
import java.util.Map;
@Component
@RetrofitClient(baseUrl = "${api.baseUrl}", connectTimeoutMs=100000,readTimeoutMs=100000,writeTimeoutMs = 100000)
public interface ApplyApi {
/**
* 获取事项信息
* @param itemCode 事项CODE 必填
* @param type 基本要素:"info",申请材料:"material" 非必填
*/
@GET
HashMap<String, Object> getItemInfoByItemCode(@Url String url,@Query("itemCode") String itemCode, @Query("type") String type);
/**
* 根据事项ID获取表单
* @param itemCode 事项CODE 必填
*/
@GET
HashMap<String, Object> getFormInfo(@Url String url,@Query("itemCode") String itemCode);
/**
* 获取表单字段信息
* @param formId 表单ID 必填
*/
@GET
HashMap<String, Object> getFieldList(@Url String url,@Query("formId") String formId);
/**
* 提交表单 Content-Type:application/x-www-form-urlencoded
* @param map
*/
@POST
@FormUrlEncoded
HashMap<String, Object> saveDataEx(@Url String url,@FieldMap HashMap<String, Object> map);
/**
* 上传材料
* @param file
* @param map
* @return
*/
@POST
@Multipart
HashMap<String, Object> upload(@Url String url,@Part MultipartBody.Part file,@PartMap Map<String, RequestBody> map);
/**
* 网上申报 Content-Type:application/x-www-form-urlencoded
* @param postdata
*/
@POST
@FormUrlEncoded
HashMap<String, Object> webApply(@Url String url,@Field("postdata") String postdata);
}
package com.lilosoft.api.api;
import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient;
import okhttp3.ResponseBody;
import org.springframework.stereotype.Component;
import retrofit2.Response;
import retrofit2.http.GET;
import retrofit2.http.Query;
@Component
@RetrofitClient(baseUrl = "${api.ocrUrl}",connectTimeoutMs=100000,readTimeoutMs=100000,writeTimeoutMs = 100000)
public interface OcrApi {
/**
* 下载办件材料
* @param fileUrl 文件地址,
* @param fileName 文件名称,
* @param isNet 是否保存在fastdfs,不传为本地磁盘保存
* @return
*/
@GET("lilo/aiCase/download")
Response<ResponseBody> downloadFile(@Query("fileUrl") String fileUrl,@Query("fileName") String fileName,@Query("isNet") String isNet);
}
package com.lilosoft.api.api;
import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient;
import com.lilosoft.api.bean.RobotCaseRecord;
import com.lilosoft.core.model.JsonResult;
import org.springframework.stereotype.Component;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;
@Component
@RetrofitClient(baseUrl = "${api.apiUrl}",connectTimeoutMs=50000,readTimeoutMs=50000,writeTimeoutMs = 50000)
public interface RobotApi {
/**
* 保存对接原始数据
*/
@POST("lilo/robotCaseRecord/save")
JsonResult saveRecord(@Body RobotCaseRecord bean);
/**
* 获取对接失败数据
* @param areaCode 地区编码
* @param sendFlag 推送状态,0:初始化,1:失败 2:成功
* @return
*/
@GET("lilo/robotCaseRecord/queryList")
JsonResult queryRecordList(@Query("areaCode") String areaCode, @Query("sendFlag") String sendFlag);
}
package com.lilosoft.api.bean;
import com.lilosoft.core.model.BaseBean;
import lombok.Data;
import java.util.Date;
@Data
public class RobotCaseRecord extends BaseBean {
/**
* 地区编码
*/
private String areaCode;
/**
* 推送数据
*/
private String content;
/**
* 更新时间
*/
private Date updateTime;
/**
* 推送状态,0:初始化,1:失败 2:成功
*/
private String sendFlag;
/**
* 失败原因
*/
private String msg;
public RobotCaseRecord() {
super();
}
}
package com.lilosoft.api.controller;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.lilosoft.api.api.RobotApi;
import com.lilosoft.api.bean.RobotCaseRecord;
import com.lilosoft.api.service.ApplyService;
import com.lilosoft.core.utils.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.HashMap;
@Service
public class MqConsumer {
/**
* 日志对象
*/
public Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private ApplyService applyService;
@Autowired
private RobotApi robotApi;
@Value("${api.mq}")
private String mq;
@JmsListener(destination = "${api.mq}", containerFactory = "jmsListenerContainerQueue")
public void receiveMsg(HashMap<String, String> text) {
RobotCaseRecord caseRecord = new RobotCaseRecord();
caseRecord.setId(IdUtil.simpleUUID());
caseRecord.setContent(text.get("content"));
caseRecord.setAreaCode(mq);
caseRecord.setSendFlag("0");
caseRecord.setUpdateTime(new Date());
try {
robotApi.saveRecord(caseRecord);
HashMap<String, Object> entries = JSONUtil.toBean(text.get("content"), HashMap.class);
String apply = applyService.webApply(entries);
if(ObjectUtils.isEmpty(apply)){
caseRecord.setSendFlag("2");
caseRecord.setMsg("success");
} else {
caseRecord.setSendFlag("1");
caseRecord.setMsg(apply);
}
robotApi.saveRecord(caseRecord);
} catch (Exception e) {
caseRecord.setSendFlag("1");
caseRecord.setMsg(e.getMessage());
robotApi.saveRecord(caseRecord);
logger.error(e.getMessage());
}
}
}
package com.lilosoft.api.service;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.springframework.stereotype.Service;
import java.util.HashMap;
@Service
public class ApplyService extends PublicService {
/**
* 网上申报
*/
public String webApply(HashMap<String, Object> paramsMap) throws Exception {
logger.info(JSONUtil.toJsonStr(paramsMap));
String itemCode = paramsMap.get("ItemCode").toString();
if(!paramsMap.containsKey("address")){
paramsMap.put("address", "");//办事人联系地址
}
HashMap<String, Object> formData = new HashMap<>();//需要提交的表单数据(不同事项不同字段),需根据formId获取表单字段
String result = "";//返回结果
boolean check = true;//事项是否查找到,默认事项已经查找到
if("46020400WJ-XK-1104".equals(itemCode)){//公共场所卫生许可证注销
ggcswxxkzx(paramsMap, formData);
}else {
check = false;
result = "未查询到相关事项;";
logger.error(result + JSONUtil.toJsonStr(paramsMap));
}
if(check){
//通用上传接口
result = super.webApply(paramsMap, formData);
}
return result;
}
/**
* 公共场所卫生许可证注销
*/
private void ggcswxxkzx(HashMap<String, Object> paramsMap, HashMap<String, Object> formData){
//组装第三步提交表单需要的数据,此数据是根据当前事项表单字段获取
formData.put("ShenQingRiQi", DateUtil.today());//申请日期
formData.put("XuKeZhengHao", "");//许可证号
formData.put("ZhuXiaoYuanYin", "");//注销原因
formData.put("ShenQingDanWei", paramsMap.get("GeRenDanWeiMingChen"));//申请单位
formData.put("DianHua", paramsMap.get("ApplicantMobile"));//电话
formData.put("FaDingDaiBiaoRen", paramsMap.get("FaDingDaiBiaoRen"));//法定代表人
formData.put("TongYiSheHuiXinYongDaiMa", paramsMap.get("TongYiSheHuiXinYongDaiMa"));//统一社会信用代码
JSONArray materials = JSONUtil.parseArray(paramsMap.get("materials"));//材料列表
for (int n = 0, m = materials.size(); n < m ; n++) {
JSONObject jsonObject1 = materials.getJSONObject(n);
String fileId = jsonObject1.getStr("fileId");//当前材料编码
if("hygiene".equals(fileId) || "business".equals(fileId)){//公共场所卫生许可证/营业执照归为一类
jsonObject1.putOpt("fileCode", "46020400WJ-XK-1104-00003");
} else if("applicationForm".equals(fileId) || "applicationText".equals(fileId)){//关于注销公共场所卫生许可证的申请书/申请表归为一类
jsonObject1.putOpt("fileCode", "46020400WJ-XK-1104-00002");
} else if("idcard".equals(fileId)){//多个身份证归为一类
jsonObject1.putOpt("fileCode", "46020400WJ-XK-1104-00001");
} else {//多余材料归为证照类
jsonObject1.putOpt("fileCode", "46020400WJ-XK-1104-00003");
}
}
paramsMap.put("materials", materials);
paramsMap.put("objectType", "1");
paramsMap.put("applyName", paramsMap.get("FaDingDaiBiaoRen"));
paramsMap.put("name", paramsMap.get("ApplicantName"));//办事人
paramsMap.put("idcard", paramsMap.get("ApplicantID"));//身份证号码
paramsMap.put("phone", paramsMap.get("ApplicantMobile"));//办事人手机号
//paramsMap.put("address", paramsMap.get("ApplicantAddress"));//办事人联系地址
//orgType 组织机构类型 政府机关 GovDept;个体工商户 PrivatBusiness 事业单位 Institutions 企业 Enterprise 社会团体 SocialOrg
paramsMap.put("orgType", "PrivatBusiness");
}
}
This diff is collapsed.
package com.lilosoft.api.service;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.lilosoft.api.api.RobotApi;
import com.lilosoft.api.bean.RobotCaseRecord;
import com.lilosoft.core.model.JsonResult;
import com.lilosoft.core.utils.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.*;
@Component
public class ScheduledService {
/**
* 日志对象
*/
public Logger logger = LoggerFactory.getLogger(getClass());
@Value("${scheduled.monitorOpen}")
private String monitorOpen;
@Value("${api.mq}")
private String mq;
@Autowired
private RobotApi robotApi;
@Autowired
private ApplyService applyService;
@Scheduled(cron="${scheduled.monitorCron}")
public void serverMonitorSchedule() {
if("true".equals(monitorOpen)){
JsonResult jsonResult = robotApi.queryRecordList(mq, "1");
if(jsonResult.isSuccess()){
Object obj = jsonResult.getObj();
if(obj != null){
List<Map<String, Object>> list = new ArrayList<>();
CollUtil.addAll(list, obj);
RobotCaseRecord bean = null;
try {
for (Map<String, Object> map : list) {
bean = BeanUtil.toBean(map, RobotCaseRecord.class);
HashMap<String, Object> entries = JSONUtil.toBean(bean.getContent(), HashMap.class);
String apply = applyService.webApply(entries);
if(ObjectUtils.isEmpty(apply)){
bean.setSendFlag("2");
bean.setMsg("success");
} else {
bean.setSendFlag("1");
bean.setMsg(apply);
}
bean.setUpdateTime(new Date());
robotApi.saveRecord(bean);
}
} catch (Exception e) {
if(bean != null){
bean.setUpdateTime(new Date());
bean.setMsg(Arrays.toString(e.getStackTrace()));
robotApi.saveRecord(bean);
}
logger.error(Arrays.toString(e.getStackTrace()));
e.printStackTrace();
}
}
} else {
logger.error("读取推送数据失败:" + jsonResult.getMsg());
}
}
}
}
package com.lilosoft.config;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;
/**
* 配置 ActiveMQ
*/
@Configuration
public class ActiveMQConfig {
@Value("${spring.activemq.user}")
private String usrName;
@Value("${spring.activemq.password}")
private String password;
@Value("${spring.activemq.broker-url}")
private String brokerUrl;
@Autowired
ApplicationArguments applicationArguments;
@Bean
public ActiveMQConnectionFactory connectionFactory() {
return new ActiveMQConnectionFactory(usrName, password, brokerUrl);
}
/**
* 设置点对点模式,和下面的发布订阅模式二选一即可 *
* @param connectionFactory
* @return
*/
@Bean
public JmsListenerContainerFactory jmsListenerContainerQueue(ActiveMQConnectionFactory connectionFactory) {
DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
bean.setPubSubDomain(Boolean.FALSE);
bean.setConnectionFactory(connectionFactory);
return bean;
}
@Bean
public JmsListenerContainerFactory jmsListenerContainerTopic(ActiveMQConnectionFactory connectionFactory) {
//设置为发布订阅模式, 默认情况下使用生产消费者方式
DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
bean.setPubSubDomain(Boolean.TRUE);
bean.setConnectionFactory(connectionFactory);
return bean;
}
}
package com.lilosoft.config;
import com.lilosoft.core.filter.xss.XssAndSqlFilter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.DispatcherType;
/**
* Filter配置
*
* @author qiusheng
*/
@Configuration
public class FilterConfig {
/**
* xssFilter注册
* @return
*/
@Bean
@ConditionalOnProperty(prefix = "api", name = "xss-open", havingValue = "true")
public FilterRegistrationBean xssFilterRegistration()
{
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setDispatcherTypes(DispatcherType.REQUEST);
registration.setFilter(new XssAndSqlFilter());
registration.addUrlPatterns("/*");
registration.addInitParameter("ignoreUrl", "/api/apply,/api/download");
registration.addInitParameter("isConvert", "false");
registration.setName("xssFilter");
registration.setOrder(Integer.MAX_VALUE);
return registration;
}
}
package com.lilosoft.config;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.context.request.RequestContextListener;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
/**
* 通用配置
*
* @author qiusheng
*
*/
//表示开启AOP代理自动配置,如果配@EnableAspectJAutoProxy表示使用cglib进行代理对象的生成;
//设置@EnableAspectJAutoProxy(exposeProxy=true)表示通过aop框架暴露该代理对象,aopContext能够访问.
@EnableAspectJAutoProxy(exposeProxy = true)
@Configuration
public class WebConfig implements WebMvcConfigurer {
/**
* RequestContextListener注册
*/
@Bean
public ServletListenerRegistrationBean<RequestContextListener> requestContextListenerRegistration() {
return new ServletListenerRegistrationBean<>(new RequestContextListener());
}
/**
* 配置消息转换器--序列化规则
* Include.Include.ALWAYS 默认
* Include.NON_DEFAULT 属性为默认值不序列化
* Include.NON_EMPTY 属性为 空("") 或者为 NULL 都不序列化,则返回的json是没有这个字段的。这样对移动端会更省流量
* Include.NON_NULL 属性为NULL 不序列化
*
* Date时间类型转化已经在配置文件spring.jackson.date-format里定义了规则,此处无需再次定义。
* @param converters
*/
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
.serializationInclusion(JsonInclude.Include.NON_NULL);
converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
}
/**
* 注册static静态资源访问
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
/** swagger配置 */
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
\ No newline at end of file
package com.lilosoft.config.interceptor;
import com.google.common.util.concurrent.RateLimiter;
import com.lilosoft.core.annotation.RateLimit;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;
@Component
public class RateLimitInterceptor extends HandlerInterceptorAdapter {
//用来存放不同接口的RateLimiter(key为接口名称,value为RateLimiter)
private ConcurrentHashMap<String, RateLimiter> map = new ConcurrentHashMap<>();
private RateLimiter rateLimiter;
@Value("${api.requestLimit}")
private int requestLimit;
/**
*
* @param request
* @param response
* @param handler 访问的目标方法
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
RateLimit annotation = method.getAnnotation(RateLimit.class);
String servletPath = request.getServletPath();//注解调用接口方法名,区分不同的限流策略
int limitNum = annotation == null ? requestLimit : annotation.limitNum();//获取注解每秒加入桶中的token
//获取rateLimiter
if(map.containsKey(servletPath)){
rateLimiter = map.get(servletPath);
} else {
map.put(servletPath, RateLimiter.create(limitNum));
rateLimiter = map.get(servletPath);
}
Assert.isTrue(rateLimiter.tryAcquire(), "请求繁忙,请稍后再试");
}
return super.preHandle(request, response, handler);
}
}
package com.lilosoft.config.interceptor;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.lilosoft.core.annotation.RepeatSubmit;
import com.lilosoft.core.model.JsonResult;
import com.lilosoft.core.utils.Json;
import com.lilosoft.core.utils.ServletUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
/**
* 防止重复提交拦截器
*
* @author ruoyi
*/
@Component
public abstract class RepeatSubmitInterceptor extends HandlerInterceptorAdapter
{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
{
if (handler instanceof HandlerMethod)
{
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class);
if (annotation != null)
{
if (this.isRepeatSubmit(request))
{
JsonResult jsonResult = JsonResult.returnException("不允许重复提交,请稍后再试");
ServletUtils.renderString(response, JSONUtil.toJsonStr(jsonResult));
return false;
}
}
return true;
}
else
{
return super.preHandle(request, response, handler);
}
}
/**
* 验证是否重复提交由子类实现具体的防重复提交的规则
*
* @return
* @throws Exception
*/
public abstract boolean isRepeatSubmit(HttpServletRequest request) throws Exception;
}
package com.lilosoft.core.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 不需要token验证
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthTokenIgnore {
}
package com.lilosoft.core.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* bean字段描述注解(导出excel,通过对象反射机制反射出注释名称填充列名时使用)
* @author Xuxiaoming
* @version 2017-11-22
*/
@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldDesc {
String desc();
}
package com.lilosoft.core.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 需要token验证
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {
int limitNum() default 20; //默认每秒放入桶中的token
}
package com.lilosoft.core.annotation;
import java.lang.annotation.*;
/**
* 自定义注解防止表单重复提交
*
* @author qiusheng
*
*/
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RepeatSubmit
{
}
\ No newline at end of file
package com.lilosoft.core.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 请求超时
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestTimeOut {
/** 过期时间,单位毫秒,默认30秒 **/
int value() default 30000;
}
package com.lilosoft.core.enums;
/**
* 错误码code可以使用纯数字,使用不同区间标识一类错误,也可以使用纯字符,也可以使用前缀+编号
*
* 错误码:ERR + 编号
*
* 可以使用日志级别的前缀作为错误类型区分 Info(I) Error(E) Warning(W)
*
* 或者以业务模块 + 错误号
*
* Alipay 用了两个code,两个msg(https://docs.open.alipay.com/api_1/alipay.trade.pay)
*/
public enum ApiCodeEnum {
SUCCESS("10000", "success"),
UNKNOW_ERROR("ERR0001","未知错误"),
PARAMETER_ERROR("ERR0002","参数错误"),
TOKEN_EXPIRE("ERR0003","认证过期"),
REQUEST_TIMEOUT("ERR0004","请求超时"),
SIGN_ERROR("ERR0005","签名错误"),
REPEAT_SUBMIT("ERR0006","请不要频繁操作"),
;
/** 代码 */
private String code;
/** 结果 */
private String msg;
ApiCodeEnum(String code, String msg) {
this.code = code;
this.msg = msg;
}
public String getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
package com.lilosoft.core.exception;
import com.lilosoft.core.model.JsonResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 全局的的异常拦截器(拦截所有的控制器)(带有@RequestMapping注解的方法上都会拦截)
*
* @author YanJie
*/
@ControllerAdvice
@Order(-1)
public class GlobalExceptionHandler {
private Logger log = LoggerFactory.getLogger(this.getClass());
/**
* token验证请求参数异常
*/
@ExceptionHandler(IllegalArgumentException.class)
@ResponseBody
public JsonResult illegalArgumentExceptionHandler(IllegalArgumentException exception) {
return JsonResult.returnException(exception);
}
/**
* 全局异常拦截,封装报错信息
*
* @param exception
* @return
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public JsonResult runtimeExceptionHandler(Exception exception) {
log.error("运行时操作异常:", exception);
return JsonResult.returnException(exception);
}
}
package com.lilosoft.core.exception;
/**
* 自定义 异常
*/
public class MyException extends RuntimeException {
private static final long serialVersionUID = -13345478421L;
private int code = ErrCode.ERR_500.getCode();
public MyException() {
super();
}
public MyException(ErrCode errCode,String msg) {
super(msg);
this.code = errCode.getCode();
}
public MyException(ErrCode errCode,String msg, Throwable cause) {
super(msg, cause);
this.code = errCode.getCode();
}
public MyException(ErrCode errCode,Throwable cause) {
super(cause);
this.code = errCode.getCode();
}
public int getCode() {
return code;
}
public MyException(String msg) {
super(msg);
}
public MyException(String msg, Throwable cause) {
super(msg, cause);
}
public MyException(Throwable cause) {
super(cause);
}
public enum ErrCode {
/**
* 业务错误
*/
ERR_500(500);
private Integer code;
private ErrCode(Integer code) {
this.code = code;
}
public Integer getCode() {
return code;
}
}
}
package com.lilosoft.core.executor;
import com.lilosoft.core.executor.handler.Handler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @ClassName: NonOrderedQueuePoolExecutor
* @Description: 无序队列线程池
* @author: QiuSheng
* @date: 创建时间:2017年12月7日 下午4:07:33
*/
public class NonOrderedQueuePoolExecutor extends ThreadPoolExecutor {
/**
* 日志对象
*/
protected Logger logger = LoggerFactory.getLogger(getClass());
public NonOrderedQueuePoolExecutor(int corePoolSize) {
super(corePoolSize, corePoolSize, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
}
public void execute(Handler command) {
Work work = new Work(command);
execute(work);
}
private class Work implements Runnable {
private Handler command;
public Work(Handler command) {
this.command = command;
}
public void run() {
long start = System.currentTimeMillis();
try {
command.action();
} catch (Exception e) {
logger.error("command.getClass().getSimpleName() Exception", e);
} finally {
long end = System.currentTimeMillis();
if (end - start > 50) {
logger.error("NonOrderedQueuePoolExecutor-->" + command.getClass().getSimpleName() + " run:"
+ (end - start));
}
}
}
}
}
package com.lilosoft.core.executor;
import com.lilosoft.core.executor.structs.OrderedQueuePool;
import com.lilosoft.core.executor.structs.TasksQueue;
import com.lilosoft.core.executor.work.AbstractWork;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @ClassName: NonOrderedQueuePoolExecutor
* @Description: 有序队列线程池
* @author: QiuSheng
* @date: 创建时间:2017年12月7日 下午4:07:33
*/
public class OrderedQueuePoolExecutor extends ThreadPoolExecutor {
private Logger log = LogManager.getLogger(OrderedQueuePoolExecutor.class);
private OrderedQueuePool<Long, AbstractWork> pool = new OrderedQueuePool<Long, AbstractWork>();
private String name;
private int corePoolSize;
private int maxQueueSize;
public OrderedQueuePoolExecutor(String name, int corePoolSize, int maxQueueSize) {
// corePoolSize: 线程池维护线程的最少数量
// maximumPoolSize:线程池维护线程的最大数量
// keepAliveTime: 线程池维护线程所允许的空闲时间
// unit: 线程池维护线程所允许的空闲时间的单位
// workQueue: 线程池所使用的缓冲队列
// handler: 线程池对拒绝任务的处理策略
super(corePoolSize, 2 * corePoolSize, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
this.name = name;
this.corePoolSize = corePoolSize;
this.maxQueueSize = maxQueueSize;
}
public OrderedQueuePoolExecutor(int corePoolSize) {
this("queue-pool", corePoolSize, 10000);
}
/**
* 增加执行任务
*
* @param key
* @return
*/
public boolean addTask(Long key, AbstractWork task) {
key = key % corePoolSize;
TasksQueue<AbstractWork> queue = pool.getTasksQueue(key);
boolean run = false;
boolean result = false;
synchronized (queue) {
if (maxQueueSize > 0) {
if (queue.size() > maxQueueSize) {
log.error("队列" + name + "(" + key + ")" + "抛弃指令!");
queue.clear();
}
}
result = queue.add(task);
if (result) {
task.setTasksQueue(queue);
{
if (queue.isProcessingCompleted()) {
queue.setProcessingCompleted(false);
run = true;
}
}
} else {
log.error("orderedqueue队列添加任务失败");
}
}
if (run) {
execute(queue.poll());
}
return result;
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
AbstractWork work = (AbstractWork) r;
TasksQueue<AbstractWork> queue = work.getTasksQueue();
if (queue != null) {
AbstractWork afterWork = null;
synchronized (queue) {
afterWork = queue.poll();
if (afterWork == null) {
queue.setProcessingCompleted(true);
}
}
if (afterWork != null) {
execute(afterWork);
}
}
}
// /**
// * 获取任务执行队列
// * @param key
// * @return
// */
// public TasksQueue<AbstractWork> getTasksQueue(Long key){
// key = key % corePoolSize;
// return pool.getTasksQueue(key);
// }
/**
* 获取剩余任务数量
*/
public int getTaskCounts() {
int count = super.getActiveCount();
Iterator<Entry<Long, TasksQueue<AbstractWork>>> iter = pool.getTasksQueues().entrySet().iterator();
while (iter.hasNext()) {
Entry<Long, TasksQueue<AbstractWork>> entry = (Entry<Long, TasksQueue<AbstractWork>>) iter.next();
TasksQueue<AbstractWork> tasksQueue = entry.getValue();
// if(tasksQueue.size() > 0){
// log.error(entry.getKey() + " queue size:" + tasksQueue.size() +
// ", is run:" + tasksQueue.isProcessingCompleted());
// }
count += tasksQueue.size();
}
return count;
}
}
package com.lilosoft.core.executor.handler;
/**
* @ClassName: Handler
* @Description:
* @author: QiuSheng
* @date: 创建时间:2018年01月10日 上午8:51:33
*/
public abstract class Handler implements ICommand {
}
package com.lilosoft.core.executor.handler;
/**
* @ClassName: ICommand
* @Description:
* @author: QiuSheng
* @date: 创建时间:2018年01月10日 上午8:51:33
*/
public interface ICommand {
void action();
}
package com.lilosoft.core.executor.structs;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 消息队列
*/
public class MessageQueue<V> {
// private static int MAX_TASK = 100;
private Lock lock = new ReentrantLock();
// private Condition notFull = lock.newCondition();
private Condition notEmpty = lock.newCondition();
private final LinkedBlockingQueue<V> messageQueue = new LinkedBlockingQueue<V>();
private boolean processingCompleted = true;
/**
* 下一执行命令
*
* @return
*/
public V poll() throws InterruptedException {
try {
lock.lock();
while(0 == messageQueue.size()) {
notEmpty.await();
}
V obj = messageQueue.poll();
// notFull.signalAll();
return obj;
} finally {
lock.unlock();
}
}
/**
* 增加执行指令
* @return
*/
public boolean add(V value) throws InterruptedException {
try {
lock.lock();
// while (MAX_TASK == messageQueue.size()) {
// notFull.await();
// }
boolean ret = messageQueue.add(value);
notEmpty.signalAll();
return ret;
} finally {
lock.unlock();
}
}
/**
* 清理
*/
public void clear() {
try {
lock.lock();
messageQueue.clear();
} finally {
lock.unlock();
}
}
/**
* 获取指令数量
*
* @return
*/
public int size() {
return messageQueue.size();
}
public boolean isProcessingCompleted() {
return processingCompleted;
}
public void setProcessingCompleted(boolean processingCompleted) {
this.processingCompleted = processingCompleted;
}
}
package com.lilosoft.core.executor.structs;
import java.util.concurrent.ConcurrentHashMap;
public class OrderedQueuePool<K, V> {
ConcurrentHashMap<K, TasksQueue<V>> map = new ConcurrentHashMap<K, TasksQueue<V>>();
/**
* 官方推荐的API方法putIfAbsent
* @param key
* @return
*/
public TasksQueue<V> increase(K key) {
TasksQueue<V> queue;
while (true) {
queue = map.get(key);
if (queue == null) {
queue = new TasksQueue<V>();
if (map.putIfAbsent(key, queue) == null) {
break;
}
}
}
return queue;
}
/**
* 获得任务队列
* 存在问题:用synchronized锁,在put操作时并没有对整个Map加锁,所以一个线程正在put(k,v)的时候,另一个线程调用get(k)会得到null,这就会造成一个线程put的值会被另一个线程put的值所覆盖
* @param key
* @return
*/
public TasksQueue<V> getTasksQueue(K key) {
synchronized (map) {
TasksQueue<V> queue = map.get(key);
if (queue == null) {
queue = new TasksQueue<V>();
map.put(key, queue);
}
return queue;
}
}
/**
* 获得全部任务队列
*
* @return
*/
public ConcurrentHashMap<K, TasksQueue<V>> getTasksQueues() {
return map;
}
/**
* 移除任务队列
*
* @param key
* @return
*/
public void removeTasksQueue(K key) {
map.remove(key);
}
}
package com.lilosoft.core.executor.structs;
import java.util.ArrayDeque;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 命令队列
*/
public class TasksQueue<V> {
private Lock lock = new ReentrantLock();
/**
* 命令队列
*/
private final ArrayDeque<V> tasksQueue = new ArrayDeque<V>();
private boolean processingCompleted = true;
/**
* 下一执行命令
*
* @return
*/
public V poll() {
try {
lock.lock();
return tasksQueue.poll();
} finally {
lock.unlock();
}
}
/**
* 增加执行指令
*
* @return
*/
public boolean add(V value) {
try {
lock.lock();
return tasksQueue.add(value);
} finally {
lock.unlock();
}
}
/**
* 清理
*/
public void clear() {
try {
lock.lock();
tasksQueue.clear();
} finally {
lock.unlock();
}
}
/**
* 获取指令数量
*
* @return
*/
public int size() {
return tasksQueue.size();
}
public boolean isProcessingCompleted() {
return processingCompleted;
}
public void setProcessingCompleted(boolean processingCompleted) {
this.processingCompleted = processingCompleted;
}
}
package com.lilosoft.core.executor.work;
import com.lilosoft.core.executor.structs.TasksQueue;
public abstract class AbstractWork implements Runnable {
private TasksQueue<AbstractWork> tasksQueue;
public TasksQueue<AbstractWork> getTasksQueue() {
return tasksQueue;
}
public void setTasksQueue(TasksQueue<AbstractWork> tasksQueue) {
this.tasksQueue = tasksQueue;
}
}
package com.lilosoft.core.filter.xss;
import org.springframework.util.StringUtils;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* XSS 过滤器
* @author yanjie
* @Date 2018年11月12日
*/
public class XssAndSqlFilter implements Filter {
FilterConfig filterConfig = null;
private String ignoreUrl;
private boolean isConvert = false;
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
setIgnoreUrl(filterConfig.getInitParameter("ignoreUrl"));
if(filterConfig.getInitParameter("isConvert") != null) {
setConvert("true".equals(filterConfig.getInitParameter("isConvert")));
}
}
public void destroy() {
this.filterConfig = null;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String servletPath = httpServletRequest.getServletPath();
// System.out.println(">>>>>>>>>>>> "+servletPath);
if(ignoreUrl !=null && !"".equals(ignoreUrl)){
String[] wsPaths= StringUtils.split(ignoreUrl, ",");
boolean ignore = false;
for(String waPath : wsPaths){
waPath = StringUtils.replace("\t", "",waPath);
waPath = StringUtils.replace("\n", "",waPath);
waPath = waPath.trim();
if(servletPath.startsWith(waPath)){
ignore = true;
break;
}
}
if(ignore) {
chain.doFilter(request, response);
}else {
chain.doFilter(new XssAndSqlHttpServletRequestWrapper((HttpServletRequest) request,isConvert), response);
}
}else {
chain.doFilter(new XssAndSqlHttpServletRequestWrapper((HttpServletRequest) request,isConvert), response);
}
}
public final String getIgnoreUrl() {
return ignoreUrl;
}
public final void setIgnoreUrl(String ignoreUrl) {
this.ignoreUrl = ignoreUrl;
}
public boolean isConvert() {
return isConvert;
}
public void setConvert(boolean isConvert) {
this.isConvert = isConvert;
}
}
\ No newline at end of file
package com.lilosoft.core.filter.xss;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.Enumeration;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Vector;
import java.util.regex.Pattern;
/**
* XSS过滤器包装类
*
* @Author YanJie
* @Date 2018年11月12日
*/
public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrapper {
private Map<String, String[]> paramMap; // 所有参数的Map集合
private HttpServletRequest orgRequest = null;
private boolean isConvert = false;
public XssAndSqlHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
orgRequest = request;
paramMap = request.getParameterMap();
}
public XssAndSqlHttpServletRequestWrapper(HttpServletRequest request,boolean isConvert) {
super(request);
orgRequest = request;
paramMap = request.getParameterMap();
this.isConvert = isConvert;
}
/**
* 参数为Map时触发
*/
@Override
public Map<String, String[]> getParameterMap() {
for(Entry<String, String[]> entry:paramMap.entrySet()) {
String[] values = entry.getValue();
if(values != null && values.length > 0) {
for (int i = 0; i < values.length; i++) {
values[i] = xssEncode(entry.getKey(), values[i]);
}
}
}
return paramMap;
}
/**
* 获取所有参数名
*
* @return 返回所有参数名
*/
@Override
public Enumeration<String> getParameterNames() {
Vector<String> vector = new Vector<String>(paramMap.keySet());
return vector.elements();
}
/**
* 覆盖getParameter方法,将参数名和参数值都做xss & sql过滤。<br/>
* 如果需要获得原始的值,则通过super.getParameterValues(name)来获取<br/>
* getParameterNames,getParameterValues和getParameterMap也可能需要覆盖
* 获取指定参数名的值,如果有重复的参数名,则返回第一个的值 接收一般变量 ,如text类型
* @param name 指定参数名
* @return 指定参数名的值
*/
@Override
public String getParameter(String name) {
String[] value = paramMap.get(name);
if (value != null && value.length > 0) {
value[0] = xssEncode(name,value[0]);
return value[0];
}else {
return null;
}
}
/**
* 获取指定参数名的所有值的数组,如:checkbox的所有数据 接收数组变量 ,如checkobx类型
*/
@Override
public String[] getParameterValues(String name) {
String[] values = paramMap.get(name);
if (values == null) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = xssEncode(name,values[i]);
}
return encodedValues;
}
/**
* 覆盖getHeader方法,将参数名和参数值都做xss & sql过滤。<br/>
* 如果需要获得原始的值,则通过super.getHeaders(name)来获取<br/>
* getHeaderNames 也可能需要覆盖
*/
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
if (value != null) {
value = xssEncode(name,value);
}
return value;
}
/**
* @Description Cookie内容过滤
* @return
*/
@Override
public Cookie[] getCookies() {
Cookie[] existingCookies = super.getCookies();
if (existingCookies != null) {
for (int i = 0 ; i < existingCookies.length ; ++i) {
Cookie cookie = existingCookies[i];
cookie.setValue(stripXSSAndSql(cookie.getValue()));
}
}
return existingCookies;
}
/**
* 将容易引起xss & sql漏洞的半角字符直接替换成全角字符
*
* @param key
* @return
*/
public String xssEncode(String key,String value) {
if (value == null || value.isEmpty()) {
return value;
} else {
value = stripXSSAndSql(value);
}
if(isConvert) {
StringBuilder sb = new StringBuilder(value.length() + 16);
for (int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
switch (c) {
case '>':
sb.append(">");// 转义大于号
break;
case '<':
sb.append("<");// 转义小于号
break;
case '\'':
sb.append("'");// 转义单引号
break;
case '\"':
sb.append(""");// 转义双引号
break;
case '&':
sb.append("&");// 转义&
break;
case '#':
sb.append("#");// 转义#
break;
default:
sb.append(c);
break;
}
}
return sb.toString();
}else {
return value;
}
}
/**
* 获取最原始的request
*
* @return
*/
public HttpServletRequest getOrgRequest() {
return orgRequest;
}
/**
* 获取最原始的request的静态方法
*
* @return
*/
public static HttpServletRequest getOrgRequest(HttpServletRequest req) {
if (req instanceof XssAndSqlHttpServletRequestWrapper) {
return ((XssAndSqlHttpServletRequestWrapper) req).getOrgRequest();
}
return req;
}
/**
*
* 防止xss跨脚本攻击(替换,根据实际情况调整)
*/
public static String stripXSSAndSql(String value) {
if (value != null) {
// NOTE: It's highly recommended to use the ESAPI library and
// uncomment the following line to
// avoid encoded attacks.
// value = ESAPI.encoder().canonicalize(value);
// Avoid null characters
/** value = value.replaceAll("", ""); ***/
// Avoid anything between script tags
Pattern scriptPattern = Pattern.compile(
"<[\r\n| | ]*script[\r\n| | ]*>(.*?)</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid anything in a src="http://www.yihaomen.com/article/java/..." type of
// e-xpression
scriptPattern = Pattern.compile("src[\r\n| | ]*=[\r\n| | ]*[\\\"|\\\'](.*?)[\\\"|\\\']",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// Remove any lonesome </script> tag
scriptPattern = Pattern.compile("</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// Remove any lonesome <script ...> tag
scriptPattern = Pattern.compile("<[\r\n| | ]*script(.*?)>",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid eval(...) expressions
scriptPattern = Pattern.compile("eval\\((.*?)\\)",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid e-xpression(...) expressions
scriptPattern = Pattern.compile("e-xpression\\((.*?)\\)",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid javascript:... expressions
scriptPattern = Pattern.compile("javascript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid vbscript:... expressions
scriptPattern = Pattern.compile("vbscript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid onload= expressions
scriptPattern = Pattern.compile("onload(.*?)=",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
}
return value;
}
public Map<String, String[]> getParamMap() {
return paramMap;
}
public void setParamMap(Map<String, String[]> paramMap) {
this.paramMap = paramMap;
}
}
\ No newline at end of file
package com.lilosoft.core.model;
import java.io.Serializable;
import java.util.Date;
/**
* Bean基础类
* @author YanJie
* @version 2016-11-28
*/
public abstract class BaseBean implements Serializable {
public static final long serialVersionUID = 1L;
/**
* 主键id
*/
private String id;
/**
* 创建时间
*/
private Date createTime;
/**
* 可用标志[0:不可用; 1:可用]
*/
private String useFlag;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getUseFlag() {
return useFlag;
}
public void setUseFlag(String useFlag) {
this.useFlag = useFlag;
}
}
package com.lilosoft.core.model;
import org.springframework.util.StringUtils;
import java.io.Serializable;
public class JsonResult implements Serializable {
private static final long serialVersionUID = 1L;
private boolean success;
private String status;
private String msg;
private Object obj;
public JsonResult() {}
public boolean isSuccess() {
return this.success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getStatus() {
return this.status;
}
public void setStatus(String status) {
this.status = status;
}
public String getMsg() {
return this.msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getObj() {
return this.obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
public static JsonResult returnNoAuthException(Exception exception) {
JsonResult result = new JsonResult();
result.setSuccess(false);
result.setStatus("401");
result.setMsg(exception.getMessage());
return result;
}
public static JsonResult returnException(Exception exception) {
JsonResult result = new JsonResult();
result.setSuccess(false);
result.setStatus("500");
result.setMsg(exception.getMessage());
return result;
}
public static JsonResult returnException(String msg) {
JsonResult result = new JsonResult();
result.setSuccess(false);
result.setStatus("500");
result.setMsg(msg);
return result;
}
public static JsonResult returnException(Exception exception, String status) {
JsonResult result = new JsonResult();
result.setSuccess(false);
if (StringUtils.isEmpty(status)) {
result.setStatus("500");
} else {
result.setStatus(status);
}
result.setMsg(exception.getMessage());
return result;
}
public static JsonResult returnException(String msg, String status) {
JsonResult result = new JsonResult();
result.setSuccess(false);
if (StringUtils.isEmpty(status)) {
result.setStatus("500");
} else {
result.setStatus(status);
}
result.setMsg(msg);
return result;
}
}
package com.lilosoft.core.queue.command;
/**
* @author YanJie
*/
public interface Command {
void execute();
}
package com.lilosoft.core.queue.service;
import com.lilosoft.core.queue.command.Command;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.LinkedBlockingQueue;
/**
* @ClassName: FileTransQueueService
* @Description: 文件转换服务
* @author: YanJie
*/
public class FileTransQueueService extends Thread {
private boolean status = true;
protected static FileTransQueueService instance = new FileTransQueueService();
protected Logger logger = LoggerFactory.getLogger(getClass());
private final LinkedBlockingQueue<Command> queue = new LinkedBlockingQueue<Command>(100);
public synchronized static FileTransQueueService getInstance() {
if (instance == null) {
instance = new FileTransQueueService();
}
return instance;
}
@Override
public void run() {
while(status){
execute();
}
}
/**
* 向队列推送消息
* @param command
*/
public void putCommand(Command command) {
try{
/**
* LinkedBlockingQueue.put():首选。队满是阻塞
* LinkedBlockingQueue.offer():队满时返回false
*/
queue.put(command);
// if (queue.isProcessingCompleted()) {
// queue.setProcessingCompleted(false);
// }
System.out.println(queue.size());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取队列未完成数量
* @return
*/
public int getQueueSize(){
return queue.size();
}
private void execute(){
try {
/**
* LinkedBlockingQueue.take():首选。当队列为空时阻塞
* LinkedBlockingQueue.poll():弹出队顶元素,队列为空时,返回空
*/
Command command = queue.take();
if (command != null) {
command.execute();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void close(){
status = false;
}
}
package com.lilosoft.core.queue.service;
import com.lilosoft.core.queue.command.Command;
import java.util.concurrent.LinkedBlockingQueue;
/**
* @ClassName: SystemQueueService
* @Description: 系统队列服务
* @author: YanJie
*/
public class SystemQueueService extends Thread {
private boolean status = true;
protected static SystemQueueService instance = new SystemQueueService();
private final LinkedBlockingQueue<Command> queue = new LinkedBlockingQueue<Command>(100);
public synchronized static SystemQueueService getInstance() {
if (instance == null) {
instance = new SystemQueueService();
}
return instance;
}
@Override
public void run() {
while(status){
execute();
}
}
/**
* 向短信队列推送待发送短信消息体
*/
public void putCommand(Command command) {
try{
/**
* LinkedBlockingQueue.put():首选。队满是阻塞
* LinkedBlockingQueue.offer():队满时返回false
*/
queue.put(command);
// if (queue.isProcessingCompleted()) {
// queue.setProcessingCompleted(false);
// }
System.out.println(queue.size());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取短信队列未发送短信数量
* @return
*/
public int getQueueSize(){
return queue.size();
}
private void execute(){
try {
/**
* LinkedBlockingQueue.take():首选。当队列为空时阻塞
* LinkedBlockingQueue.poll():弹出队顶元素,队列为空时,返回空
*/
Command command = queue.take();
if (command != null) {
command.execute();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void close(){
status = false;
}
}
package com.lilosoft.core.utils;
import com.lilosoft.core.annotation.AuthTokenIgnore;
import com.lilosoft.core.annotation.RequestTimeOut;
import org.springframework.web.method.HandlerMethod;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class ApiUtil {
/**
* 按参数名升续拼接参数
* @param request
* @return
*/
public static String concatSignString(HttpServletRequest request) {
Map<String, String> paramterMap = new HashMap<>();
request.getParameterMap().forEach((key, value) -> paramterMap.put(key, value[0]));
// 按照key升续排序,然后拼接参数
Set<String> keySet = paramterMap.keySet();
String[] keyArray = keySet.toArray(new String[keySet.size()]);
Arrays.sort(keyArray);
StringBuilder sb = new StringBuilder();
for (String k : keyArray) {
// 或略掉的字段
if (k.equals("sign")) {
continue;
}
if (paramterMap.get(k).trim().length() > 0) {
// 参数值为空,则不参与签名
sb.append(k).append("=").append(paramterMap.get(k).trim()).append("&");
}
}
return sb.toString();
}
public static String concatSignString(Map<String, String> map) {
Map<String, String> paramterMap = new HashMap<>();
map.forEach((key, value) -> paramterMap.put(key, value));
// 按照key升续排序,然后拼接参数
Set<String> keySet = paramterMap.keySet();
String[] keyArray = keySet.toArray(new String[keySet.size()]);
Arrays.sort(keyArray);
StringBuilder sb = new StringBuilder();
for (String k : keyArray) {
if (paramterMap.get(k).trim().length() > 0) {
// 参数值为空,则不参与签名
sb.append(k).append("=").append(paramterMap.get(k).trim()).append("&");
}
}
return sb.toString();
}
/**
* 获取方法上的@NotRepeatSubmit注解
* @param handler
* @return
*/
public static RequestTimeOut getNotRepeatSubmit(Object handler) {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
RequestTimeOut annotation = method.getAnnotation(RequestTimeOut.class);
return annotation;
}
return null;
}
/**
* 获取方法上的@AuthToken注解
* @param handler
* @return
*/
public static AuthTokenIgnore getAuthToken(Object handler) {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
AuthTokenIgnore annotation = method.getAnnotation(AuthTokenIgnore.class);
return annotation;
}
return null;
}
}
package com.lilosoft.core.utils;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* 精确的浮点数运算
*
* @author ruoyi
*/
public class Arith
{
/** 默认除法运算精度 */
private static final int DEF_DIV_SCALE = 10;
/** 这个类不能实例化 */
private Arith()
{
}
/**
* 提供精确的加法运算。
* @param v1 被加数
* @param v2 加数
* @return 两个参数的和
*/
public static double add(double v1, double v2)
{
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue();
}
/**
* 提供精确的减法运算。
* @param v1 被减数
* @param v2 减数
* @return 两个参数的差
*/
public static double sub(double v1, double v2)
{
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.subtract(b2).doubleValue();
}
/**
* 提供精确的乘法运算。
* @param v1 被乘数
* @param v2 乘数
* @return 两个参数的积
*/
public static double mul(double v1, double v2)
{
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2).doubleValue();
}
/**
* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
* 小数点以后10位,以后的数字四舍五入。
* @param v1 被除数
* @param v2 除数
* @return 两个参数的商
*/
public static double div(double v1, double v2)
{
return div(v1, v2, DEF_DIV_SCALE);
}
/**
* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
* 定精度,以后的数字四舍五入。
* @param v1 被除数
* @param v2 除数
* @param scale 表示表示需要精确到小数点以后几位。
* @return 两个参数的商
*/
public static double div(double v1, double v2, int scale)
{
if (scale < 0)
{
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
if (b1.compareTo(BigDecimal.ZERO) == 0)
{
return BigDecimal.ZERO.doubleValue();
}
return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue();
}
/**
* 提供精确的小数位四舍五入处理。
* @param v 需要四舍五入的数字
* @param scale 小数点后保留几位
* @return 四舍五入后的结果
*/
public static double round(double v, int scale)
{
if (scale < 0)
{
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
BigDecimal one = new BigDecimal("1");
return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue();
}
}
package com.lilosoft.core.utils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* Base64Helper
*
* @version 1.0.0
* @author:YanJie
* @creat:2013-7-22-下午02:45:10
*/
public class Base64Helper {
private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
.toCharArray();
public static String encode(byte[] data) {
int start = 0;
int len = data.length;
StringBuffer buf = new StringBuffer(data.length * 3 / 2);
int end = len - 3;
int i = start;
// int n = 0;
while (i <= end) {
int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 0x0ff) << 8)
| (((int) data[i + 2]) & 0x0ff);
buf.append(legalChars[(d >> 18) & 63]);
buf.append(legalChars[(d >> 12) & 63]);
buf.append(legalChars[(d >> 6) & 63]);
buf.append(legalChars[d & 63]);
i += 3;
// if (n++ >= 14) {
// n = 0;
// buf.append(" ");
// }
}
if (i == start + len - 2) {
int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 255) << 8);
buf.append(legalChars[(d >> 18) & 63]);
buf.append(legalChars[(d >> 12) & 63]);
buf.append(legalChars[(d >> 6) & 63]);
buf.append("=");
} else if (i == start + len - 1) {
int d = (((int) data[i]) & 0x0ff) << 16;
buf.append(legalChars[(d >> 18) & 63]);
buf.append(legalChars[(d >> 12) & 63]);
buf.append("==");
}
return buf.toString();
}
private static int decode(char c) {
if (c >= 'A' && c <= 'Z')
return ((int) c) - 65;
else if (c >= 'a' && c <= 'z')
return ((int) c) - 97 + 26;
else if (c >= '0' && c <= '9')
return ((int) c) - 48 + 26 + 26;
else
switch (c) {
case '+':
return 62;
case '/':
return 63;
case '=':
return 0;
default:
throw new RuntimeException("unexpected code: " + c);
}
}
public static byte[] decode(String s) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
decode(s, bos);
} catch (IOException e) {
throw new RuntimeException();
}
byte[] decodedBytes = bos.toByteArray();
try {
bos.close();
bos = null;
} catch (IOException ex) {
System.err.println("Error while decoding BASE64: " + ex.toString());
}
return decodedBytes;
}
private static void decode(String s, OutputStream os) throws IOException {
int i = 0;
int len = s.length();
while (true) {
while (i < len && s.charAt(i) <= ' ')
i++;
if (i == len)
break;
int tri = (decode(s.charAt(i)) << 18) + (decode(s.charAt(i + 1)) << 12)
+ (decode(s.charAt(i + 2)) << 6) + (decode(s.charAt(i + 3)));
os.write((tri >> 16) & 255);
if (s.charAt(i + 2) == '=')
break;
os.write((tri >> 8) & 255);
if (s.charAt(i + 3) == '=')
break;
os.write(tri & 255);
i += 4;
}
}
}
package com.lilosoft.core.utils;
import java.io.Serializable;
/**
* @author GuJiale
*
*/
public class Json implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1981503077969785993L;
/**
*
*/
private boolean success = false;
/**
*
*/
private String msg = "";
/**
*
*/
private Object obj = null;
public boolean isSuccess() {
return success;
}
public Json setSuccess(boolean success) {
this.success = success;
return this;
}
public String getMsg() {
return msg;
}
public Json setMsg(String msg) {
this.msg = msg;
return this;
}
public Object getObj() {
return obj;
}
public Json setObj(Object obj) {
this.obj = obj;
return this;
}
}
package com.lilosoft.core.utils;
import java.security.MessageDigest;
public class MD5Util {
private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
private static String byteArrayToHexString(byte b[]) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++)
resultSb.append(byteToHexString(b[i]));
return resultSb.toString();
}
private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
n += 256;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
public static String encode(String origin) {
return encode(origin, "UTF-8");
}
public static String encode(String origin, String charsetname) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
if (charsetname == null || "".equals(charsetname))
resultString = byteArrayToHexString(md.digest(resultString
.getBytes()));
else
resultString = byteArrayToHexString(md.digest(resultString
.getBytes(charsetname)));
} catch (Exception exception) {
}
return resultString;
}
}
package com.lilosoft.core.utils;
import java.math.BigDecimal;
/**
* @ClassName: NumberToCN
* @Description:
* @author: QiuSheng
* @date: 创建时间:2017年10月30日 下午3:08:32
*/
public class NumberToCN {
/**
* 汉语中数字大写
*/
private static final String[] CN_UPPER_NUMBER = { "零", "壹", "贰", "叁", "肆",
"伍", "陆", "柒", "捌", "玖" };
/**
* 汉语中货币单位大写,这样的设计类似于占位符
*/
private static final String[] CN_UPPER_MONETRAY_UNIT = { "分", "角", "元",
"拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "兆", "拾",
"佰", "仟" };
/**
* 特殊字符:整
*/
private static final String CN_FULL = "整";
/**
* 特殊字符:负
*/
private static final String CN_NEGATIVE = "负";
/**
* 金额的精度,默认值为2
*/
private static final int MONEY_PRECISION = 2;
/**
* 特殊字符:零元整
*/
private static final String CN_ZEOR_FULL = "零元" + CN_FULL;
/**
* 把输入的金额转换为汉语中人民币的大写
*
* @param numberOfMoney
* 输入的金额
* @return 对应的汉语大写
*/
public static String number2CNMontrayUnit(BigDecimal numberOfMoney) {
StringBuffer sb = new StringBuffer();
// -1, 0, or 1 as the value of this BigDecimal is negative, zero, or
// positive.
int signum = numberOfMoney.signum();
// 零元整的情况
if (signum == 0) {
return CN_ZEOR_FULL;
}
//这里会进行金额的四舍五入
long number = numberOfMoney.movePointRight(MONEY_PRECISION)
.setScale(0, 4).abs().longValue();
// 得到小数点后两位值
long scale = number % 100;
int numUnit = 0;
int numIndex = 0;
boolean getZero = false;
// 判断最后两位数,一共有四中情况:00 = 0, 01 = 1, 10, 11
if (!(scale > 0)) {
numIndex = 2;
number = number / 100;
getZero = true;
}
if ((scale > 0) && (!(scale % 10 > 0))) {
numIndex = 1;
number = number / 10;
getZero = true;
}
int zeroSize = 0;
while (true) {
if (number <= 0) {
break;
}
// 每次获取到最后一个数
numUnit = (int) (number % 10);
if (numUnit > 0) {
if ((numIndex == 9) && (zeroSize >= 3)) {
sb.insert(0, CN_UPPER_MONETRAY_UNIT[6]);
}
if ((numIndex == 13) && (zeroSize >= 3)) {
sb.insert(0, CN_UPPER_MONETRAY_UNIT[10]);
}
sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
sb.insert(0, CN_UPPER_NUMBER[numUnit]);
getZero = false;
zeroSize = 0;
} else {
++zeroSize;
if (!(getZero)) {
sb.insert(0, CN_UPPER_NUMBER[numUnit]);
}
if (numIndex == 2) {
if (number > 0) {
sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
}
} else if (((numIndex - 2) % 4 == 0) && (number % 1000 > 0)) {
sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
}
getZero = true;
}
// 让number每次都去掉最后一个数
number = number / 10;
++numIndex;
}
// 如果signum == -1,则说明输入的数字为负数,就在最前面追加特殊字符:负
if (signum == -1) {
sb.insert(0, CN_NEGATIVE);
}
// 输入的数字小数点后两位为"00"的情况,则要在最后追加特殊字符:整
if (!(scale > 0)) {
sb.append(CN_FULL);
}
return sb.toString();
}
public static void main(String[] args) {
double money = 2020004.0099999999;
BigDecimal numberOfMoney = new BigDecimal(money);
String s = NumberToCN.number2CNMontrayUnit(numberOfMoney);
System.out.println("你输入的金额为:【"+ money +"】 #--# [" +s.toString()+"]");
}
}
package com.lilosoft.core.utils;
import org.springframework.lang.Nullable;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
public class ObjectUtils {
private ObjectUtils() {
}
public static boolean isEmpty(@Nullable Object obj) {
if (obj == null) {
return true;
} else if (obj instanceof Optional) {
return !((Optional)obj).isPresent();
} else if (obj instanceof CharSequence) {
return ((CharSequence)obj).toString().trim().length() == 0;
} else if (obj.getClass().isArray()) {
return Array.getLength(obj) == 0;
} else if (obj instanceof Collection) {
return ((Collection)obj).isEmpty();
} else {
return obj instanceof Map ? ((Map)obj).isEmpty() : false;
}
}
}
package com.lilosoft.core.utils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* 客户端工具类
*
* @author qiusheng
*/
public class ServletUtils
{
/**
* 获取String参数
*/
public static String getParameter(String name)
{
return getRequest().getParameter(name);
}
/**
* 获取request
*/
public static HttpServletRequest getRequest()
{
return getRequestAttributes().getRequest();
}
/**
* 获取response
*/
public static HttpServletResponse getResponse()
{
return getRequestAttributes().getResponse();
}
/**
* 获取session
*/
public static HttpSession getSession()
{
return getRequest().getSession();
}
public static ServletRequestAttributes getRequestAttributes()
{
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
return (ServletRequestAttributes) attributes;
}
/**
* 将字符串渲染到客户端
*
* @param response 渲染对象
* @param string 待渲染的字符串
* @return null
*/
public static String renderString(HttpServletResponse response, String string)
{
try
{
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().print(string);
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
}
package com.lilosoft.core.utils;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.*;
/**
* 流转换工具类
* @author YanJie
*
*/
public class StreamUtils {
final static int BUFFER_SIZE = 4096;
/**
* 将InputStream转换成String
*
* @param in
* InputStream
* @return String
* @throws Exception
*
*/
public static String InputStreamTOString(InputStream in) {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] data = new byte[BUFFER_SIZE];
String string = null;
int count = 0;
try {
while ((count = in.read(data, 0, BUFFER_SIZE)) != -1)
outStream.write(data, 0, count);
} catch (IOException e) {
e.printStackTrace();
}
data = null;
try {
string = new String(outStream.toByteArray(), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return string;
}
/**
* 将InputStream转换成某种字符编码的String
*
* @param in
* @param encoding
* @return
* @throws Exception
*/
public static String InputStreamTOString(InputStream in, String encoding) {
String string = null;
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] data = new byte[BUFFER_SIZE];
int count = -1;
try {
while ((count = in.read(data, 0, BUFFER_SIZE)) != -1)
outStream.write(data, 0, count);
} catch (IOException e) {
e.printStackTrace();
}
data = null;
try {
string = new String(outStream.toByteArray(), encoding);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return string;
}
/**
* 将String转换成InputStream
*
* @param in
* @return
* @throws Exception
*/
public static InputStream StringTOInputStream(String in) throws Exception {
ByteArrayInputStream is = new ByteArrayInputStream(in.getBytes("UTF-8"));
return is;
}
/**
* 将String转换成InputStream
*
* @param in
* @return
* @throws Exception
*/
public static byte[] StringTObyte(String in) {
byte[] bytes = null;
try {
bytes = InputStreamTOByte(StringTOInputStream(in));
} catch (IOException e) {
} catch (Exception e) {
e.printStackTrace();
}
return bytes;
}
/**
* 将InputStream转换成byte数组
*
* @param in
* InputStream
* @return byte[]
* @throws IOException
*/
public static byte[] InputStreamTOByte(InputStream in) throws IOException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] data = new byte[BUFFER_SIZE];
int count = -1;
while ((count = in.read(data, 0, BUFFER_SIZE)) != -1)
outStream.write(data, 0, count);
data = null;
return outStream.toByteArray();
}
/**
* 将byte数组转换成InputStream
*
* @param in
* @return
* @throws Exception
*/
public static InputStream byteTOInputStream(byte[] in) throws Exception {
ByteArrayInputStream is = new ByteArrayInputStream(in);
return is;
}
/**
* 将byte数组转换成String
*
* @param in
* @return
* @throws Exception
*/
public static String byteTOString(byte[] in) {
InputStream is = null;
try {
is = byteTOInputStream(in);
} catch (Exception e) {
e.printStackTrace();
}
return InputStreamTOString(is, "UTF-8");
}
/**
* 将byte数组转换成String
*
* @param in
* @return
* @throws Exception
*/
public static String getString(String in) {
String is = null;
try {
is = byteTOString(StringTObyte(in));
} catch (Exception e) {
e.printStackTrace();
}
return is;
}
// InputStream 转换成byte[]
public byte[] getBytes(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] b = new byte[BUFFER_SIZE];
int len = 0;
while ((len = is.read(b, 0, BUFFER_SIZE)) != -1) {
baos.write(b, 0, len);
}
baos.flush();
byte[] bytes = baos.toByteArray();
System.out.println(new String(bytes));
return bytes;
}
/**
* 根据文件路径创建文件输入流处理
* 以字节为单位(非 unicode )
* @return
*/
public static FileInputStream getFileInputStream(String filepath) {
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(filepath);
} catch (FileNotFoundException e) {
System.out.print("错误信息:文件不存在");
e.printStackTrace();
}
return fileInputStream;
}
/**
* 根据文件对象创建文件输入流处理
* 以字节为单位(非 unicode )
* @return
*/
public static FileInputStream getFileInputStream(File file) {
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
System.out.print("错误信息:文件不存在");
e.printStackTrace();
}
return fileInputStream;
}
/**
* 根据文件对象创建文件输出流处理
* 以字节为单位(非 unicode )
* @param file
* @param append true:文件以追加方式打开,false:则覆盖原文件的内容
* @return
*/
public static FileOutputStream getFileOutputStream(File file,boolean append) {
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(file,append);
} catch (FileNotFoundException e) {
System.out.print("错误信息:文件不存在");
e.printStackTrace();
}
return fileOutputStream;
}
/**
* 根据文件路径创建文件输出流处理
* 以字节为单位(非 unicode )
* @param append true:文件以追加方式打开,false:则覆盖原文件的内容
* @return
*/
public static FileOutputStream getFileOutputStream(String filepath,boolean append) {
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(filepath,append);
} catch (FileNotFoundException e) {
System.out.print("错误信息:文件不存在");
e.printStackTrace();
}
return fileOutputStream;
}
/**
* BufferedImage转成InputStream
* @param bimage
* @return
*/
public static ByteArrayInputStream getImageStream(BufferedImage bimage){
ByteArrayInputStream is = null;
ByteArrayOutputStream bs = new ByteArrayOutputStream();
ImageOutputStream imOut;
try {
imOut = ImageIO.createImageOutputStream(bs);
ImageIO.write(bimage, "png",imOut);
is= new ByteArrayInputStream(bs.toByteArray());
} catch (IOException e) {
e.printStackTrace();
}
return is;
}
public static File getFile(String filepath) {
return new File(filepath);
}
public static ByteArrayOutputStream getByteArrayOutputStream() {
return new ByteArrayOutputStream();
}
}
\ No newline at end of file
################### api配置 ###################
api:
xss-open: true #是否开启xss跨站脚本攻击防护支持 (true/false)
requestLimit: 30 #接口每秒请求限制
baseUrl: @profiles.baseUrl@ #审批系统地址
ocrUrl: @profiles.ocrUrl@ #资料预审接口地址
apiUrl: @profiles.apiUrl@ #资料预审配置接口地址
mq: @profiles.mq@ #mq监听队列名称
scheduled: #定时任务推送
monitorCron: 0 0/5 * * * ?
monitorOpen: true
################### 项目启动端口 ################### ocrUrl: https://api.egovrobot.com/rocr/ http://192.168.2.180:8099
server:
port: @profiles.server.port@ #端口
tomcat:
max-threads: 800 #tomcat最大线程数,默认为200
uri-encoding: utf-8
max-http-form-post-size: 10MB
servlet:
context-path: /
################### 日志配置 ###################
logging:
level:
com.lilosoft: debug
org.springframework: warn
################### spring配置 ###################
spring:
http:
encoding:
force: true
charset: UTF-8
enabled: true
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
serialization:
write-dates-as-timestamps: false
jms:
pub-sub-domain: false #false点对点队列模式 true订阅模式
template:
delivery-mode: persistent #持久化
activemq:
brokerUrl: @profiles.activemq.brokerUrl@
user: root
password: lilo!@#2020@lilosoft!@#2021
close-timeout: 15s # 在考虑结束之前等待的时间
in-memory: false # 默认代理URL是否应该在内存中。如果指定了显式代理,则忽略此值。
pool:
enabled: false
# max-connections: 10
packages:
trust-all: true
__ __ _
_ __ ___ / / _____ ____ ____ ___ ___ / /_ ____ ____ _ ____ (_)
| | /| / / / _ \ / / / ___/ / __ \ / __ `__ \ / _ \ / __/ / __ \ / __ `/ / __ \ / /
| |/ |/ / / __/ / / / /__ / /_/ / / / / / / // __/ / /_ / /_/ / / /_/ / / /_/ / / /
|__/|__/ \___/ /_/ \___/ \____/ /_/ /_/ /_/ \___/ \__/ \____/ \__,_/ / .___/ /_/
/_/
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 定义变量后,可以使“${}”来使用变量 source来源为spring 上下文信息 -->
<springProperty scope="context" name="springApplicationName" source="spring.application.name"/>
<springProperty scope="context" name="serverPort" source="server.port"/>
<springProperty scope="context" name="logFilePath" source="application.log.path" defaultValue="/home/mortals/app/logs" />
<springProperty scope="context" name="logLevel" source="application.log.level" defaultValue="INFO" />
<!-- appender用来格式化日志输出节点,有俩个属性name和class,class用来指定哪种输出策略,常用就是控制台输出策略和文件输出策略 -->
<!-- 控制台输出策略-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%X{traceId}] [%thread] [%.50c\(%L\)] - %msg%n</pattern>
</encoder>
</appender>
<!-- 文件输出策略-->
<appender name="fileInfo" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%X{traceId}] [%thread] [%.50c\(%L\)] - %msg%n</pattern>
</encoder>
<file>${logFilePath}/${springApplicationName:-default}/${springApplicationName:-default}-info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 文件保存策略-->
<fileNamePattern>${logFilePath}/${springApplicationName:-default}/${springApplicationName:-default}-info.log.%d{yyyyMMdd}</fileNamePattern>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
<!--日志文件保留天数-->
<MaxHistory>15</MaxHistory>
</rollingPolicy>
</appender>
<!-- 异常文件输出策略-->
<appender name="fileError" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%X{traceId}] [%thread] [%.50c\(%L\)] - %msg%n</pattern>
</encoder>
<file>${logFilePath}/${springApplicationName:-default}/${springApplicationName:-default}-error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${logFilePath}/${springApplicationName:-default}/${springApplicationName:-default}-error.log.%d{yyyyMMdd}</fileNamePattern>
<!--日志文件保留天数-->
<cleanHistoryOnStart>true</cleanHistoryOnStart>
<MaxHistory>15</MaxHistory>
</rollingPolicy>
</appender>
<root level="${logLevel}">
<appender-ref ref="console"/>
<appender-ref ref="fileInfo"/>
<appender-ref ref="fileError"/>
</root>
<!--TRACE < DEBUG < INFO < WARN < ERROR < FATAL -->
<!--用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>。<logger>仅有一个name属性,一个可选的level和一个可选的additivity属性。-->
<!-- name 用来指定受此loger约束的某一个包或者具体的某一个类-->
<!-- level 用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。如果未设置此属性,那么当前logger将会继承上级的级别-->
<!-- additivity 是否向上级logger传递打印信息。默认是true。false:表示只用当前logger的appender-ref。true:表示当前logger的appender-ref和rootLogger的appender-ref都有效。-->
<logger name="com.mortals" level="${logLevel}" additivity="false">
<appender-ref ref="console"/>
<appender-ref ref="fileInfo"/>
<appender-ref ref="fileError"/>
</logger>
<logger name="com.mortals.xhx.module" level="${logLevel}" additivity="false">
<appender-ref ref="console"/>
<appender-ref ref="fileInfo"/>
<appender-ref ref="fileError"/>
</logger>
</configuration>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment