diff --git a/asr-service/.settings/org.eclipse.core.resources.prefs b/asr-service/.settings/org.eclipse.core.resources.prefs index f9fe345..e9441bb 100644 --- a/asr-service/.settings/org.eclipse.core.resources.prefs +++ b/asr-service/.settings/org.eclipse.core.resources.prefs @@ -1,4 +1,3 @@ eclipse.preferences.version=1 encoding//src/main/java=UTF-8 -encoding//src/test/java=UTF-8 encoding/=UTF-8 diff --git a/asr-service/pom.xml b/asr-service/pom.xml index ec3ff9c..97afb7a 100644 --- a/asr-service/pom.xml +++ b/asr-service/pom.xml @@ -22,5 +22,188 @@ 3.8.1 test - + + org.springframework.boot + spring-boot-starter-web + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + org.springframework.boot + spring-boot-starter-actuator + + + org.projectlombok + lombok + + + com.alibaba + fastjson + 2.0.17 + + + org.apache.httpcomponents + httpclient + 4.5.3 + + + org.apache.httpcomponents + httpmime + 4.5.13 + + + commons-lang + commons-lang + 2.6 + + + + com.squareup.okhttp3 + okhttp + 3.14.9 + + + org.springframework.kafka + spring-kafka + + + + org.apache.poi + poi + 4.1.2 + + + org.apache.poi + poi-ooxml + 4.1.2 + + + + + com.alibaba.fastjson2 + fastjson2 + 2.0.21 + + + + com.aliyun + alibabacloud-quanmiaolightapp20240801 + 2.0.33 + + + com.aliyun + alibabacloud-aimiaobi20230801 + 1.0.89 + + + org.projectlombok + lombok + 1.18.30 + + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + org.springframework.boot + spring-boot-maven-plugin + + com.bw.asr.Application + ZIP + + + ${project.groupId} + ${project.artifactId} + + + + + + + repackage + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.1.1 + + + copy + package + + copy-dependencies + + + jar + jar + runtime + ${project.build.directory}/libs + + + + + + + diff --git a/asr-service/src/main/java/com/bw/App.java b/asr-service/src/main/java/com/bw/App.java deleted file mode 100644 index d38a3e4..0000000 --- a/asr-service/src/main/java/com/bw/App.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.bw; - -/** - * Hello world! - * - */ -public class App -{ - public static void main( String[] args ) - { - System.out.println( "Hello World!" ); - } -} diff --git a/asr-service/src/main/java/com/bw/asr/Application.java b/asr-service/src/main/java/com/bw/asr/Application.java new file mode 100644 index 0000000..166eaf5 --- /dev/null +++ b/asr-service/src/main/java/com/bw/asr/Application.java @@ -0,0 +1,19 @@ +package com.bw.asr; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + + +/** + * 系统接口启动类 + * @author jian.mao + * @date 2025年12月30日 + * @description + */ +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/asr-service/src/main/java/com/bw/asr/cache/ConfigCache.java b/asr-service/src/main/java/com/bw/asr/cache/ConfigCache.java new file mode 100644 index 0000000..2397ac1 --- /dev/null +++ b/asr-service/src/main/java/com/bw/asr/cache/ConfigCache.java @@ -0,0 +1,37 @@ +package com.bw.asr.cache; + +import lombok.extern.slf4j.Slf4j; + +import java.util.Map; +import java.util.concurrent.LinkedBlockingDeque; + +/** + * @author jian.mao + * @date 2022年11月11日 + * @description 静态变量类 + */ +@Slf4j +public class ConfigCache { + + /**启动条件**/ + public static boolean isStart = true; + /*****任务队列*****/ + public static LinkedBlockingDeque> taskQueue = new LinkedBlockingDeque>(); + /****结果队列****/ + public static LinkedBlockingDeque> resultQueue = new LinkedBlockingDeque>(); + + + /** + * 队列录入任务 + * @param queue + * @param task + */ + public static void putQueue(LinkedBlockingDeque> queue,Map task){ + //next app 写入队列准备调出 + try { + queue.put(task); + } catch (InterruptedException e) { + log.error("队列写入data失败---"); + } + } +} diff --git a/asr-service/src/main/java/com/bw/asr/controller/TaskReceiveController.java b/asr-service/src/main/java/com/bw/asr/controller/TaskReceiveController.java new file mode 100644 index 0000000..e167fd2 --- /dev/null +++ b/asr-service/src/main/java/com/bw/asr/controller/TaskReceiveController.java @@ -0,0 +1,39 @@ +package com.bw.asr.controller; + +import javax.annotation.Resource; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.bw.asr.service.TaskReceiveService; + +import lombok.extern.slf4j.Slf4j; + +/** + * 任务接收控制层 + * @author jian.mao + * @date 2025年1月14日 + * @description + */ +@Controller +@RequestMapping("/task") +@Slf4j +public class TaskReceiveController { + @Resource + private TaskReceiveService taskReceiveService; + @PostMapping("/put") + @ResponseBody + public String put(@RequestBody String param){ + String response = taskReceiveService.put(param); + return response; + } + @RequestMapping(value = "/hello", method = RequestMethod.GET) + @ResponseBody + public String hello(String param, String token) { + return "123"; + } +} diff --git a/asr-service/src/main/java/com/bw/asr/entity/AppResultDoc.java b/asr-service/src/main/java/com/bw/asr/entity/AppResultDoc.java new file mode 100644 index 0000000..35060e7 --- /dev/null +++ b/asr-service/src/main/java/com/bw/asr/entity/AppResultDoc.java @@ -0,0 +1,42 @@ +package com.bw.asr.entity; + + +import java.io.Serializable; +import java.util.Map; + + +import lombok.Data; + +/** + * ES 索引:opai_app_result + * 应用执行结果文档 + * + * @author jian.mao + */ +@Data +public class AppResultDoc implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 任务ID */ + private String taskId; + + /** 应用id */ + private Integer appId; + + /** 状态 0 进行中,1成功,2失败 */ + private Integer status; + + /** 创建时间(毫秒时间戳) */ + private Long createTime; + + /** 执行结果(可索引) */ + private Map result; + + /** 逻辑删除标识:0-未删除 1-已删除 */ + private Integer del; + + /***前端输入参数 ***/ + private Map input; + +} diff --git a/asr-service/src/main/java/com/bw/asr/entity/Constants.java b/asr-service/src/main/java/com/bw/asr/entity/Constants.java new file mode 100644 index 0000000..effe70d --- /dev/null +++ b/asr-service/src/main/java/com/bw/asr/entity/Constants.java @@ -0,0 +1,45 @@ +package com.bw.asr.entity; + + +/** + * 常量实体类 + * @author jian.mao + * @date 2022年11月15日 + * @description + */ + +public class Constants { + + /** + * 空字符串常量 + */ + public static final String EMPTY = ""; + + /************************应用参数*************************************/ + public static final String CODE = "code"; + public static final String ID = "id"; + public static final String MESSAGE = "message"; + /******************************api使用*******************************/ + public static final String ERROR = "error"; + public static final String TRACE = "trace"; + public static final String WORKSPACEID = "workspaceId"; + public static final String VIDEOURL = "videoUrl"; + public static final String VIDEOMODELID = "videoModelId"; + public static final String SNAPSHOTINTERVAL = "snapshotInterval";//1-10秒 + public static final String LANGUAGE = "language"; + public static final String METHODNAME = "methodName";//userdefined + public static final String INTERVAL = "interval"; + public static final String STARTTIME = "startTime"; + public static final String ENDTIME = "endTime"; + public static final String DATA_KEY = "videoCaptionInfo"; + public static final String SUBCONTENT = "subContent"; + public static final String SUBTITLES = "subtitles"; + public static final String VIDEOCONTENTS = "videoContents"; + public static final String JOBID = "jobId"; + + + /** + * 任务id + */ + public static final String TASKID = "taskId"; +} diff --git a/asr-service/src/main/java/com/bw/asr/entity/VideoResult.java b/asr-service/src/main/java/com/bw/asr/entity/VideoResult.java new file mode 100644 index 0000000..0e4cbc7 --- /dev/null +++ b/asr-service/src/main/java/com/bw/asr/entity/VideoResult.java @@ -0,0 +1,52 @@ +package com.bw.asr.entity; + +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * 视频解析结果实体 - 根据阿里云实际数据结构更新 + */ +@Data +public class VideoResult { + // 基础信息 + private String taskId; + private String taskStatus; + private String errorMessage; + private Long createTime = System.currentTimeMillis(); + private List> subtitles; // 字幕列表 + private Integer captionCount; // 字幕数量 + private String headerInfo; // header信息 + + // 辅助字段 + private String videoUrl; // 视频URL + + // 格式化方法 + public String getFormattedCreateTime() { + if (createTime != null) { + return new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date(createTime)); + } + return "未知时间"; + } + + /** + * 获取第一条字幕(如果有) + */ + public Map getFirstSubtitle() { + if (subtitles != null && !subtitles.isEmpty()) { + return subtitles.get(0); + } + return null; + } + + /** + * 获取最后一条字幕(如果有) + */ + public Map getLastSubtitle() { + if (subtitles != null && !subtitles.isEmpty()) { + return subtitles.get(subtitles.size() - 1); + } + return null; + } +} \ No newline at end of file diff --git a/asr-service/src/main/java/com/bw/asr/handler/MainHandler.java b/asr-service/src/main/java/com/bw/asr/handler/MainHandler.java new file mode 100644 index 0000000..236bb12 --- /dev/null +++ b/asr-service/src/main/java/com/bw/asr/handler/MainHandler.java @@ -0,0 +1,206 @@ +package com.bw.asr.handler; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + + +import org.apache.commons.io.FileUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import com.alibaba.fastjson.JSONObject; +import com.bw.asr.cache.ConfigCache; +import com.bw.asr.service.AsrTaskService; +import com.bw.asr.utils.DateUtil; +import com.bw.asr.utils.FileUtil; + +import lombok.extern.slf4j.Slf4j; + + +/** + * @author jian.mao + * @date 2025年1月13日 + * @description + */ +@Component +@Order(value = 1) +@Slf4j +public class MainHandler implements ApplicationRunner { + + @Value("${task.task-queue-path}") + private String taskPath; + @Value("${task.result-task-queue-path}") + private String resultTaskPath; + @Autowired + private AsrTaskService asrTaskService; + /***线程池参数***/ + @Value("${threadPool.corePoolSize}") + private int corePoolSize; + @Value("${threadPool.maximumPoolSize}") + private int maximumPoolSize; + @Value("${threadPool.keepAliveTime}") + private long keepAliveTime; + @Value("${threadPool.queueSize}") + private int queueSize; + + /** + *执行入口 + */ + @Override + public void run(ApplicationArguments args) throws Exception { + //线程池方式 + ThreadPoolExecutor executor = new ThreadPoolExecutor( + corePoolSize, + maximumPoolSize, + keepAliveTime, + TimeUnit.SECONDS, + new LinkedBlockingQueue<>(queueSize), + new ThreadPoolExecutor.CallerRunsPolicy() + ); + //消费创建任务队列数据 + Thread consumerThread = new Thread(() -> { + while (true) { + try { + // 从队列中获取任务 + Map task = ConfigCache.taskQueue.take(); + // 提交给线程池执行 + executor.execute(() -> createTask(task)); + } catch (InterruptedException e) { + // 恢复中断状态 + Thread.currentThread().interrupt(); + log.error("任务消费线程被中断"); + break; + } + } + }); + consumerThread.start(); + log.info("创建任务消费线程启动-----"); + + + //消费结果任务队列数据 + Thread resultConsumerThread = new Thread(() -> { + while (true) { + try { + // 从队列中获取任务 + Map task = ConfigCache.resultQueue.take(); + // 提交给线程池执行 + executor.execute(() -> getResult(task)); + } catch (InterruptedException e) { + // 恢复中断状态 + Thread.currentThread().interrupt(); + log.error("任务消费线程被中断"); + break; + } + DateUtil.sleep(3000); + } + }); + resultConsumerThread.start(); + log.info("结果任务消费线程启动-----"); + //启动加载缓存任务 + readTask(taskPath, ConfigCache.taskQueue); + readTask(resultTaskPath, ConfigCache.resultQueue); + //停止处理 + waitDown(); + } + + /** + * 创建任务执行方法 + * @param task + */ + private void createTask(Map task) { + asrTaskService.create(task); + } + + private void getResult(Map task) { + asrTaskService.parse(task); + } + + + /****************************************************************load******************************************************************************/ + /** + * 加载文件中的任务 + * @param path 文件地址 + * @param queue 队列 + */ + @SuppressWarnings("unchecked") + public static void readTask(String path, LinkedBlockingDeque> queue) { + File file = new File(path); + if (file.exists()) { + List tasks = null; + try { + tasks = FileUtils.readLines(file, "UTF-8"); + } catch (IOException e) { + e.printStackTrace(); + } + for (String taskStr : tasks) { + Map task = JSONObject.parseObject(taskStr); + try { + queue.put(task); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + file.delete(); + } + } + + /*******************************************************************stop************************************************************************/ + + /** + * 结束触发钩子 + */ + public void waitDown() { + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + // 停止线程 + ConfigCache.isStart = false; + log.info("stop-------"); + writeTsskToFile(); + } + }); + } + + + /** + * 任务持久化到硬盘 + */ + public void writeTsskToFile() { + while (true) { + if (ConfigCache.taskQueue.size() > 0) { + try { + Map task = ConfigCache.taskQueue.take(); + FileUtil.writeFile(taskPath, JSONObject.toJSONString(task)); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } else { + log.info("taskQueue write is file end"); + break; + } + } + while (true) { + if (ConfigCache.resultQueue.size() > 0) { + try { + Map task = ConfigCache.resultQueue.take(); + FileUtil.writeFile(resultTaskPath, JSONObject.toJSONString(task)); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } else { + log.info("taskQueue write is file end"); + break; + } + } + } +} diff --git a/asr-service/src/main/java/com/bw/asr/service/AsrTaskService.java b/asr-service/src/main/java/com/bw/asr/service/AsrTaskService.java new file mode 100644 index 0000000..dbb88a4 --- /dev/null +++ b/asr-service/src/main/java/com/bw/asr/service/AsrTaskService.java @@ -0,0 +1,18 @@ +package com.bw.asr.service; + +import java.util.Map; + +public interface AsrTaskService { + /** + * ocr远端任务 + * @param task + */ + public void create(Map task); + + /** + * 解析结果 + * @param task + */ + public void parse(Map task); + +} diff --git a/asr-service/src/main/java/com/bw/asr/service/TaskReceiveService.java b/asr-service/src/main/java/com/bw/asr/service/TaskReceiveService.java new file mode 100644 index 0000000..0423b36 --- /dev/null +++ b/asr-service/src/main/java/com/bw/asr/service/TaskReceiveService.java @@ -0,0 +1,17 @@ +package com.bw.asr.service; + +/** + * 任务接收服务层 + * @author jian.mao + * @date 2025年1月14日 + * @description + */ +public interface TaskReceiveService { + + /** + * 任务新增 + * @param dataJson + * @return + */ + public String put(String dataJson); +} diff --git a/asr-service/src/main/java/com/bw/asr/service/impl/AsrTaskServiceImpl.java b/asr-service/src/main/java/com/bw/asr/service/impl/AsrTaskServiceImpl.java new file mode 100644 index 0000000..efa3374 --- /dev/null +++ b/asr-service/src/main/java/com/bw/asr/service/impl/AsrTaskServiceImpl.java @@ -0,0 +1,553 @@ +package com.bw.asr.service.impl; + +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import com.aliyun.auth.credentials.Credential; +import com.aliyun.auth.credentials.provider.StaticCredentialProvider; +import com.aliyun.core.http.HttpClient; +import com.aliyun.httpcomponent.httpclient.ApacheAsyncHttpClientBuilder; +import com.aliyun.sdk.gateway.pop.Configuration; +import com.aliyun.sdk.gateway.pop.auth.SignatureVersion; +import com.aliyun.sdk.service.quanmiaolightapp20240801.AsyncClient; +import com.aliyun.sdk.service.quanmiaolightapp20240801.models.*; +import darabonba.core.client.ClientOverrideConfiguration; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.stereotype.Service; + +import com.bw.asr.entity.Constants; +import com.bw.asr.entity.VideoResult; +import com.bw.asr.service.AsrTaskService; +import com.bw.asr.utils.DownLoadUtil; +import com.bw.asr.utils.FileUtil; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.bw.asr.entity.AppResultDoc; +import com.bw.asr.cache.ConfigCache; + +import lombok.extern.slf4j.Slf4j; + +import java.time.Duration; +import java.util.concurrent.CompletableFuture; + +/** + * 视频解析服务实现类 + */ +@Service +@Slf4j +@RefreshScope +public class AsrTaskServiceImpl implements AsrTaskService { + @Value("${file.path-prefix}") + private String downloadFilePathPrefix; + + @Value("${aliyun.access-key-id}") + private String accessKeyId; + + @Value("${aliyun.access-key-secret}") + private String accessKeySecret; + + @Value("${aliyun.workspace-id}") + private String workspaceId; + + @Value("${video.analysis.model-id}") + private String modelId; + + @Value("${video.analysis.video-model-id}") + private String videoModelId; + + @Value("${api.save-url}") + private String saveUrl; + + // 语言映射表(中文 -> 英文) + private static final Map LANGUAGE_MAPPING = new HashMap<>(); + + static { + LANGUAGE_MAPPING.put("中文", "chinese"); + LANGUAGE_MAPPING.put("法语", "french"); + LANGUAGE_MAPPING.put("英语", "english"); + LANGUAGE_MAPPING.put("日语", "japanese"); + LANGUAGE_MAPPING.put("中英文自由说", "chineseEnglishFreely"); + LANGUAGE_MAPPING.put("阿拉伯语", "arabic"); + LANGUAGE_MAPPING.put("韩语", "korean"); + LANGUAGE_MAPPING.put("马来语", "malay"); + LANGUAGE_MAPPING.put("泰语", "thai"); + LANGUAGE_MAPPING.put("葡萄牙语", "portuguese"); + LANGUAGE_MAPPING.put("西班牙语", "spanish"); + LANGUAGE_MAPPING.put("印尼语", "indonesian"); + LANGUAGE_MAPPING.put("越南语", "vietnamese"); + } + + /** + * 获取阿里云客户端 + */ + private AsyncClient getClient() { + try { + Credential credential = Credential.builder() + .accessKeyId(accessKeyId) + .accessKeySecret(accessKeySecret) + .build(); + + HttpClient httpClient = new ApacheAsyncHttpClientBuilder() + .connectionTimeout(Duration.ofSeconds(30)) + .responseTimeout(Duration.ofSeconds(60)) + .ignoreSSL(false) + .build(); + + return AsyncClient.builder() + .credentialsProvider(StaticCredentialProvider.create(credential)) + .serviceConfiguration(Configuration.create().setSignatureVersion(SignatureVersion.V3)) + .overrideConfiguration(ClientOverrideConfiguration.create() + .setProtocol("HTTPS") + .setEndpointOverride("quanmiaolightapp.cn-beijing.aliyuncs.com")) + .httpClient(httpClient) + .build(); + } catch (Exception e) { + log.error("初始化阿里云客户端失败", e); + return null; + } + } + /** + * 提交视频分析任务 + */ + @Override + public void create(Map task) { + try { + //源文件链接 + String videoUrl = task.get(Constants.VIDEOURL).toString(); + String url = videoUrl.replace("10.8.0.16", "182.92.120.176"); + String inputLanguage = task.get(Constants.LANGUAGE).toString(); + // 映射语言参数 + String language = mapLanguage(inputLanguage); + // 构建请求 + SubmitVideoAnalysisTaskRequest request = buildVideoAnalysisRequest(url,language); + + // 提交任务 + AsyncClient client = getClient(); + CompletableFuture responseFuture = + client.submitVideoAnalysisTask(request); + SubmitVideoAnalysisTaskResponse response = responseFuture.get(); + + if (response != null && response.getBody().getSuccess() && + response.getBody().getData() != null) { + String jobId = response.getBody().getData().getTaskId(); + log.info("视频解析任务提交成功,任务ID:{}", (String)task.get(Constants.TASKID)); + + task.put(Constants.JOBID, URLEncoder.encode(jobId.replace("\"", ""), "UTF-8")); + + //任务创建成功,放到监控结果队列中 + ConfigCache.resultQueue.put(task); + + } else { + throw new RuntimeException("视频解析任务提交失败"); + } + + } catch (Throwable e) { + log.error("提交视频解析任务异常", e); + //失败直接发送结果 + AppResultDoc entity = new AppResultDoc(); + entity.setTaskId((String)task.get(Constants.TASKID)); + entity.setAppId((Integer)task.get(Constants.ID)); + long now = System.currentTimeMillis(); + entity.setCreateTime(now); + Map result = new HashMap(16); + result.put(Constants.ERROR, "识别任务创建异常"); + entity.setResult(result); + entity.setStatus(2); + entity.setDel(0); + entity.setInput(task); + //回传给api服务保存 + DownLoadUtil.doPost(saveUrl, JSONObject.toJSONString(entity)); + } + } + + /** + * 构建视频理解请求 + */ + private SubmitVideoAnalysisTaskRequest buildVideoAnalysisRequest(String videoUrl,String language) { + return SubmitVideoAnalysisTaskRequest.builder() + .workspaceId(workspaceId) + .videoUrl(videoUrl) + .videoModelId(videoModelId) + .language(language) + .generateOptions(Arrays.asList("videoAnalysis", "videoGenerate")) + .videoModelCustomPromptTemplate("# 角色\n你是一名专业的视频字幕提取员\n\n# 任务\n提取视频中的所有对话和字幕内容\n\n# 输入\n{videoAsrText}\n\n# 输出格式\n时间戳:00:00:00 - 内容:这里是字幕内容") + .textProcessTasks(Collections.singletonList( + SubmitVideoAnalysisTaskRequest.TextProcessTasks.builder() + .modelId(modelId) + .modelCustomPromptTemplate("# 角色\n视频内容分析师\n\n# 输入\n{videoAnalysisText}\n{videoAsrText}\n\n# 任务\n提取视频字幕并标记时间戳\n\n# 输出格式\n=== 视频字幕时间轴 ===") + .build() + )) + .frameSampleMethod(SubmitVideoAnalysisTaskRequest.FrameSampleMethod.builder() + .methodName("standard") + .build()) + .build(); + } + + @Override + public void parse(Map task) { + ObjectMapper objectMapper = new ObjectMapper(); + // TODO Auto-generated method stub + try { + String jobId = (String) task.get(Constants.JOBID); + //获取视频解析结果 + VideoResult videoResult = getVideoAnalysisResult(jobId); + System.out.println("result ---------------" +videoResult); + log.info("获取解析结果-jobId:{},result:{}",jobId,videoResult); + if (videoResult != null) { + String status = videoResult.getTaskStatus(); + // 1. 检查headerInfo中是否有错误信息 + Object headerInfo = videoResult.getHeaderInfo(); + String errorMessage = ""; + if (headerInfo != null && headerInfo.toString().contains("errorCode")) { + log.error("阿里云返回错误信息: {}", headerInfo); + errorMessage = extractErrorMessageFromHeader(headerInfo.toString()); + } + if ("SUCCESSED".equals(status)) { +// String content = printSimpleCaptions(videoResult); +// String jsonString = objectMapper.writeValueAsString(videoResult.getSubtitles()); +// if(jsonString.isEmpty() || jsonString == null || "[]".equals(jsonString.trim())) { +// jsonString = "未解析到字幕信息"; +// } + + List> subtitles = videoResult.getSubtitles(); + // 检查字幕是否为空 + if (subtitles == null || subtitles.isEmpty()) { + AppResultDoc entity = new AppResultDoc(); + entity.setTaskId((String)task.get(Constants.TASKID)); + entity.setAppId((Integer)task.get(Constants.ID)); + long now = System.currentTimeMillis(); + entity.setCreateTime(now); + Map result = new HashMap(16); + result.put(Constants.ERROR, "未解析到字幕信息"); + entity.setResult(result); + entity.setStatus(2); + entity.setDel(0); + entity.setInput(task); + //回传给api服务保存 + DownLoadUtil.doPost(saveUrl, JSONObject.toJSONString(entity)); + } + + //成功 发送结果 + AppResultDoc entity = new AppResultDoc(); + entity.setTaskId((String)task.get(Constants.TASKID)); + entity.setAppId((Integer)task.get(Constants.ID)); + long now = System.currentTimeMillis(); + entity.setCreateTime(now); + Map result = new HashMap(16); + result.put(Constants.SUBCONTENT, subtitles);//videoResult.getSubtitles() + result.put(Constants.SUBTITLES, videoResult.getCaptionCount()); + entity.setResult(result); + entity.setStatus(1); + entity.setDel(0); + entity.setInput(task); + //回传给api服务保存 + DownLoadUtil.doPost(saveUrl, JSONObject.toJSONString(entity)); + }else if("FAILED".equals(status) || "CANCELED".equals(status)) { + System.out.println("视频解析失败: " + videoResult.getErrorMessage()); + //发送失败结果 + AppResultDoc entity = new AppResultDoc(); + entity.setTaskId((String)task.get(Constants.TASKID)); + entity.setAppId((Integer)task.get(Constants.ID)); + long now = System.currentTimeMillis(); + entity.setCreateTime(now); + Map result = new HashMap(16); + result.put(Constants.ERROR, "识别失败"); + entity.setResult(result); + entity.setStatus(2); + entity.setDel(0); + entity.setInput(task); + //回传给api服务保存 + DownLoadUtil.doPost(saveUrl, JSONObject.toJSONString(entity)); + }else if("PENDING".equals(status) && !errorMessage.isEmpty() && errorMessage !=null){ + log.error("任务处于PENDING状态但有错误信息,立即处理。taskId: {}, 错误: {}", (String)task.get(Constants.TASKID), errorMessage); + //发送失败结果 + AppResultDoc entity = new AppResultDoc(); + entity.setTaskId((String)task.get(Constants.TASKID)); + entity.setAppId((Integer)task.get(Constants.ID)); + long now = System.currentTimeMillis(); + entity.setCreateTime(now); + Map result = new HashMap(16); + result.put(Constants.ERROR, errorMessage); + entity.setResult(result); + entity.setStatus(2); + entity.setDel(0); + entity.setInput(task); + //回传给api服务保存 + DownLoadUtil.doPost(saveUrl, JSONObject.toJSONString(entity)); + }else { + //识别中 -- 放回队列 + ConfigCache.resultQueue.put(task); + } + } + } catch (Throwable e) { + // TODO: handle exception + log.error("创建文档解析任务异常。e:",e); + //发送失败结果 + AppResultDoc entity = new AppResultDoc(); + entity.setTaskId((String)task.get(Constants.TASKID)); + entity.setAppId((Integer)task.get(Constants.ID)); + long now = System.currentTimeMillis(); + entity.setCreateTime(now); + Map result = new HashMap(16); + result.put(Constants.ERROR, "源文件解析异常"); + entity.setResult(result); + entity.setStatus(2); + entity.setDel(0); + entity.setInput(task); + //回传给api服务保存 + DownLoadUtil.doPost(saveUrl, JSONObject.toJSONString(entity)); + } + } + + /** + * 获取视频分析结果 + */ + public VideoResult getVideoAnalysisResult(String taskId) { + try { + AsyncClient client = getClient(); + GetVideoAnalysisTaskRequest request = GetVideoAnalysisTaskRequest.builder() + .taskId(taskId) + .workspaceId(workspaceId) + .build(); + + CompletableFuture responseFuture = + client.getVideoAnalysisTask(request); + GetVideoAnalysisTaskResponse response = responseFuture.get(); + + if (response != null && response.getBody().getSuccess() && + response.getBody().getData() != null) { + return parseVideoAnalysisResult(response.getBody().getData(), taskId); + } + + } catch (Exception e) { + log.error("获取视频解析结果异常", e); + } + + return null; + } + + + + /** + * 解析视频分析结果 + */ + private VideoResult parseVideoAnalysisResult(GetVideoAnalysisTaskResponseBody.Data data, String taskId) { + VideoResult result = new VideoResult(); + result.setTaskId(taskId); + result.setTaskStatus(data.getTaskStatus()); + + try { + String jsonStr = JSON.toJSONString(data); + JSONObject json = JSON.parseObject(jsonStr); + + // 提取错误信息 + if (json.containsKey("errorMessage")) { + result.setErrorMessage(json.getString("errorMessage")); + } + + // 提取payload中的数据 + if (json.containsKey("payload")) { + JSONObject payload = json.getJSONObject("payload"); + if (payload.containsKey("output")) { + JSONObject output = payload.getJSONObject("output"); + extractCaptionsFromOutput(output, result); + } + } + + // 提取header信息 + if (json.containsKey("header")) { + JSONObject header = json.getJSONObject("header"); + result.setHeaderInfo(JSON.toJSONString(header)); + } + } catch (Exception e) { + log.error("解析视频分析结果异常", e); + } + + return result; + } + + /** + * 从output中提取字幕 + */ + private void extractCaptionsFromOutput(JSONObject output, VideoResult result) { + try { + // 提取视频字幕结果 + if (output.containsKey("videoCaptionResult")) { + JSONObject captionResult = output.getJSONObject("videoCaptionResult"); + if (captionResult.getBooleanValue("generateFinished") && + captionResult.containsKey("videoCaptions")) { + + JSONArray captions = captionResult.getJSONArray("videoCaptions"); + List> subtitleList = new ArrayList<>(); + + for (int i = 0; i < captions.size(); i++) { + JSONObject caption = captions.getJSONObject(i); + Map subtitle = new HashMap<>(); + +// subtitle.put("startTime", caption.getLong("startTime")); +// subtitle.put("endTime", caption.getLong("endTime")); + subtitle.put("startTimeFormat", caption.getString("startTimeFormat")); + subtitle.put("endTimeFormat", caption.getString("endTimeFormat")); + subtitle.put("text", caption.getString("text")); + +// if (caption.containsKey("speaker")) { +// subtitle.put("speaker", caption.getString("speaker")); +// } + + subtitleList.add(subtitle); + } + + result.setSubtitles(subtitleList); + result.setCaptionCount(subtitleList.size()); + } + } + + } catch (Exception e) { + log.error("提取字幕异常", e); + } + } + + /** + * 打印简化的字幕格式 + */ + private String printSimpleCaptions(VideoResult result) { + if (result.getSubtitles() != null && !result.getSubtitles().isEmpty()) { + StringBuilder captionsBuilder = new StringBuilder(); + + for (Map subtitle : result.getSubtitles()) { + String startTime = (String) subtitle.get("startTimeFormat"); + String endTime = (String) subtitle.get("endTimeFormat"); + String text = (String) subtitle.get("text"); + String content = "[" + startTime + " - " + endTime + "] "+ text; + + // 添加到构建器 + captionsBuilder.append(content).append("\n"); + // 同时输出到控制台(如果需要的话) + System.out.println(content); + } + + // 返回所有字幕内容 + return captionsBuilder.toString(); + } else { + System.out.println("未检测到字幕内容"); + return "未检测到字幕内容"; + } + } + /** + * 从headerInfo中提取错误信息 + */ + private String extractErrorMessageFromHeader(String headerInfo) { + try { + JSONObject json = JSON.parseObject(headerInfo); + + // 尝试提取errorMessage + if (json.containsKey("errorMessage")) { + String errorMsg = json.getString("errorMessage"); + + return errorMsg.length() > 200 ? + errorMsg.substring(0, 200) + "..." : errorMsg; + } + + if (json.containsKey("eventInfo")) { + return json.getString("eventInfo"); + } + + if (json.containsKey("errorCode")) { + return "错误代码: " + json.getString("errorCode"); + } + + } catch (Exception e) { + log.warn("解析headerInfo失败", e); + } + + // 如果解析失败,返回原始信息的前100个字符 + return headerInfo.length() > 100 ? + headerInfo.substring(0, 100) + "..." : headerInfo; + } + /** + * 映射语言参数(中文 -> 英文) + */ + private String mapLanguage(String inputLanguage) { + if (inputLanguage == null || inputLanguage.trim().isEmpty()) { + return "chinese"; // 默认中文 + } + + String trimmed = inputLanguage.trim().toLowerCase(); + + // 首先尝试精确匹配 + for (Map.Entry entry : LANGUAGE_MAPPING.entrySet()) { + if (trimmed.equals(entry.getKey().toLowerCase())) { + return entry.getValue(); + } + } + + // 尝试包含匹配(支持更灵活的输入) + for (Map.Entry entry : LANGUAGE_MAPPING.entrySet()) { + if (trimmed.contains(entry.getKey().toLowerCase())) { + log.debug("语言包含匹配: {} -> {}", trimmed, entry.getValue()); + return entry.getValue(); + } + } + // 默认返回中文 + log.warn("无法识别的语言输入: {}, 使用默认值: chinese", inputLanguage); + return "chinese"; + } + /** + * 测试方法 + */ +// public static void main(String[] args) { +// try { +// System.out.println("=== 视频字幕提取测试 ===\n"); +// +// // 创建服务实例 +// AsrTaskServiceImpl service = new AsrTaskServiceImpl(); +// +// // 设置配置 +// service.accessKeyId = "LTAI5tDbzNNXnSg9r6ncQi2x"; +// service.accessKeySecret = "f8aX6BM8ZiQbEfL1o4gcvX2PsziCw3"; +// service.workspaceId = "llm-7qk6vvzgxq7qhl8e"; +// service.modelId = "quanmiao-llm-plus"; +// service.videoModelId = "quanmiao-vl-plus"; +// service.language = "chinese"; +// +// // 测试视频URL +// String testVideoUrl = "https://vd9.bdstatic.com/mda-rmggrjqeweys54r8/mb/cae_h264/1765977811688977696/mda-rmggrjqeweys54r8.mp4"; +// +// // 创建任务 +// Map task = new HashMap<>(); +// task.put("videoUrl", testVideoUrl); +// +// System.out.println("提交视频分析任务..."); +// System.out.println("视频URL: " + testVideoUrl); +// +// // 提交任务 +// service.create(task); +// +// // 等待任务处理(实际使用中可以通过回调或轮询获取结果) +// System.out.println("任务已提交,正在处理中..."); +// +// // 为了测试,我们可以等待一段时间后手动获取结果 +// Thread.sleep(30000); // 等待30秒 +// +// String taskId = (String) task.get("taskId"); +// if (taskId != null) { +// System.out.println("\n任务ID: " + taskId); +// +// // 获取简化字幕 +// System.out.println("\n=== 提取到的字幕 ==="); +// String captions = service.getSimplifiedCaptions(taskId); +// System.out.println(captions); +// } +// +// } catch (Exception e) { +// System.err.println("测试失败: " + e.getMessage()); +// e.printStackTrace(); +// } +// } +} \ No newline at end of file diff --git a/asr-service/src/main/java/com/bw/asr/service/impl/TaskReceiveServiceImpl.java b/asr-service/src/main/java/com/bw/asr/service/impl/TaskReceiveServiceImpl.java new file mode 100644 index 0000000..68273a2 --- /dev/null +++ b/asr-service/src/main/java/com/bw/asr/service/impl/TaskReceiveServiceImpl.java @@ -0,0 +1,55 @@ +package com.bw.asr.service.impl; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.stereotype.Service; + +import com.alibaba.fastjson.JSONObject; +import com.bw.asr.cache.ConfigCache; +import com.bw.asr.entity.Constants; +import com.bw.asr.service.TaskReceiveService; + +import lombok.extern.slf4j.Slf4j; + +/** + * 任务接收服务层实现类 + * @author jian.mao + * @date 2025年1月14日 + * @description + */ +@Service +@Slf4j +public class TaskReceiveServiceImpl implements TaskReceiveService { + + @Override + public String put(String dataJson) { + Map response = new HashMap<>(16); + int code = 200; + String message = "success"; + Map task = null; + try { + task = JSONObject.parseObject(dataJson); + } catch (Exception e) { + log.error("参数结构不合法,", e); + code = 100010; + message = "参数不合法"; + } + // 写入队列 + try { + if(task.containsKey(Constants.TRACE) && (boolean)task.get(Constants.TRACE)){ + ConfigCache.taskQueue.putFirst(task); + }else{ + ConfigCache.taskQueue.put(task); + } + } catch (InterruptedException e) { + log.error("任务写入队列异常,", e); + code = 100011; + message = "任务写入队列失败"; + } + response.put(Constants.CODE, code); + response.put(Constants.MESSAGE, message); + return JSONObject.toJSONString(response); + } + +} diff --git a/asr-service/src/main/java/com/bw/asr/utils/DateUtil.java b/asr-service/src/main/java/com/bw/asr/utils/DateUtil.java new file mode 100644 index 0000000..10654e4 --- /dev/null +++ b/asr-service/src/main/java/com/bw/asr/utils/DateUtil.java @@ -0,0 +1,177 @@ +package com.bw.asr.utils; + + +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Date; + +import lombok.extern.slf4j.Slf4j; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + +/** + * 日期工具类 + * + * @author jian.mao + * @date 2022年11月15日 + * @description + */ +@Slf4j +public class DateUtil { + + /** + * @return + */ + public static String getTimeStrForNow() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHH"); + return sdf.format(new Date()); + } + + + public static String getTimeStrForDay(long time) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + + return sdf.format(new Date(time * 1000)); + } + + public static String getTimeStrForDay() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + + return sdf.format(new Date()); + } + + + public static String getDateTime() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String time = sdf.format(new Date()); + return time; + } + + public static String getDateTime(Long timestap) { + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String time = sdf.format(new Date(timestap)); + return time; + } + + public static String getDate(Long timestap) { + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + String time = sdf.format(new Date(timestap)); + return time; + } + + public static String getDateTimeForMonth() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM"); + String time = sdf.format(new Date()); + return time; + } + + /** + * 休眠 + * + * @param millis 毫秒 + */ + public static void sleep(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * 1. @Description:时间戳转时间 + * 2. @Author: ying.zhao + * 3. @Date: 2023/3/28 + */ + + public static String timestampToDate(String time) { + int thirteen = 13; + int ten = 10; + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); +// if (time.length() == thirteen) { + if (time.length() > ten) { + return sdf.format(new Date(Long.parseLong(time))); + } else { + return sdf.format(new Date(Integer.parseInt(time) * 1000L)); + } + } + + public static String parseCreated(String jsonTime){ + String formattedDateTime = getDateTime(); + try { + // 使用fastjson解析JSON数据 + JSONObject jsonObject = JSON.parseObject(jsonTime); + // 获取日期和时间的值 + JSONObject dateObject = jsonObject.getJSONObject("date"); + int day = dateObject.getIntValue("day"); + int month = dateObject.getIntValue("month"); + int year = dateObject.getIntValue("year"); + + JSONObject timeObject = jsonObject.getJSONObject("time"); + int hour = timeObject.getIntValue("hour"); + int minute = timeObject.getIntValue("minute"); + int second = timeObject.getIntValue("second"); + + // 创建LocalDateTime对象 + LocalDateTime dateTime = LocalDateTime.of(year, month, day, hour, minute, second); + + // 定义日期时间格式化器 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + // 格式化日期时间 + formattedDateTime = dateTime.format(formatter); + } catch (Exception e) { + log.info("日期转换失败:{}",e); + } + return formattedDateTime; + } + + /** + * 字符串转换日期 + * @param format + * @param date + * @return + */ + public static Date strToDate(String format,String date){ + SimpleDateFormat sdf = new SimpleDateFormat(format); + if (date == null || date.equals("")){ + return new Date(); + }else{ + Date ru = null; + try { + ru = sdf.parse(date); + } catch (ParseException e) { + e.printStackTrace(); + } + return ru; + } + } + /** + * 日期格式话 + * @param format 日期格式 + * @param dater 要转换的日期,默认当前时间 + * @return + */ + public static String FormatDate(String format,Date date){ + String fromatDate = null; + SimpleDateFormat sdf = new SimpleDateFormat(format); + if (date == null){ + fromatDate = sdf.format(new Date()); + }else{ + fromatDate = sdf.format(date); + } + return fromatDate; + } + public static void main(String[] args) { + String time = timestampToDate("955814400000"); + System.out.println(time); + } +} diff --git a/asr-service/src/main/java/com/bw/asr/utils/DownLoadUtil.java b/asr-service/src/main/java/com/bw/asr/utils/DownLoadUtil.java new file mode 100644 index 0000000..710222c --- /dev/null +++ b/asr-service/src/main/java/com/bw/asr/utils/DownLoadUtil.java @@ -0,0 +1,1045 @@ +package com.bw.asr.utils; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.StatusLine; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.AuthCache; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.HttpClient; +import org.apache.http.client.HttpRequestRetryHandler; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.config.SocketConfig; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.LayeredConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.auth.BasicScheme; +import org.apache.http.impl.client.BasicAuthCache; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.client.LaxRedirectStrategy; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.bw.asr.entity.Constants; + +import okhttp3.Call; +import okhttp3.Headers; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + + + + + + + + + +/** + * 下载工具类 + * @author jian.mao + * @date 2023年9月19日 + * @description + */ +public class DownLoadUtil { + + private static String ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36"; + private final static Logger log = LoggerFactory.getLogger(DownLoadUtil.class); + /** 代理服务器(产品官网 www.16yun.cn) **/ + final static String PROXYHOST = "u270.40.tp.16yun.cn"; + final static Integer PROXYPORT = 6448; + /** 代理验证信息 **/ + final static String PROXYUSER = "16HFBVJC"; + final static String PROXYPASS = "897944"; + + private static PoolingHttpClientConnectionManager cm = null; + private static HttpRequestRetryHandler httpRequestRetryHandler = null; + private static HttpHost proxy = null; + + private static CredentialsProvider credsProvider = null; + private static RequestConfig reqConfig = null; + + static { + ConnectionSocketFactory plainsf = PlainConnectionSocketFactory + .getSocketFactory(); + LayeredConnectionSocketFactory sslsf = SSLConnectionSocketFactory + .getSocketFactory(); + + Registry registry = RegistryBuilder.create().register("http", plainsf) + .register("https", sslsf).build(); + + cm = new PoolingHttpClientConnectionManager(registry); + cm.setMaxTotal(20); + cm.setDefaultMaxPerRoute(5); + + proxy = new HttpHost(PROXYHOST, PROXYPORT, "https"); + + credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials(AuthScope.ANY, + new UsernamePasswordCredentials(PROXYUSER, PROXYPASS)); + + reqConfig = RequestConfig.custom().setConnectionRequestTimeout(5000) + .setConnectTimeout(5000).setSocketTimeout(5000) + .setExpectContinueEnabled(false) + .setProxy(new HttpHost(PROXYHOST, PROXYPORT)).build(); + } + + /** + * 模拟客户端get请求 + * + * @param url + * 模拟请求得url + * @param headers + * 头部信息,没有可以不传 + * @return + */ + @SafeVarargs + public static String proxyDoGet(String url, Map... headers) { + // 设置超时时间 + int timeout = 30; + RequestConfig config = RequestConfig.custom() + .setConnectTimeout(timeout * 1000) + .setConnectionRequestTimeout(timeout * 1000) + .setSocketTimeout(timeout * 1000).build(); + SocketConfig socketConfig = SocketConfig.custom() + .setSoKeepAlive(false) + .setSoLinger(1) + .setSoReuseAddress(true) + .setSoTimeout(timeout * 1000) + .setTcpNoDelay(true).build(); + AuthCache authCache = new BasicAuthCache(); + authCache.put(proxy, new BasicScheme()); + HttpClientContext localContext = HttpClientContext.create(); + localContext.setAuthCache(authCache); + HttpClientBuilder httpBuilder = HttpClientBuilder.create(); + CloseableHttpClient httpClient = httpBuilder + .setDefaultSocketConfig(socketConfig) + .setDefaultRequestConfig(config) + .setDefaultCredentialsProvider(credsProvider).build(); + HttpGet httpGet = new HttpGet(url); + httpGet.setConfig(reqConfig); + if (headers != null && headers.length > 0) { + Map tempHeaders = headers[0]; + for (String key : tempHeaders.keySet()) { + httpGet.setHeader(key, tempHeaders.get(key).toString()); + } + } else { + httpGet.setHeader("Accept", + "application/json, text/javascript, */*; q=0.01"); + httpGet.setHeader("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8"); + } + CloseableHttpResponse response = null; + String html = ""; + int notFundCode = 404; + int successCode = 200; + try { + response = httpClient.execute(httpGet, localContext); + // 从响应模型中获取响应实体 + HttpEntity responseEntity = response.getEntity(); + StatusLine statusLine = response.getStatusLine(); + System.out.println("响应状态为:" + response.getStatusLine()); + if (statusLine.getStatusCode() == successCode) { + if (responseEntity != null) { + html = EntityUtils.toString(responseEntity, "utf-8"); + System.out.println("响应内容长度为:" + + responseEntity.getContentLength()); + // 下载结果为空不正常 + if (html.equals(Constants.EMPTY)) { + html = "Download failed error is:reslut is null"; + } + } + } else if (statusLine.getStatusCode() == notFundCode) { + html = "

页面404,正常结束请求即可

"; + } else { + throw new Exception("请求错误,code码为:" + statusLine.getStatusCode()); + } + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:reslut is null"; + }finally{ + try { + response.close(); + httpClient.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + return html; + + } + + + public static String httpsslProxyGet(String url, Map... headers) throws Exception { + //采用绕过验证的方式处理https请求 + SSLContext sslcontext = createIgnoreVerifySSL(); + + // 设置协议http和https对应的处理socket链接工厂的对象 + Registry socketFactoryRegistry = RegistryBuilder.create() + .register("http", PlainConnectionSocketFactory.INSTANCE) + .register("https", new SSLConnectionSocketFactory(sslcontext)) + .build(); + PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + connManager.setMaxTotal(50); + connManager.setDefaultMaxPerRoute(10); + HttpClients.custom().setConnectionManager(connManager); + // 设置超时时间 + int timeout = 30; + RequestConfig config = RequestConfig.custom() + .setConnectTimeout(timeout * 1000) + .setConnectionRequestTimeout(timeout * 1000) + .setSocketTimeout(timeout * 1000).build(); + SocketConfig socketConfig = SocketConfig.custom() + .setSoKeepAlive(false) + .setSoLinger(1) + .setSoReuseAddress(true) + .setSoTimeout(timeout * 1000) + .setTcpNoDelay(true).build(); + AuthCache authCache = new BasicAuthCache(); + authCache.put(proxy, new BasicScheme()); + HttpClientContext localContext = HttpClientContext.create(); + localContext.setAuthCache(authCache); + HttpClientBuilder httpBuilder = HttpClientBuilder.create(); + CloseableHttpClient httpClient = httpBuilder + .setConnectionManager(connManager) + .setDefaultSocketConfig(socketConfig) + .setDefaultRequestConfig(config) + .setDefaultCredentialsProvider(credsProvider).build(); + HttpGet httpGet = new HttpGet(url); + httpGet.setConfig(reqConfig); + if (headers != null && headers.length > 0) { + Map tempHeaders = headers[0]; + for (String key : tempHeaders.keySet()) { + httpGet.setHeader(key, tempHeaders.get(key).toString()); + } + } else { + httpGet.setHeader("Accept", + "application/json, text/javascript, */*; q=0.01"); + httpGet.setHeader("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8"); + } + CloseableHttpResponse response = null; + String html = ""; + int notFundCode = 404; + int successCode = 200; + try { + response = httpClient.execute(httpGet, localContext); + // 从响应模型中获取响应实体 + HttpEntity responseEntity = response.getEntity(); + StatusLine statusLine = response.getStatusLine(); + System.out.println("响应状态为:" + response.getStatusLine()); + if (statusLine.getStatusCode() == successCode) { + if (responseEntity != null) { + html = EntityUtils.toString(responseEntity, "utf-8"); + System.out.println("响应内容长度为:" + + responseEntity.getContentLength()); + // 下载结果为空不正常 + if (html.equals(Constants.EMPTY)) { + html = "Download failed error is:reslut is null"; + } + } + } else if (statusLine.getStatusCode() == notFundCode) { + html = "

页面404,正常结束请求即可

"; + } else { + throw new Exception("请求错误,code码为:" + statusLine.getStatusCode()); + } + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:reslut is null"; + }finally{ + try { + response.close(); + httpClient.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + return html; + + } + + + /** + * json参数方式POST提交 + * @param url + * @param params + * @return + */ + public static String doPost(String url, String params, Map... headers){ + String strResult = ""; + //设置超时时间 + int timeout = 60; + RequestConfig config = RequestConfig.custom(). + setConnectTimeout(timeout * 1000). + setConnectionRequestTimeout(timeout * 1000). + setSocketTimeout(timeout * 1000).build(); + SocketConfig socketConfig = SocketConfig.custom() + .setSoKeepAlive(false) + .setSoLinger(1) + .setSoReuseAddress(true) + .setSoTimeout(timeout * 1000) + .setTcpNoDelay(true).build(); +// AuthCache authCache = new BasicAuthCache(); +// authCache.put(proxy, new BasicScheme()); +// HttpClientContext localContext = HttpClientContext.create(); +// localContext.setAuthCache(authCache); + // 1. 获取默认的client实例 + HttpClientBuilder httpBuilder = HttpClientBuilder.create(); + httpBuilder.setUserAgent(ua); + HttpClient client = httpBuilder.setDefaultSocketConfig(socketConfig).setDefaultRequestConfig(config).build(); +// HttpClient client = httpBuilder.setDefaultSocketConfig(socketConfig).setDefaultRequestConfig(config).setConnectionManager(cm) +// .setDefaultCredentialsProvider(credsProvider).build(); + // 2. 创建httppost实例 + HttpPost httpPost = new HttpPost(url); +// httpPost.setConfig(reqConfig); + if (headers != null && headers.length > 0) { + Map tempHeaders = headers[0]; + for (String key : tempHeaders.keySet()) { + httpPost.setHeader(key, tempHeaders.get(key).toString()); + } + } else { + httpPost.addHeader("Content-Type", "application/json;charset=utf-8"); + } + HttpResponse resp = null; + try { + httpPost.setEntity(new StringEntity(params,"utf-8")); + resp = client.execute(httpPost); +// resp = client.execute(httpPost,localContext); + StatusLine statusLine = resp.getStatusLine(); + System.out.println("响应状态为:" + resp.getStatusLine()); + int notFundCode = 300; + int successCode = 200; + if(statusLine.getStatusCode() >= successCode && statusLine.getStatusCode() < notFundCode){ + // 7. 获取响应entity + HttpEntity respEntity = resp.getEntity(); + strResult = EntityUtils.toString(respEntity, "UTF-8"); + if(strResult.equals(Constants.EMPTY)){ + strResult = "Download failed error is:reslut is null"; + } + }else{ + throw new Exception("请求错误,code码为:"+statusLine.getStatusCode()); + } + } catch (Exception e) { + e.printStackTrace(); + strResult = "Download failed error is:"+ThrowMessageUtil.getErrmessage(e); + } + return strResult; + } + public static String httpPost(String url,String params) { + String html=""; + html = doPost(url,params); + int i = 1; + while(true){ + if(html.contains("Download failed error is:")){ + log.error("DownLoadUtil------------->download is failure,url is:"+url); + DateUtil.sleep(5000); + i++; + }else{ + break; + } + if(i > 5){ + break; + } + html = doPost(url,params); + } + return html; + } + /** + * 绕过验证 + * + * @return + * @throws NoSuchAlgorithmException + * @throws KeyManagementException + */ + public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException { + SSLContext sc = SSLContext.getInstance("SSLv3"); + + // 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法 + X509TrustManager trustManager = new X509TrustManager() { + @Override + public void checkClientTrusted( + java.security.cert.X509Certificate[] paramArrayOfX509Certificate, + String paramString) throws CertificateException { + } + + @Override + public void checkServerTrusted( + java.security.cert.X509Certificate[] paramArrayOfX509Certificate, + String paramString) throws CertificateException { + } + + @Override + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + }; + + sc.init(null, new TrustManager[] { trustManager }, null); + return sc; + } + /** + * 模拟请求 + * + * @param url 资源地址 + * @param map 参数列表 + * @param encoding 编码 + * @return + * @throws NoSuchAlgorithmException + * @throws KeyManagementException + * @throws IOException + * @throws ClientProtocolException + */ + public static String httpsslGet(String url,Map ... headers) { + String html=""; + CloseableHttpClient client = null; + HttpEntity responseEntity = null; + CloseableHttpResponse response = null; + try { + log.debug("DownLoadUtil------------->设置下载相关信息, start...."); + //采用绕过验证的方式处理https请求 + SSLContext sslcontext = createIgnoreVerifySSL(); + + // 设置协议http和https对应的处理socket链接工厂的对象 + Registry socketFactoryRegistry = RegistryBuilder.create() + .register("http", PlainConnectionSocketFactory.INSTANCE) + .register("https", new SSLConnectionSocketFactory(sslcontext)) + .build(); + PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + connManager.setMaxTotal(50); + connManager.setDefaultMaxPerRoute(10); + HttpClients.custom().setConnectionManager(connManager); + //设置超时时间 + int timeout = 30; + RequestConfig config = RequestConfig.custom(). + setConnectTimeout(timeout * 1000). + setConnectionRequestTimeout(timeout * 1000). + setSocketTimeout(timeout * 1000).build(); + SocketConfig socketConfig = SocketConfig.custom() + .setSoKeepAlive(false) + .setSoLinger(1) + .setSoReuseAddress(true) + .setSoTimeout(10000) + .setTcpNoDelay(true).build(); + // 设置重定向策略 + LaxRedirectStrategy redirectStrategy = new LaxRedirectStrategy(); + //创建自定义的httpclient对象 + client = HttpClients.custom().setConnectionManager(connManager).setDefaultRequestConfig(config).setRedirectStrategy(redirectStrategy).setDefaultSocketConfig(socketConfig).setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36").build(); +// CloseableHttpClient client = HttpClients.createDefault(); + + HttpGet httpGet = new HttpGet(url); + if(headers != null && headers.length > 0){ + Map tempHeaders = headers[0]; + for (String key : tempHeaders.keySet()) { + httpGet.setHeader(key,tempHeaders.get(key).toString()); + } + }else{ + httpGet.setHeader("Accept", "application/json, text/javascript, */*; q=0.01"); + httpGet.setHeader("Accept-Language","zh-CN,zh;q=0.9,en;q=0.8"); + httpGet.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36"); + } + log.debug("DownLoadUtil------------->设置下载相关信息, end...."); + try { + int notFundCode = 404; + int successCode = 200; + log.debug("DownLoadUtil------------->下载执行,start...."); + httpGet.setConfig(config); + response = client.execute(httpGet); + log.debug("DownLoadUtil------------->下载执行,end...."); + // 从响应模型中获取响应实体 + StatusLine statusLine = response.getStatusLine(); + log.debug("DownLoadUtil------------->响应状态为:" + response.getStatusLine()+",下载请求没问题url:"+url+",read is start ...."); + System.out.println("响应状态为:" + response.getStatusLine()); + responseEntity = response.getEntity(); + log.debug("DownLoadUtil------------->响应状态为:" + response.getStatusLine()+",下载请求没问题url:"+url+",read is end ...."); + if(statusLine.getStatusCode() == successCode){ + if (responseEntity != null) { + html=EntityUtils.toString(responseEntity,"utf-8"); + System.out.println("响应内容长度为:" + responseEntity.getContentLength()); + } + }else if(statusLine.getStatusCode() == notFundCode){ + html = "

页面404,正常结束请求即可

"; + }else{ + throw new Exception("请求错误,code码为:"+statusLine.getStatusCode()); + } + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:"+ThrowMessageUtil.getErrmessage(e); + + } + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:"+ThrowMessageUtil.getErrmessage(e); + }finally{ + try { + responseEntity.getContent().close(); + response.close(); + client.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + + return html; + } + + public static String httpSSLGet(String url,Map ... headers) { + String html=""; + html = httpsslGet(url,headers); + int i = 1; + while(true){ + if(html.contains("Download failed error is:")){ + log.error("DownLoadUtil------------->download is failure,url is:"+url); + DateUtil.sleep(30000); + i++; + }else{ + break; + } + if(i > 5){ + break; + } + html = httpsslGet(url,headers); + } + return html; + } + public static String doPostFrom(String url,Map param,Map ... headers){ + //设置超时时间 + int timeout = 15; + RequestConfig config = RequestConfig.custom(). + setConnectTimeout(timeout * 1000). + setConnectionRequestTimeout(timeout * 1000). + setSocketTimeout(timeout * 1000).build(); + SocketConfig socketConfig = SocketConfig.custom() + .setSoKeepAlive(false) + .setSoLinger(1) + .setSoReuseAddress(true) + .setSoTimeout(10000) + .setTcpNoDelay(true).build(); +// AuthCache authCache = new BasicAuthCache(); +// authCache.put(proxy, new BasicScheme()); +// HttpClientContext localContext = HttpClientContext.create(); +// localContext.setAuthCache(authCache); + HttpClientBuilder httpBuilder = HttpClientBuilder.create(); + httpBuilder.setUserAgent(ua); +// HttpClient httpClient = httpBuilder.setDefaultSocketConfig(socketConfig).setDefaultRequestConfig(config).setConnectionManager(cm) +// .setDefaultCredentialsProvider(credsProvider).build(); + HttpClient httpClient = httpBuilder.setDefaultSocketConfig(socketConfig).setDefaultRequestConfig(config).build(); + HttpPost httpPost = new HttpPost(url); +// httpPost.setConfig(reqConfig); + if(headers != null && headers.length > 0){ + Map tempHeaders = headers[0]; + for (String key : tempHeaders.keySet()) { + httpPost.setHeader(key,tempHeaders.get(key).toString()); + } + }else{ + httpPost.addHeader("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"); + httpPost.addHeader("accept-Language", "zh-CN,zh;q=0.9,en;q=0.8"); + httpPost.addHeader("content-type", "application/x-www-form-urlencoded"); + httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"); +// httpPost.addHeader("Referer", "http://www.neeq.com.cn/rule/Business_rules.html"); + } + // 创建请求参数 + List list = new LinkedList<>(); + for (String key : param.keySet()) { + BasicNameValuePair param1 = new BasicNameValuePair(key,param.get(key).toString()); + list.add(param1); + } + // 使用URL实体转换工具 + String html=""; + try { + UrlEncodedFormEntity entityParam = new UrlEncodedFormEntity(list, "UTF-8"); + httpPost.setEntity(entityParam); + HttpResponse response = httpClient.execute(httpPost); +// HttpResponse response = httpClient.execute(httpPost,localContext); + // 从响应模型中获取响应实体 + HttpEntity responseEntity = response.getEntity(); + StatusLine statusLine = response.getStatusLine(); + System.out.println("响应状态为:" + response.getStatusLine()); + int notFundCode = 404; + int successCode = 200; + if(statusLine.getStatusCode() == successCode){ + if (responseEntity != null) { + html=EntityUtils.toString(responseEntity,"utf-8"); + } + }else{ + throw new Exception("请求错误,code码为:"+statusLine.getStatusCode()); + } + + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:"+ThrowMessageUtil.getErrmessage(e); + } + + return html; + + } + public static String httpPostForm(String url,Map params,Map ... headers) { + String html=""; + html = doPostFrom(url,params); + int i = 1; + while(true){ + if(html.contains("Download failed error is:")){ + log.error("DownLoadUtil------------->download is failure,url is:"+url); + DateUtil.sleep(5000); + i++; + }else{ + break; + } + if(i > 5){ + break; + } + html = doPostFrom(url,params,headers); + } + return html; + } + + public static String dosslPost(String url,String params,Map ... headers) { + String html=""; + CloseableHttpClient client = null; + HttpEntity responseEntity = null; + CloseableHttpResponse response = null; + try { + //采用绕过验证的方式处理https请求 + SSLContext sslcontext = createIgnoreVerifySSL(); + // 设置协议http和https对应的处理socket链接工厂的对象 + Registry socketFactoryRegistry = RegistryBuilder.create() + .register("http", PlainConnectionSocketFactory.INSTANCE) + .register("https", new SSLConnectionSocketFactory(sslcontext)) + .build(); + PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + HttpClients.custom().setConnectionManager(connManager); + //设置超时时间 + int timeout = 5; + RequestConfig config = RequestConfig.custom(). + setConnectTimeout(timeout * 1000). + setConnectionRequestTimeout(timeout * 1000). + setSocketTimeout(timeout * 1000).build(); + SocketConfig socketConfig = SocketConfig.custom() + .setSoKeepAlive(false) + .setSoLinger(1) + .setSoReuseAddress(true) + .setSoTimeout(10000) + .setTcpNoDelay(true).build(); + //创建自定义的httpclient对象 + client = HttpClients.custom().setConnectionManager(connManager).setDefaultRequestConfig(config).setDefaultSocketConfig(socketConfig).build(); +// CloseableHttpClient client = HttpClients.createDefault(); + // 2. 创建httppost实例 + HttpPost httpPost = new HttpPost(url); +// httpPost.setConfig(reqConfig); + httpPost.addHeader("Content-Type", "application/json;charset=utf-8"); + if(headers != null && headers.length > 0){ + Map tempHeaders = headers[0]; + for (String key : tempHeaders.keySet()) { + httpPost.setHeader(key,tempHeaders.get(key).toString()); + } + }else{ + httpPost.setHeader("Accept", "application/json, text/javascript, */*; q=0.01"); + httpPost.setHeader("Accept-Language","zh-CN,zh;q=0.9,en;q=0.8"); + httpPost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36"); + } + + try { + httpPost.setEntity(new StringEntity(params,"utf-8")); + response = client.execute(httpPost); + int notFundCode = 404; + int successCode = 200; + // 从响应模型中获取响应实体 + StatusLine statusLine = response.getStatusLine(); + System.out.println("响应状态为:" + response.getStatusLine()); + responseEntity = response.getEntity(); + if(statusLine.getStatusCode() == successCode){ + if (responseEntity != null) { + html=EntityUtils.toString(responseEntity,"utf-8"); + System.out.println("响应内容长度为:" + responseEntity.getContentLength()); + } + }else if(statusLine.getStatusCode() == notFundCode){ + html = "

页面404,正常结束请求即可

"; + }else{ + throw new Exception("请求错误,code码为:"+statusLine.getStatusCode()); + } + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:"+ThrowMessageUtil.getErrmessage(e); + + } + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:"+ThrowMessageUtil.getErrmessage(e); + }finally{ + try { + responseEntity.getContent().close(); + response.close(); + client.close(); + } catch (UnsupportedOperationException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + + return html; + } + public static String dosslPostForm(String url,Map param,Map ... headers) { + String html=""; + try { + //采用绕过验证的方式处理https请求 + SSLContext sslcontext = createIgnoreVerifySSL(); + + // 设置协议http和https对应的处理socket链接工厂的对象 + Registry socketFactoryRegistry = RegistryBuilder.create() + .register("http", PlainConnectionSocketFactory.INSTANCE) + .register("https", new SSLConnectionSocketFactory(sslcontext)) + .build(); + PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + HttpClients.custom().setConnectionManager(connManager); + //设置超时时间 + int timeout = 5; + RequestConfig config = RequestConfig.custom(). + setConnectTimeout(timeout * 1000). + setConnectionRequestTimeout(timeout * 1000). + setSocketTimeout(timeout * 1000).build(); + SocketConfig socketConfig = SocketConfig.custom() + .setSoKeepAlive(false) + .setSoLinger(1) + .setSoReuseAddress(true) + .setSoTimeout(10000) + .setTcpNoDelay(true).build(); + //创建自定义的httpclient对象 + CloseableHttpClient client = HttpClients.custom().setConnectionManager(connManager).setDefaultRequestConfig(config).setDefaultSocketConfig(socketConfig).build(); +// CloseableHttpClient client = HttpClients.createDefault(); + // 2. 创建httppost实例 + HttpPost httpPost = new HttpPost(url); +// httpPost.setConfig(reqConfig); + if(headers != null && headers.length > 0){ + Map tempHeaders = headers[0]; + for (String key : tempHeaders.keySet()) { + httpPost.setHeader(key,tempHeaders.get(key).toString()); + } + }else{ + httpPost.setHeader("Accept", "application/json, text/javascript, */*; q=0.01"); + httpPost.setHeader("Accept-Language","zh-CN,zh;q=0.9,en;q=0.8"); + httpPost.addHeader("content-type", "application/x-www-form-urlencoded"); + httpPost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36"); + } + + // 创建请求参数 + List list = new LinkedList<>(); + for (String key : param.keySet()) { + BasicNameValuePair param1 = new BasicNameValuePair(key,param.get(key).toString()); + list.add(param1); + } + // 使用URL实体转换工具 + try { + UrlEncodedFormEntity entityParam = new UrlEncodedFormEntity(list, "UTF-8"); + httpPost.setEntity(entityParam); + HttpResponse response = client.execute(httpPost); +// HttpResponse response = httpClient.execute(httpPost,localContext); + // 从响应模型中获取响应实体 + int notFundCode = 404; + int successCode = 200; + HttpEntity responseEntity = response.getEntity(); + StatusLine statusLine = response.getStatusLine(); + System.out.println("响应状态为:" + response.getStatusLine()); + if(statusLine.getStatusCode() == successCode){ + if (responseEntity != null) { + html=EntityUtils.toString(responseEntity,"utf-8"); + } + }else{ + throw new Exception("请求错误,code码为:"+statusLine.getStatusCode()); + } + + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:"+ThrowMessageUtil.getErrmessage(e); + } + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:"+ThrowMessageUtil.getErrmessage(e); + } + + + return html; + } + public static String httpSSLPostForm(String url,Map params,Map ...headers) { + String html=""; + try { + html = dosslPostForm(url,params,headers); + } catch (Exception e) { + e.printStackTrace(); + // TODO: handle exception + html = "Download failed error is:Exception!"; + } + int i = 1; + while(true){ + if(html.contains("Download failed error is:")){ + log.error("DownLoadUtil------------->download is failure,url is:"+url); + DateUtil.sleep(30000); + i++; + }else{ + break; + } + if(i > 5){ + break; + } + try { + html = dosslPostForm(url,params,headers); + } catch (Exception e) { + e.printStackTrace(); + // TODO: handle exception + html = "Download failed error is:Exception!"; + } + } + return html; + } + public static String httpSSLPost(String url,String params,Map ...headers) { + String html=""; + try { + html = dosslPost(url,params,headers); + } catch (Throwable e) { + e.printStackTrace(); + // TODO: handle exception + html = "Download failed error is:Exception!"; + } + int i = 1; + while(true){ + if(html.contains("Download failed error is:")){ + log.error("DownLoadUtil------------->download is failure,url is:"+url); + DateUtil.sleep(30000); + i++; + }else{ + break; + } + if(i > 5){ + break; + } + try { + html = dosslPost(url,params,headers); + } catch (Throwable e) { + e.printStackTrace(); + // TODO: handle exception + html = "Download failed error is:Exception!"; + } + } + return html; + } + + /** + * 模拟客户端get请求 + * @param url 模拟请求得url + * @param headers 头部信息,没有可以不传 + * @return + */ + public static String doGet(String url,Map ... headers){ + //设置超时时间 + int timeout = 15; + RequestConfig config = RequestConfig.custom(). + setConnectTimeout(timeout * 1000). + setConnectionRequestTimeout(timeout * 1000). + setSocketTimeout(timeout * 1000).build(); + SocketConfig socketConfig = SocketConfig.custom() + .setSoKeepAlive(false) + .setSoLinger(1) + .setSoReuseAddress(true) + .setSoTimeout(10000) + .setTcpNoDelay(true).build(); + HttpClientBuilder httpBuilder = HttpClientBuilder.create(); + httpBuilder.setUserAgent(ua); + HttpClient httpClient = httpBuilder.setDefaultSocketConfig(socketConfig).setDefaultRequestConfig(config).build(); + HttpGet httpGet = new HttpGet(url); + if(headers != null && headers.length > 0){ + Map tempHeaders = headers[0]; + for (String key : tempHeaders.keySet()) { + httpGet.setHeader(key,tempHeaders.get(key).toString()); + } + }else{ + httpGet.setHeader("Accept", "application/json, text/javascript, */*; q=0.01"); + httpGet.setHeader("Accept-Language","zh-CN,zh;q=0.9,en;q=0.8"); + } + String html=""; + try { + HttpResponse response = httpClient.execute(httpGet); + // 从响应模型中获取响应实体 + HttpEntity responseEntity = response.getEntity(); + StatusLine statusLine = response.getStatusLine(); + System.out.println("响应状态为:" + response.getStatusLine()); + int notFundCode = 404; + int successCode = 200; + int successCodeMax = 300; + if(statusLine.getStatusCode() >= successCode && statusLine.getStatusCode() < successCodeMax){ + if (responseEntity != null) { + html=EntityUtils.toString(responseEntity,"utf-8"); + if(html.equals("")){ + html = "Download failed error is:reslut is null"; + } + } + }else if(statusLine.getStatusCode() == notFundCode){ + html = "

页面404,正常结束请求即可

"; + }else{ + throw new Exception("请求错误,code码为:"+statusLine.getStatusCode()); + } + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:"+ThrowMessageUtil.getErrmessage(e); + } + return html; + + } + + /** + * 文件下载 + * @param fileURL 文件链接 + * @param destinationFilePath 文件存储地址 + * @throws IOException + */ + public static void downloadFile(String fileURL, String destinationFilePath) throws IOException { + // 设置连接超时和读取超时 + RequestConfig config = RequestConfig.custom() + // 设置连接超时为10秒 + .setConnectTimeout(10000) + // 设置读取超时为30秒 + .setSocketTimeout(30000) + .build(); + + // 创建 HttpClient 实例 + try (CloseableHttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(config) + .build()) { + + // 创建 HttpGet 请求 + HttpGet request = new HttpGet(URI.create(fileURL)); + + // 执行请求 + try (CloseableHttpResponse response = httpClient.execute(request)) { + // 获取响应的输入流 + InputStream inputStream = response.getEntity().getContent(); + try (FileOutputStream outputStream = new FileOutputStream(destinationFilePath)) { + byte[] buffer = new byte[4096]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + } + log.info("文件下载成功---{}" , destinationFilePath); + } + } + } + + /** + * 文件上传 + * @param filePath + * @param gofastUrl + * @return + */ +// public static String upLoadFile(String filePath,String gofastUrl) { +// File file = new File(filePath); +// String realFilename = filePath.substring(filePath.lastIndexOf(File.separator) + 1); +// MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM); +// builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"file\";filename=\"" + realFilename + "\""), +// RequestBody.create(MediaType.parse("image/png"), file) +// +// ).addFormDataPart("output", "json").build(); +// RequestBody body = builder.build(); +// Request request = new Request.Builder().url(gofastUrl).post(body).header("Expect", "100-continue").build(); +// OkHttpClient.Builder okBuilder = new OkHttpClient.Builder(); +// OkHttpClient client = okBuilder.connectTimeout(600, TimeUnit.MILLISECONDS) +// .readTimeout(600, TimeUnit.SECONDS).build(); +// Call call = client.newCall(request); +// String html = ""; +// Response response = null; +// try { +// response = call.execute(); +// html = response.body().string(); +// } catch (IOException e) { +// log.info("upload fail:{}", filePath); +// e.printStackTrace(); +// } finally { +// response.close(); +// } +// return html; +// } + + /** + * 文件上传 + */ + public static String uploadFile(String filePath, String url, Map params) { + OkHttpClient client = new OkHttpClient.Builder() + .connectTimeout(60, TimeUnit.SECONDS) + .readTimeout(60, TimeUnit.SECONDS) + .build(); + + try { + File file = new File(filePath); + MultipartBody.Builder builder = new MultipartBody.Builder() + .setType(MultipartBody.FORM); + + // 添加参数 + for (Map.Entry entry : params.entrySet()) { + builder.addFormDataPart(entry.getKey(), entry.getValue()); + } + + // 添加文件 + builder.addFormDataPart("file", file.getName(), + RequestBody.create(MediaType.parse("application/octet-stream"), file)); + + RequestBody requestBody = builder.build(); + Request request = new Request.Builder() + .url(url) + .post(requestBody) + .build(); + + Response response = client.newCall(request).execute(); + return response.body().string(); + + } catch (Exception e) { + log.error("文件上传异常", e); + return "{\"code\":500,\"message\":\"上传失败\"}"; + } + } + public static void main(String[] args) throws Exception { + + } + + +} diff --git a/asr-service/src/main/java/com/bw/asr/utils/FileUtil.java b/asr-service/src/main/java/com/bw/asr/utils/FileUtil.java new file mode 100644 index 0000000..c51929b --- /dev/null +++ b/asr-service/src/main/java/com/bw/asr/utils/FileUtil.java @@ -0,0 +1,41 @@ +package com.bw.asr.utils; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +/** + * 文件工具类 + * @author jian.mao + * @date 2023年7月14日 + * @description + */ +public class FileUtil { + + /** + * 数据写入文件 + * @param Path 文件路径 + * @param result 数据 + * @throws IOException + */ + public static void writeFile(String path,String result){ + try { + FileWriter fw = new FileWriter(path,true); + fw.write(result+"\n"); + fw.flush(); + fw.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void delFile(String path) { + try { + File file = new File(path); + file.delete(); + } catch (Exception e) { + // TODO: handle exception + e.printStackTrace(); + } + } +} diff --git a/asr-service/src/main/java/com/bw/asr/utils/SpringBootKafka.java b/asr-service/src/main/java/com/bw/asr/utils/SpringBootKafka.java new file mode 100644 index 0000000..eab5a8f --- /dev/null +++ b/asr-service/src/main/java/com/bw/asr/utils/SpringBootKafka.java @@ -0,0 +1,45 @@ +package com.bw.asr.utils; + +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.support.SendResult; +import org.springframework.stereotype.Component; +import org.springframework.util.concurrent.ListenableFuture; +import org.springframework.util.concurrent.ListenableFutureCallback; + +/** + * @PROJECT_NAME: companybusinesscrawl + * @DESCRIPTION:SpringBootKafka 工具类 + * @DATE: 2023/4/6 11:09 + */ +@Slf4j +@Component +public class SpringBootKafka { + @Autowired + private KafkaTemplate kafkaTemplate; + /** + * 自定义topicKafkaTemplate + */ + /** + * public static final String TOPIC = "companyBussTest"; + **/ + public void send(String topic, String message) { + //发送消息 + ListenableFuture> future = kafkaTemplate.send(topic, message); + future.addCallback(new ListenableFutureCallback>() { + @Override + public void onFailure(Throwable throwable) { + //发送失败的处理 + log.info(topic + " - 生产者 发送消息失败:" + throwable.getMessage()); + } + + @Override + public void onSuccess(SendResult stringObjectSendResult) { + //成功的处理 + log.info(topic + " - 生产者 发送消息成功" ); + } + }); + } +} diff --git a/asr-service/src/main/java/com/bw/asr/utils/ThrowMessageUtil.java b/asr-service/src/main/java/com/bw/asr/utils/ThrowMessageUtil.java new file mode 100644 index 0000000..b7a137f --- /dev/null +++ b/asr-service/src/main/java/com/bw/asr/utils/ThrowMessageUtil.java @@ -0,0 +1,23 @@ +package com.bw.asr.utils; + +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * @author jian.mao + * @date 2023年3月22日 + * @description + */ +public class ThrowMessageUtil { + + /** + * 获取异常信息 + * @param t + * @return + */ + public static String getErrmessage(Throwable t){ + StringWriter stringWriter=new StringWriter(); + t.printStackTrace(new PrintWriter(stringWriter,true)); + return stringWriter.getBuffer().toString(); + } +} diff --git a/asr-service/src/main/resources/bootstrap.yml b/asr-service/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..4aaf300 --- /dev/null +++ b/asr-service/src/main/resources/bootstrap.yml @@ -0,0 +1,52 @@ +# ==================== 必须文件:bootstrap.yml ==================== +# 这个文件用于配置Nacos客户端,优先级最高 +spring: + application: + name: asr-service # 服务名,对应Nacos中的Data ID + + cloud: + nacos: + # ======== 配置中心 ======== + config: + server-addr: 127.0.0.1:8848 # Nacos地址 + username: nacos # 用户名 + password: nacos # 密码 + group: public_dev # 分组 + namespace: opai # 命名空间(默认public) + file-extension: yaml # 配置文件格式 + timeout: 5000 # 超时时间(ms) + + # 核心配置:开启动态刷新 + refresh-enabled: true # 必须为true! + + # 主配置文件(从Nacos加载) + data-id: ${spring.application.name}.${spring.cloud.nacos.config.file-extension} + + # 共享配置文件(可选) + shared-configs[0]: + data-id: application.yaml # 公共配置 + group: public_dev # 公共分组 + namespace: opai + refresh: true # 公共配置也要刷新 + + # 扩展配置(可选) + # extension-configs[0]: + # data-id: datasource.yaml + # group: dev + # refresh: true + + # ======== 服务发现 ======== + discovery: + server-addr: ${spring.cloud.nacos.config.server-addr} + username: ${spring.cloud.nacos.config.username} + password: ${spring.cloud.nacos.config.password} + group: ${spring.cloud.nacos.config.group} + namespace: ${spring.cloud.nacos.config.namespace} + +logging: + level: + root: info + com.alibaba.nacos.client.config.impl: WARN + file: + path: ../logs + \ No newline at end of file diff --git a/asr-service/src/main/resources/logback-spring.xml b/asr-service/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..729b92c --- /dev/null +++ b/asr-service/src/main/resources/logback-spring.xml @@ -0,0 +1,36 @@ + + + + + + + + + true + + ${logging.level} + + + ${log-path}/asr-service.log + + + ${log-path}/asr-service.log.%d{yyyy-MM-dd} + 7 + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %line %-5level %logger{50} - %msg%n + UTF-8 + + + + + + + + diff --git a/asr-service/src/test/java/com/bw/AppTest.java b/asr-service/src/test/java/com/bw/AppTest.java deleted file mode 100644 index fc367fc..0000000 --- a/asr-service/src/test/java/com/bw/AppTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.bw; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -/** - * Unit test for simple App. - */ -public class AppTest - extends TestCase -{ - /** - * Create the test case - * - * @param testName name of the test case - */ - public AppTest( String testName ) - { - super( testName ); - } - - /** - * @return the suite of tests being tested - */ - public static Test suite() - { - return new TestSuite( AppTest.class ); - } - - /** - * Rigourous Test :-) - */ - public void testApp() - { - assertTrue( true ); - } -} diff --git a/funasr-service/.classpath b/funasr-service/.classpath new file mode 100644 index 0000000..f7e4a1d --- /dev/null +++ b/funasr-service/.classpath @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/funasr-service/.gitignore b/funasr-service/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/funasr-service/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/funasr-service/.project b/funasr-service/.project new file mode 100644 index 0000000..352c18b --- /dev/null +++ b/funasr-service/.project @@ -0,0 +1,23 @@ + + + funasr-service + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/funasr-service/.settings/org.eclipse.core.resources.prefs b/funasr-service/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..abdea9a --- /dev/null +++ b/funasr-service/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding/=UTF-8 diff --git a/funasr-service/.settings/org.eclipse.jdt.core.prefs b/funasr-service/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..71df522 --- /dev/null +++ b/funasr-service/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,9 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.methodParameters=generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/funasr-service/.settings/org.eclipse.m2e.core.prefs b/funasr-service/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/funasr-service/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/funasr-service/pom.xml b/funasr-service/pom.xml new file mode 100644 index 0000000..1efcc42 --- /dev/null +++ b/funasr-service/pom.xml @@ -0,0 +1,213 @@ + + + 4.0.0 + + com.bw + opai-service-center + 0.0.1-SNAPSHOT + + com.bw + funasr-service + 0.0.1-SNAPSHOT + funasr-service + http://maven.apache.org + + UTF-8 + + + + junit + junit + 3.8.1 + test + + + org.springframework.boot + spring-boot-starter-web + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + org.springframework.boot + spring-boot-starter-actuator + + + org.projectlombok + lombok + + + com.alibaba + fastjson + 2.0.17 + + + org.apache.httpcomponents + httpclient + 4.5.3 + + + org.apache.httpcomponents + httpmime + 4.5.13 + + + commons-lang + commons-lang + 2.6 + + + + com.squareup.okhttp3 + okhttp + 3.14.9 + + + org.springframework.kafka + spring-kafka + + + + org.apache.poi + poi + 4.1.2 + + + org.apache.poi + poi-ooxml + 4.1.2 + + + + + com.alibaba.fastjson2 + fastjson2 + 2.0.21 + + + + com.aliyun + alibabacloud-quanmiaolightapp20240801 + 2.0.33 + + + com.aliyun + alibabacloud-aimiaobi20230801 + 1.0.89 + + + org.projectlombok + lombok + 1.18.30 + + + com.alibaba + dashscope-sdk-java + 2.14.3 + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + org.springframework.boot + spring-boot-maven-plugin + + com.bw.funasr.Application + ZIP + + + ${project.groupId} + ${project.artifactId} + + + + + + + repackage + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.1.1 + + + copy + package + + copy-dependencies + + + jar + jar + runtime + ${project.build.directory}/libs + + + + + + + + + diff --git a/funasr-service/src/main/java/com/bw/funasr/Application.java b/funasr-service/src/main/java/com/bw/funasr/Application.java new file mode 100644 index 0000000..e972ad9 --- /dev/null +++ b/funasr-service/src/main/java/com/bw/funasr/Application.java @@ -0,0 +1,19 @@ +package com.bw.funasr; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + + +/** + * 系统接口启动类 + * @author jian.mao + * @date 2025年12月30日 + * @description + */ +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/funasr-service/src/main/java/com/bw/funasr/cache/ConfigCache.java b/funasr-service/src/main/java/com/bw/funasr/cache/ConfigCache.java new file mode 100644 index 0000000..0cea733 --- /dev/null +++ b/funasr-service/src/main/java/com/bw/funasr/cache/ConfigCache.java @@ -0,0 +1,37 @@ +package com.bw.funasr.cache; + +import lombok.extern.slf4j.Slf4j; + +import java.util.Map; +import java.util.concurrent.LinkedBlockingDeque; + +/** + * @author jian.mao + * @date 2022年11月11日 + * @description 静态变量类 + */ +@Slf4j +public class ConfigCache { + + /**启动条件**/ + public static boolean isStart = true; + /*****任务队列*****/ + public static LinkedBlockingDeque> taskQueue = new LinkedBlockingDeque>(); + /****结果队列****/ + public static LinkedBlockingDeque> resultQueue = new LinkedBlockingDeque>(); + + + /** + * 队列录入任务 + * @param queue + * @param task + */ + public static void putQueue(LinkedBlockingDeque> queue,Map task){ + //next app 写入队列准备调出 + try { + queue.put(task); + } catch (InterruptedException e) { + log.error("队列写入data失败---"); + } + } +} diff --git a/funasr-service/src/main/java/com/bw/funasr/controller/TaskReceiveController.java b/funasr-service/src/main/java/com/bw/funasr/controller/TaskReceiveController.java new file mode 100644 index 0000000..6a07813 --- /dev/null +++ b/funasr-service/src/main/java/com/bw/funasr/controller/TaskReceiveController.java @@ -0,0 +1,39 @@ +package com.bw.funasr.controller; + +import javax.annotation.Resource; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.bw.funasr.service.TaskReceiveService; + +import lombok.extern.slf4j.Slf4j; + +/** + * 任务接收控制层 + * @author jian.mao + * @date 2025年1月14日 + * @description + */ +@Controller +@RequestMapping("/task") +@Slf4j +public class TaskReceiveController { + @Resource + private TaskReceiveService taskReceiveService; + @PostMapping("/put") + @ResponseBody + public String put(@RequestBody String param){ + String response = taskReceiveService.put(param); + return response; + } + @RequestMapping(value = "/hello", method = RequestMethod.GET) + @ResponseBody + public String hello(String param, String token) { + return "123"; + } +} diff --git a/funasr-service/src/main/java/com/bw/funasr/entity/AppResultDoc.java b/funasr-service/src/main/java/com/bw/funasr/entity/AppResultDoc.java new file mode 100644 index 0000000..75d01db --- /dev/null +++ b/funasr-service/src/main/java/com/bw/funasr/entity/AppResultDoc.java @@ -0,0 +1,42 @@ +package com.bw.funasr.entity; + + +import java.io.Serializable; +import java.util.Map; + + +import lombok.Data; + +/** + * ES 索引:opai_app_result + * 应用执行结果文档 + * + * @author jian.mao + */ +@Data +public class AppResultDoc implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 任务ID */ + private String taskId; + + /** 应用id */ + private Integer appId; + + /** 状态 0 进行中,1成功,2失败 */ + private Integer status; + + /** 创建时间(毫秒时间戳) */ + private Long createTime; + + /** 执行结果(可索引) */ + private Map result; + + /** 逻辑删除标识:0-未删除 1-已删除 */ + private Integer del; + + /***前端输入参数 ***/ + private Map input; + +} diff --git a/funasr-service/src/main/java/com/bw/funasr/entity/Constants.java b/funasr-service/src/main/java/com/bw/funasr/entity/Constants.java new file mode 100644 index 0000000..3db9271 --- /dev/null +++ b/funasr-service/src/main/java/com/bw/funasr/entity/Constants.java @@ -0,0 +1,34 @@ +package com.bw.funasr.entity; + + +/** + * 常量实体类 + * @author jian.mao + * @date 2022年11月15日 + * @description + */ + +public class Constants { + + /** + * 空字符串常量 + */ + public static final String EMPTY = ""; + + /************************应用参数*************************************/ + public static final String CODE = "code"; + public static final String ID = "id"; + public static final String MESSAGE = "message"; + /******************************api使用*******************************/ + public static final String ERROR = "error"; + public static final String VIDEOURL = "videoUrl"; + public static final String VOICECONTENT = "voiceContent"; + public static final String TRACE = "trace"; + public static final String JOBID = "jobId"; + + + /** + * 任务id + */ + public static final String TASKID = "taskId"; +} diff --git a/funasr-service/src/main/java/com/bw/funasr/handler/MainHandler.java b/funasr-service/src/main/java/com/bw/funasr/handler/MainHandler.java new file mode 100644 index 0000000..063b615 --- /dev/null +++ b/funasr-service/src/main/java/com/bw/funasr/handler/MainHandler.java @@ -0,0 +1,206 @@ +package com.bw.funasr.handler; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + + +import org.apache.commons.io.FileUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import com.alibaba.fastjson.JSONObject; +import com.bw.funasr.cache.ConfigCache; +import com.bw.funasr.service.FunasrTaskService; +import com.bw.funasr.utils.DateUtil; +import com.bw.funasr.utils.FileUtil; + +import lombok.extern.slf4j.Slf4j; + + +/** + * @author jian.mao + * @date 2025年1月13日 + * @description + */ +@Component +@Order(value = 1) +@Slf4j +public class MainHandler implements ApplicationRunner { + + @Value("${task.task-queue-path}") + private String taskPath; + @Value("${task.result-task-queue-path}") + private String resultTaskPath; + @Autowired + private FunasrTaskService funasrTaskService; + /***线程池参数***/ + @Value("${threadPool.corePoolSize}") + private int corePoolSize; + @Value("${threadPool.maximumPoolSize}") + private int maximumPoolSize; + @Value("${threadPool.keepAliveTime}") + private long keepAliveTime; + @Value("${threadPool.queueSize}") + private int queueSize; + + /** + *执行入口 + */ + @Override + public void run(ApplicationArguments args) throws Exception { + //线程池方式 + ThreadPoolExecutor executor = new ThreadPoolExecutor( + corePoolSize, + maximumPoolSize, + keepAliveTime, + TimeUnit.SECONDS, + new LinkedBlockingQueue<>(queueSize), + new ThreadPoolExecutor.CallerRunsPolicy() + ); + //消费创建任务队列数据 + Thread consumerThread = new Thread(() -> { + while (true) { + try { + // 从队列中获取任务 + Map task = ConfigCache.taskQueue.take(); + // 提交给线程池执行 + executor.execute(() -> createTask(task)); + } catch (InterruptedException e) { + // 恢复中断状态 + Thread.currentThread().interrupt(); + log.error("任务消费线程被中断"); + break; + } + } + }); + consumerThread.start(); + log.info("创建任务消费线程启动-----"); + + + //消费结果任务队列数据 + Thread resultConsumerThread = new Thread(() -> { + while (true) { + try { + // 从队列中获取任务 + Map task = ConfigCache.resultQueue.take(); + // 提交给线程池执行 + executor.execute(() -> getResult(task)); + } catch (InterruptedException e) { + // 恢复中断状态 + Thread.currentThread().interrupt(); + log.error("任务消费线程被中断"); + break; + } + DateUtil.sleep(3000); + } + }); + resultConsumerThread.start(); + log.info("结果任务消费线程启动-----"); + //启动加载缓存任务 + readTask(taskPath, ConfigCache.taskQueue); + readTask(resultTaskPath, ConfigCache.resultQueue); + //停止处理 + waitDown(); + } + + /** + * 创建任务执行方法 + * @param task + */ + private void createTask(Map task) { + funasrTaskService.create(task); + } + + private void getResult(Map task) { + funasrTaskService.parse(task); + } + + + /****************************************************************load******************************************************************************/ + /** + * 加载文件中的任务 + * @param path 文件地址 + * @param queue 队列 + */ + @SuppressWarnings("unchecked") + public static void readTask(String path, LinkedBlockingDeque> queue) { + File file = new File(path); + if (file.exists()) { + List tasks = null; + try { + tasks = FileUtils.readLines(file, "UTF-8"); + } catch (IOException e) { + e.printStackTrace(); + } + for (String taskStr : tasks) { + Map task = JSONObject.parseObject(taskStr); + try { + queue.put(task); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + file.delete(); + } + } + + /*******************************************************************stop************************************************************************/ + + /** + * 结束触发钩子 + */ + public void waitDown() { + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + // 停止线程 + ConfigCache.isStart = false; + log.info("stop-------"); + writeTsskToFile(); + } + }); + } + + + /** + * 任务持久化到硬盘 + */ + public void writeTsskToFile() { + while (true) { + if (ConfigCache.taskQueue.size() > 0) { + try { + Map task = ConfigCache.taskQueue.take(); + FileUtil.writeFile(taskPath, JSONObject.toJSONString(task)); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } else { + log.info("taskQueue write is file end"); + break; + } + } + while (true) { + if (ConfigCache.resultQueue.size() > 0) { + try { + Map task = ConfigCache.resultQueue.take(); + FileUtil.writeFile(resultTaskPath, JSONObject.toJSONString(task)); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } else { + log.info("taskQueue write is file end"); + break; + } + } + } +} diff --git a/funasr-service/src/main/java/com/bw/funasr/service/FunasrTaskService.java b/funasr-service/src/main/java/com/bw/funasr/service/FunasrTaskService.java new file mode 100644 index 0000000..a4cb72d --- /dev/null +++ b/funasr-service/src/main/java/com/bw/funasr/service/FunasrTaskService.java @@ -0,0 +1,17 @@ +package com.bw.funasr.service; + +import java.util.Map; + +public interface FunasrTaskService { + /** + * ocr远端任务 + * @param task + */ + public void create(Map task); + /** + * 解析结果 + * @param task + */ + public void parse(Map task); + +} diff --git a/funasr-service/src/main/java/com/bw/funasr/service/Impl/FunasrTaskServiceImpl.java b/funasr-service/src/main/java/com/bw/funasr/service/Impl/FunasrTaskServiceImpl.java new file mode 100644 index 0000000..4794ac9 --- /dev/null +++ b/funasr-service/src/main/java/com/bw/funasr/service/Impl/FunasrTaskServiceImpl.java @@ -0,0 +1,190 @@ +package com.bw.funasr.service.Impl; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.stereotype.Service; + +import com.alibaba.dashscope.audio.asr.transcription.Transcription; +import com.alibaba.dashscope.audio.asr.transcription.TranscriptionParam; +import com.alibaba.dashscope.audio.asr.transcription.TranscriptionQueryParam; +import com.alibaba.dashscope.audio.asr.transcription.TranscriptionResult; +import com.alibaba.dashscope.audio.asr.transcription.TranscriptionTaskResult; +import com.alibaba.fastjson2.JSONObject; +import com.bw.funasr.service.FunasrTaskService; +import com.bw.funasr.entity.AppResultDoc; +import com.bw.funasr.utils.DownLoadUtil; +import com.bw.funasr.cache.ConfigCache; +import com.bw.funasr.entity.Constants; +import com.google.gson.*; + +import lombok.extern.slf4j.Slf4j; + +/** + * 语音转文字服务实现类 + */ +@Service +@Slf4j +@RefreshScope +public class FunasrTaskServiceImpl implements FunasrTaskService{ + + @Value("${aliyun.apiKey}") + private String apiKey; + + @Value("${aliyun.model}") + private String model; + + @Value("${aliyun.apiUrl}") + private String apiUrl; + + @Value("${api.save-url}") + private String saveUrl; + + @Override + public void create(Map task) { + // TODO Auto-generated method stub + String videoUrl = task.get(Constants.VIDEOURL).toString(); + + String url = videoUrl.replace("10.8.0.16", "182.92.120.176"); + com.alibaba.dashscope.utils.Constants.baseHttpApiUrl = apiUrl; + // 创建转写请求参数。 + TranscriptionParam param = + TranscriptionParam.builder() + .apiKey(apiKey) + .model(model) +// .parameter("language_hints", new String[]{"zh", "en"})//language_hints为可选参数,用于指定待识别音频的语言代码 + .fileUrls(Arrays.asList(url)) + .build(); + try { + Transcription transcription = new Transcription(); + // 提交转写请求 + TranscriptionResult result = transcription.asyncCall(param); + + System.out.println("RequestId: " + result.getRequestId()); + String jobId = result.getTaskId(); + log.info("语音解析任务提交成功,任务ID:{}", (String)task.get(Constants.TASKID)); + + task.put(Constants.JOBID, URLEncoder.encode(jobId.replace("\"", ""), "UTF-8")); + + //任务创建成功,放到监控结果队列中 + ConfigCache.resultQueue.put(task); + + } catch (Exception e) { + log.error("提交视频解析任务异常", e); + //失败直接发送结果 + AppResultDoc entity = new AppResultDoc(); + entity.setTaskId((String)task.get(Constants.TASKID)); + entity.setAppId((Integer)task.get(Constants.ID)); + long now = System.currentTimeMillis(); + entity.setCreateTime(now); + Map result = new HashMap(16); + result.put(Constants.ERROR, "识别任务创建异常"); + entity.setResult(result); + entity.setStatus(2); + entity.setDel(0); + entity.setInput(task); + //回传给api服务保存 + DownLoadUtil.doPost(saveUrl, JSONObject.toJSONString(entity)); + } + } + + @Override + public void parse(Map task) { + // TODO Auto-generated method stub + try { + String jobId = (String) task.get(Constants.JOBID); + TranscriptionQueryParam queryParam = TranscriptionQueryParam.builder() + .apiKey(apiKey) + .taskId(jobId) + .build(); + Transcription transcription = new Transcription(); + // 提交转写请求 + TranscriptionResult result = transcription.wait(queryParam); + String taskStatus = result.getTaskStatus().toString(); + log.info("获取解析结果-jobId:{},status:{}",jobId,taskStatus); + if ("SUCCEEDED".equals(taskStatus)) { + // 获取转写结果 + List taskResultList = result.getResults(); + if (taskResultList != null && taskResultList.size() > 0) { + for (TranscriptionTaskResult taskResult : taskResultList) { + String transcriptionUrl = taskResult.getTranscriptionUrl(); + HttpURLConnection connection = (HttpURLConnection) new URL(transcriptionUrl).openConnection(); + connection.setRequestMethod("GET"); + connection.connect(); + BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + JsonObject jsonResult = gson.fromJson(reader, JsonObject.class); + System.out.println(gson.toJson(jsonResult)); + JsonArray transcripts = jsonResult.getAsJsonArray("transcripts"); + if (transcripts != null && transcripts.size() > 0) { + JsonObject firstTranscript = transcripts.get(0).getAsJsonObject(); + String transcriptText = firstTranscript.get("text").getAsString(); + + //成功 发送结果 + log.info("发送解析结果-taskId{}",task.get(Constants.TASKID)); + AppResultDoc entity = new AppResultDoc(); + entity.setTaskId((String)task.get(Constants.TASKID)); + entity.setAppId((Integer)task.get(Constants.ID)); + long now = System.currentTimeMillis(); + entity.setCreateTime(now); + Map result1 = new HashMap(16); + result1.put(Constants.VOICECONTENT, transcriptText); + entity.setResult(result1); + entity.setStatus(1); + entity.setDel(0); + entity.setInput(task); + //回传给api服务保存 + DownLoadUtil.doPost(saveUrl, JSONObject.toJSONString(entity)); + } + } + } + }else if("PENDING".equals(taskStatus) || "RUNNING".equals(taskStatus)){ + //识别中 -- 放回队列 + ConfigCache.resultQueue.put(task); + }else { + log.error("语音转文字任务失败,jobId: {}, status: {}", jobId, taskStatus); + //获取错误信息 + JsonObject outputJson = result.getOutput(); + String message = outputJson.get("message").getAsString(); + //发送失败结果 + AppResultDoc entity = new AppResultDoc(); + entity.setTaskId((String)task.get(Constants.TASKID)); + entity.setAppId((Integer) task.get(Constants.ID)); + entity.setCreateTime(System.currentTimeMillis()); + + Map resultMap = new HashMap<>(16); + resultMap.put(Constants.ERROR, message); + entity.setResult(resultMap); + entity.setStatus(2); + entity.setDel(0); + entity.setInput(task); + DownLoadUtil.doPost(saveUrl, JSONObject.toJSONString(entity)); + } + } catch (Throwable e) { + log.error("创建文档解析任务异常。e:",e); + //发送失败结果 + AppResultDoc entity = new AppResultDoc(); + entity.setTaskId((String)task.get(Constants.TASKID)); + entity.setAppId((Integer)task.get(Constants.ID)); + long now = System.currentTimeMillis(); + entity.setCreateTime(now); + Map result = new HashMap(16); + result.put(Constants.ERROR, "源文件解析异常"); + entity.setResult(result); + entity.setStatus(2); + entity.setDel(0); + entity.setInput(task); + //回传给api服务保存 + DownLoadUtil.doPost(saveUrl, JSONObject.toJSONString(entity)); + } + } +} diff --git a/funasr-service/src/main/java/com/bw/funasr/service/Impl/TaskReceiveServiceImpl.java b/funasr-service/src/main/java/com/bw/funasr/service/Impl/TaskReceiveServiceImpl.java new file mode 100644 index 0000000..0464317 --- /dev/null +++ b/funasr-service/src/main/java/com/bw/funasr/service/Impl/TaskReceiveServiceImpl.java @@ -0,0 +1,55 @@ +package com.bw.funasr.service.Impl; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.stereotype.Service; + +import com.alibaba.fastjson.JSONObject; +import com.bw.funasr.cache.ConfigCache; +import com.bw.funasr.entity.Constants; +import com.bw.funasr.service.TaskReceiveService; + +import lombok.extern.slf4j.Slf4j; + +/** + * 任务接收服务层实现类 + * @author jian.mao + * @date 2025年1月14日 + * @description + */ +@Service +@Slf4j +public class TaskReceiveServiceImpl implements TaskReceiveService { + + @Override + public String put(String dataJson) { + Map response = new HashMap<>(16); + int code = 200; + String message = "success"; + Map task = null; + try { + task = JSONObject.parseObject(dataJson); + } catch (Exception e) { + log.error("参数结构不合法,", e); + code = 100010; + message = "参数不合法"; + } + // 写入队列 + try { + if(task.containsKey(Constants.TRACE) && (boolean)task.get(Constants.TRACE)){ + ConfigCache.taskQueue.putFirst(task); + }else{ + ConfigCache.taskQueue.put(task); + } + } catch (InterruptedException e) { + log.error("任务写入队列异常,", e); + code = 100011; + message = "任务写入队列失败"; + } + response.put(Constants.CODE, code); + response.put(Constants.MESSAGE, message); + return JSONObject.toJSONString(response); + } + +} diff --git a/funasr-service/src/main/java/com/bw/funasr/service/TaskReceiveService.java b/funasr-service/src/main/java/com/bw/funasr/service/TaskReceiveService.java new file mode 100644 index 0000000..be4a706 --- /dev/null +++ b/funasr-service/src/main/java/com/bw/funasr/service/TaskReceiveService.java @@ -0,0 +1,17 @@ +package com.bw.funasr.service; + +/** + * 任务接收服务层 + * @author jian.mao + * @date 2025年1月14日 + * @description + */ +public interface TaskReceiveService { + + /** + * 任务新增 + * @param dataJson + * @return + */ + public String put(String dataJson); +} diff --git a/funasr-service/src/main/java/com/bw/funasr/utils/DateUtil.java b/funasr-service/src/main/java/com/bw/funasr/utils/DateUtil.java new file mode 100644 index 0000000..d4852ec --- /dev/null +++ b/funasr-service/src/main/java/com/bw/funasr/utils/DateUtil.java @@ -0,0 +1,177 @@ +package com.bw.funasr.utils; + + +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Date; + +import lombok.extern.slf4j.Slf4j; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + +/** + * 日期工具类 + * + * @author jian.mao + * @date 2022年11月15日 + * @description + */ +@Slf4j +public class DateUtil { + + /** + * @return + */ + public static String getTimeStrForNow() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHH"); + return sdf.format(new Date()); + } + + + public static String getTimeStrForDay(long time) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + + return sdf.format(new Date(time * 1000)); + } + + public static String getTimeStrForDay() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + + return sdf.format(new Date()); + } + + + public static String getDateTime() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String time = sdf.format(new Date()); + return time; + } + + public static String getDateTime(Long timestap) { + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String time = sdf.format(new Date(timestap)); + return time; + } + + public static String getDate(Long timestap) { + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + String time = sdf.format(new Date(timestap)); + return time; + } + + public static String getDateTimeForMonth() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM"); + String time = sdf.format(new Date()); + return time; + } + + /** + * 休眠 + * + * @param millis 毫秒 + */ + public static void sleep(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * 1. @Description:时间戳转时间 + * 2. @Author: ying.zhao + * 3. @Date: 2023/3/28 + */ + + public static String timestampToDate(String time) { + int thirteen = 13; + int ten = 10; + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); +// if (time.length() == thirteen) { + if (time.length() > ten) { + return sdf.format(new Date(Long.parseLong(time))); + } else { + return sdf.format(new Date(Integer.parseInt(time) * 1000L)); + } + } + + public static String parseCreated(String jsonTime){ + String formattedDateTime = getDateTime(); + try { + // 使用fastjson解析JSON数据 + JSONObject jsonObject = JSON.parseObject(jsonTime); + // 获取日期和时间的值 + JSONObject dateObject = jsonObject.getJSONObject("date"); + int day = dateObject.getIntValue("day"); + int month = dateObject.getIntValue("month"); + int year = dateObject.getIntValue("year"); + + JSONObject timeObject = jsonObject.getJSONObject("time"); + int hour = timeObject.getIntValue("hour"); + int minute = timeObject.getIntValue("minute"); + int second = timeObject.getIntValue("second"); + + // 创建LocalDateTime对象 + LocalDateTime dateTime = LocalDateTime.of(year, month, day, hour, minute, second); + + // 定义日期时间格式化器 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + // 格式化日期时间 + formattedDateTime = dateTime.format(formatter); + } catch (Exception e) { + log.info("日期转换失败:{}",e); + } + return formattedDateTime; + } + + /** + * 字符串转换日期 + * @param format + * @param date + * @return + */ + public static Date strToDate(String format,String date){ + SimpleDateFormat sdf = new SimpleDateFormat(format); + if (date == null || date.equals("")){ + return new Date(); + }else{ + Date ru = null; + try { + ru = sdf.parse(date); + } catch (ParseException e) { + e.printStackTrace(); + } + return ru; + } + } + /** + * 日期格式话 + * @param format 日期格式 + * @param dater 要转换的日期,默认当前时间 + * @return + */ + public static String FormatDate(String format,Date date){ + String fromatDate = null; + SimpleDateFormat sdf = new SimpleDateFormat(format); + if (date == null){ + fromatDate = sdf.format(new Date()); + }else{ + fromatDate = sdf.format(date); + } + return fromatDate; + } + public static void main(String[] args) { + String time = timestampToDate("955814400000"); + System.out.println(time); + } +} diff --git a/funasr-service/src/main/java/com/bw/funasr/utils/DownLoadUtil.java b/funasr-service/src/main/java/com/bw/funasr/utils/DownLoadUtil.java new file mode 100644 index 0000000..e2ec6de --- /dev/null +++ b/funasr-service/src/main/java/com/bw/funasr/utils/DownLoadUtil.java @@ -0,0 +1,1045 @@ +package com.bw.funasr.utils; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.StatusLine; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.AuthCache; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.HttpClient; +import org.apache.http.client.HttpRequestRetryHandler; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.config.SocketConfig; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.LayeredConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.auth.BasicScheme; +import org.apache.http.impl.client.BasicAuthCache; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.client.LaxRedirectStrategy; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.bw.funasr.entity.Constants; + +import okhttp3.Call; +import okhttp3.Headers; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + + + + + + + + + +/** + * 下载工具类 + * @author jian.mao + * @date 2023年9月19日 + * @description + */ +public class DownLoadUtil { + + private static String ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36"; + private final static Logger log = LoggerFactory.getLogger(DownLoadUtil.class); + /** 代理服务器(产品官网 www.16yun.cn) **/ + final static String PROXYHOST = "u270.40.tp.16yun.cn"; + final static Integer PROXYPORT = 6448; + /** 代理验证信息 **/ + final static String PROXYUSER = "16HFBVJC"; + final static String PROXYPASS = "897944"; + + private static PoolingHttpClientConnectionManager cm = null; + private static HttpRequestRetryHandler httpRequestRetryHandler = null; + private static HttpHost proxy = null; + + private static CredentialsProvider credsProvider = null; + private static RequestConfig reqConfig = null; + + static { + ConnectionSocketFactory plainsf = PlainConnectionSocketFactory + .getSocketFactory(); + LayeredConnectionSocketFactory sslsf = SSLConnectionSocketFactory + .getSocketFactory(); + + Registry registry = RegistryBuilder.create().register("http", plainsf) + .register("https", sslsf).build(); + + cm = new PoolingHttpClientConnectionManager(registry); + cm.setMaxTotal(20); + cm.setDefaultMaxPerRoute(5); + + proxy = new HttpHost(PROXYHOST, PROXYPORT, "https"); + + credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials(AuthScope.ANY, + new UsernamePasswordCredentials(PROXYUSER, PROXYPASS)); + + reqConfig = RequestConfig.custom().setConnectionRequestTimeout(5000) + .setConnectTimeout(5000).setSocketTimeout(5000) + .setExpectContinueEnabled(false) + .setProxy(new HttpHost(PROXYHOST, PROXYPORT)).build(); + } + + /** + * 模拟客户端get请求 + * + * @param url + * 模拟请求得url + * @param headers + * 头部信息,没有可以不传 + * @return + */ + @SafeVarargs + public static String proxyDoGet(String url, Map... headers) { + // 设置超时时间 + int timeout = 30; + RequestConfig config = RequestConfig.custom() + .setConnectTimeout(timeout * 1000) + .setConnectionRequestTimeout(timeout * 1000) + .setSocketTimeout(timeout * 1000).build(); + SocketConfig socketConfig = SocketConfig.custom() + .setSoKeepAlive(false) + .setSoLinger(1) + .setSoReuseAddress(true) + .setSoTimeout(timeout * 1000) + .setTcpNoDelay(true).build(); + AuthCache authCache = new BasicAuthCache(); + authCache.put(proxy, new BasicScheme()); + HttpClientContext localContext = HttpClientContext.create(); + localContext.setAuthCache(authCache); + HttpClientBuilder httpBuilder = HttpClientBuilder.create(); + CloseableHttpClient httpClient = httpBuilder + .setDefaultSocketConfig(socketConfig) + .setDefaultRequestConfig(config) + .setDefaultCredentialsProvider(credsProvider).build(); + HttpGet httpGet = new HttpGet(url); + httpGet.setConfig(reqConfig); + if (headers != null && headers.length > 0) { + Map tempHeaders = headers[0]; + for (String key : tempHeaders.keySet()) { + httpGet.setHeader(key, tempHeaders.get(key).toString()); + } + } else { + httpGet.setHeader("Accept", + "application/json, text/javascript, */*; q=0.01"); + httpGet.setHeader("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8"); + } + CloseableHttpResponse response = null; + String html = ""; + int notFundCode = 404; + int successCode = 200; + try { + response = httpClient.execute(httpGet, localContext); + // 从响应模型中获取响应实体 + HttpEntity responseEntity = response.getEntity(); + StatusLine statusLine = response.getStatusLine(); + System.out.println("响应状态为:" + response.getStatusLine()); + if (statusLine.getStatusCode() == successCode) { + if (responseEntity != null) { + html = EntityUtils.toString(responseEntity, "utf-8"); + System.out.println("响应内容长度为:" + + responseEntity.getContentLength()); + // 下载结果为空不正常 + if (html.equals(Constants.EMPTY)) { + html = "Download failed error is:reslut is null"; + } + } + } else if (statusLine.getStatusCode() == notFundCode) { + html = "

页面404,正常结束请求即可

"; + } else { + throw new Exception("请求错误,code码为:" + statusLine.getStatusCode()); + } + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:reslut is null"; + }finally{ + try { + response.close(); + httpClient.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + return html; + + } + + + public static String httpsslProxyGet(String url, Map... headers) throws Exception { + //采用绕过验证的方式处理https请求 + SSLContext sslcontext = createIgnoreVerifySSL(); + + // 设置协议http和https对应的处理socket链接工厂的对象 + Registry socketFactoryRegistry = RegistryBuilder.create() + .register("http", PlainConnectionSocketFactory.INSTANCE) + .register("https", new SSLConnectionSocketFactory(sslcontext)) + .build(); + PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + connManager.setMaxTotal(50); + connManager.setDefaultMaxPerRoute(10); + HttpClients.custom().setConnectionManager(connManager); + // 设置超时时间 + int timeout = 30; + RequestConfig config = RequestConfig.custom() + .setConnectTimeout(timeout * 1000) + .setConnectionRequestTimeout(timeout * 1000) + .setSocketTimeout(timeout * 1000).build(); + SocketConfig socketConfig = SocketConfig.custom() + .setSoKeepAlive(false) + .setSoLinger(1) + .setSoReuseAddress(true) + .setSoTimeout(timeout * 1000) + .setTcpNoDelay(true).build(); + AuthCache authCache = new BasicAuthCache(); + authCache.put(proxy, new BasicScheme()); + HttpClientContext localContext = HttpClientContext.create(); + localContext.setAuthCache(authCache); + HttpClientBuilder httpBuilder = HttpClientBuilder.create(); + CloseableHttpClient httpClient = httpBuilder + .setConnectionManager(connManager) + .setDefaultSocketConfig(socketConfig) + .setDefaultRequestConfig(config) + .setDefaultCredentialsProvider(credsProvider).build(); + HttpGet httpGet = new HttpGet(url); + httpGet.setConfig(reqConfig); + if (headers != null && headers.length > 0) { + Map tempHeaders = headers[0]; + for (String key : tempHeaders.keySet()) { + httpGet.setHeader(key, tempHeaders.get(key).toString()); + } + } else { + httpGet.setHeader("Accept", + "application/json, text/javascript, */*; q=0.01"); + httpGet.setHeader("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8"); + } + CloseableHttpResponse response = null; + String html = ""; + int notFundCode = 404; + int successCode = 200; + try { + response = httpClient.execute(httpGet, localContext); + // 从响应模型中获取响应实体 + HttpEntity responseEntity = response.getEntity(); + StatusLine statusLine = response.getStatusLine(); + System.out.println("响应状态为:" + response.getStatusLine()); + if (statusLine.getStatusCode() == successCode) { + if (responseEntity != null) { + html = EntityUtils.toString(responseEntity, "utf-8"); + System.out.println("响应内容长度为:" + + responseEntity.getContentLength()); + // 下载结果为空不正常 + if (html.equals(Constants.EMPTY)) { + html = "Download failed error is:reslut is null"; + } + } + } else if (statusLine.getStatusCode() == notFundCode) { + html = "

页面404,正常结束请求即可

"; + } else { + throw new Exception("请求错误,code码为:" + statusLine.getStatusCode()); + } + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:reslut is null"; + }finally{ + try { + response.close(); + httpClient.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + return html; + + } + + + /** + * json参数方式POST提交 + * @param url + * @param params + * @return + */ + public static String doPost(String url, String params, Map... headers){ + String strResult = ""; + //设置超时时间 + int timeout = 60; + RequestConfig config = RequestConfig.custom(). + setConnectTimeout(timeout * 1000). + setConnectionRequestTimeout(timeout * 1000). + setSocketTimeout(timeout * 1000).build(); + SocketConfig socketConfig = SocketConfig.custom() + .setSoKeepAlive(false) + .setSoLinger(1) + .setSoReuseAddress(true) + .setSoTimeout(timeout * 1000) + .setTcpNoDelay(true).build(); +// AuthCache authCache = new BasicAuthCache(); +// authCache.put(proxy, new BasicScheme()); +// HttpClientContext localContext = HttpClientContext.create(); +// localContext.setAuthCache(authCache); + // 1. 获取默认的client实例 + HttpClientBuilder httpBuilder = HttpClientBuilder.create(); + httpBuilder.setUserAgent(ua); + HttpClient client = httpBuilder.setDefaultSocketConfig(socketConfig).setDefaultRequestConfig(config).build(); +// HttpClient client = httpBuilder.setDefaultSocketConfig(socketConfig).setDefaultRequestConfig(config).setConnectionManager(cm) +// .setDefaultCredentialsProvider(credsProvider).build(); + // 2. 创建httppost实例 + HttpPost httpPost = new HttpPost(url); +// httpPost.setConfig(reqConfig); + if (headers != null && headers.length > 0) { + Map tempHeaders = headers[0]; + for (String key : tempHeaders.keySet()) { + httpPost.setHeader(key, tempHeaders.get(key).toString()); + } + } else { + httpPost.addHeader("Content-Type", "application/json;charset=utf-8"); + } + HttpResponse resp = null; + try { + httpPost.setEntity(new StringEntity(params,"utf-8")); + resp = client.execute(httpPost); +// resp = client.execute(httpPost,localContext); + StatusLine statusLine = resp.getStatusLine(); + System.out.println("响应状态为:" + resp.getStatusLine()); + int notFundCode = 300; + int successCode = 200; + if(statusLine.getStatusCode() >= successCode && statusLine.getStatusCode() < notFundCode){ + // 7. 获取响应entity + HttpEntity respEntity = resp.getEntity(); + strResult = EntityUtils.toString(respEntity, "UTF-8"); + if(strResult.equals(Constants.EMPTY)){ + strResult = "Download failed error is:reslut is null"; + } + }else{ + throw new Exception("请求错误,code码为:"+statusLine.getStatusCode()); + } + } catch (Exception e) { + e.printStackTrace(); + strResult = "Download failed error is:"+ThrowMessageUtil.getErrmessage(e); + } + return strResult; + } + public static String httpPost(String url,String params) { + String html=""; + html = doPost(url,params); + int i = 1; + while(true){ + if(html.contains("Download failed error is:")){ + log.error("DownLoadUtil------------->download is failure,url is:"+url); + DateUtil.sleep(5000); + i++; + }else{ + break; + } + if(i > 5){ + break; + } + html = doPost(url,params); + } + return html; + } + /** + * 绕过验证 + * + * @return + * @throws NoSuchAlgorithmException + * @throws KeyManagementException + */ + public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException { + SSLContext sc = SSLContext.getInstance("SSLv3"); + + // 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法 + X509TrustManager trustManager = new X509TrustManager() { + @Override + public void checkClientTrusted( + java.security.cert.X509Certificate[] paramArrayOfX509Certificate, + String paramString) throws CertificateException { + } + + @Override + public void checkServerTrusted( + java.security.cert.X509Certificate[] paramArrayOfX509Certificate, + String paramString) throws CertificateException { + } + + @Override + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + }; + + sc.init(null, new TrustManager[] { trustManager }, null); + return sc; + } + /** + * 模拟请求 + * + * @param url 资源地址 + * @param map 参数列表 + * @param encoding 编码 + * @return + * @throws NoSuchAlgorithmException + * @throws KeyManagementException + * @throws IOException + * @throws ClientProtocolException + */ + public static String httpsslGet(String url,Map ... headers) { + String html=""; + CloseableHttpClient client = null; + HttpEntity responseEntity = null; + CloseableHttpResponse response = null; + try { + log.debug("DownLoadUtil------------->设置下载相关信息, start...."); + //采用绕过验证的方式处理https请求 + SSLContext sslcontext = createIgnoreVerifySSL(); + + // 设置协议http和https对应的处理socket链接工厂的对象 + Registry socketFactoryRegistry = RegistryBuilder.create() + .register("http", PlainConnectionSocketFactory.INSTANCE) + .register("https", new SSLConnectionSocketFactory(sslcontext)) + .build(); + PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + connManager.setMaxTotal(50); + connManager.setDefaultMaxPerRoute(10); + HttpClients.custom().setConnectionManager(connManager); + //设置超时时间 + int timeout = 30; + RequestConfig config = RequestConfig.custom(). + setConnectTimeout(timeout * 1000). + setConnectionRequestTimeout(timeout * 1000). + setSocketTimeout(timeout * 1000).build(); + SocketConfig socketConfig = SocketConfig.custom() + .setSoKeepAlive(false) + .setSoLinger(1) + .setSoReuseAddress(true) + .setSoTimeout(10000) + .setTcpNoDelay(true).build(); + // 设置重定向策略 + LaxRedirectStrategy redirectStrategy = new LaxRedirectStrategy(); + //创建自定义的httpclient对象 + client = HttpClients.custom().setConnectionManager(connManager).setDefaultRequestConfig(config).setRedirectStrategy(redirectStrategy).setDefaultSocketConfig(socketConfig).setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36").build(); +// CloseableHttpClient client = HttpClients.createDefault(); + + HttpGet httpGet = new HttpGet(url); + if(headers != null && headers.length > 0){ + Map tempHeaders = headers[0]; + for (String key : tempHeaders.keySet()) { + httpGet.setHeader(key,tempHeaders.get(key).toString()); + } + }else{ + httpGet.setHeader("Accept", "application/json, text/javascript, */*; q=0.01"); + httpGet.setHeader("Accept-Language","zh-CN,zh;q=0.9,en;q=0.8"); + httpGet.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36"); + } + log.debug("DownLoadUtil------------->设置下载相关信息, end...."); + try { + int notFundCode = 404; + int successCode = 200; + log.debug("DownLoadUtil------------->下载执行,start...."); + httpGet.setConfig(config); + response = client.execute(httpGet); + log.debug("DownLoadUtil------------->下载执行,end...."); + // 从响应模型中获取响应实体 + StatusLine statusLine = response.getStatusLine(); + log.debug("DownLoadUtil------------->响应状态为:" + response.getStatusLine()+",下载请求没问题url:"+url+",read is start ...."); + System.out.println("响应状态为:" + response.getStatusLine()); + responseEntity = response.getEntity(); + log.debug("DownLoadUtil------------->响应状态为:" + response.getStatusLine()+",下载请求没问题url:"+url+",read is end ...."); + if(statusLine.getStatusCode() == successCode){ + if (responseEntity != null) { + html=EntityUtils.toString(responseEntity,"utf-8"); + System.out.println("响应内容长度为:" + responseEntity.getContentLength()); + } + }else if(statusLine.getStatusCode() == notFundCode){ + html = "

页面404,正常结束请求即可

"; + }else{ + throw new Exception("请求错误,code码为:"+statusLine.getStatusCode()); + } + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:"+ThrowMessageUtil.getErrmessage(e); + + } + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:"+ThrowMessageUtil.getErrmessage(e); + }finally{ + try { + responseEntity.getContent().close(); + response.close(); + client.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + + return html; + } + + public static String httpSSLGet(String url,Map ... headers) { + String html=""; + html = httpsslGet(url,headers); + int i = 1; + while(true){ + if(html.contains("Download failed error is:")){ + log.error("DownLoadUtil------------->download is failure,url is:"+url); + DateUtil.sleep(30000); + i++; + }else{ + break; + } + if(i > 5){ + break; + } + html = httpsslGet(url,headers); + } + return html; + } + public static String doPostFrom(String url,Map param,Map ... headers){ + //设置超时时间 + int timeout = 15; + RequestConfig config = RequestConfig.custom(). + setConnectTimeout(timeout * 1000). + setConnectionRequestTimeout(timeout * 1000). + setSocketTimeout(timeout * 1000).build(); + SocketConfig socketConfig = SocketConfig.custom() + .setSoKeepAlive(false) + .setSoLinger(1) + .setSoReuseAddress(true) + .setSoTimeout(10000) + .setTcpNoDelay(true).build(); +// AuthCache authCache = new BasicAuthCache(); +// authCache.put(proxy, new BasicScheme()); +// HttpClientContext localContext = HttpClientContext.create(); +// localContext.setAuthCache(authCache); + HttpClientBuilder httpBuilder = HttpClientBuilder.create(); + httpBuilder.setUserAgent(ua); +// HttpClient httpClient = httpBuilder.setDefaultSocketConfig(socketConfig).setDefaultRequestConfig(config).setConnectionManager(cm) +// .setDefaultCredentialsProvider(credsProvider).build(); + HttpClient httpClient = httpBuilder.setDefaultSocketConfig(socketConfig).setDefaultRequestConfig(config).build(); + HttpPost httpPost = new HttpPost(url); +// httpPost.setConfig(reqConfig); + if(headers != null && headers.length > 0){ + Map tempHeaders = headers[0]; + for (String key : tempHeaders.keySet()) { + httpPost.setHeader(key,tempHeaders.get(key).toString()); + } + }else{ + httpPost.addHeader("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"); + httpPost.addHeader("accept-Language", "zh-CN,zh;q=0.9,en;q=0.8"); + httpPost.addHeader("content-type", "application/x-www-form-urlencoded"); + httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"); +// httpPost.addHeader("Referer", "http://www.neeq.com.cn/rule/Business_rules.html"); + } + // 创建请求参数 + List list = new LinkedList<>(); + for (String key : param.keySet()) { + BasicNameValuePair param1 = new BasicNameValuePair(key,param.get(key).toString()); + list.add(param1); + } + // 使用URL实体转换工具 + String html=""; + try { + UrlEncodedFormEntity entityParam = new UrlEncodedFormEntity(list, "UTF-8"); + httpPost.setEntity(entityParam); + HttpResponse response = httpClient.execute(httpPost); +// HttpResponse response = httpClient.execute(httpPost,localContext); + // 从响应模型中获取响应实体 + HttpEntity responseEntity = response.getEntity(); + StatusLine statusLine = response.getStatusLine(); + System.out.println("响应状态为:" + response.getStatusLine()); + int notFundCode = 404; + int successCode = 200; + if(statusLine.getStatusCode() == successCode){ + if (responseEntity != null) { + html=EntityUtils.toString(responseEntity,"utf-8"); + } + }else{ + throw new Exception("请求错误,code码为:"+statusLine.getStatusCode()); + } + + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:"+ThrowMessageUtil.getErrmessage(e); + } + + return html; + + } + public static String httpPostForm(String url,Map params,Map ... headers) { + String html=""; + html = doPostFrom(url,params); + int i = 1; + while(true){ + if(html.contains("Download failed error is:")){ + log.error("DownLoadUtil------------->download is failure,url is:"+url); + DateUtil.sleep(5000); + i++; + }else{ + break; + } + if(i > 5){ + break; + } + html = doPostFrom(url,params,headers); + } + return html; + } + + public static String dosslPost(String url,String params,Map ... headers) { + String html=""; + CloseableHttpClient client = null; + HttpEntity responseEntity = null; + CloseableHttpResponse response = null; + try { + //采用绕过验证的方式处理https请求 + SSLContext sslcontext = createIgnoreVerifySSL(); + // 设置协议http和https对应的处理socket链接工厂的对象 + Registry socketFactoryRegistry = RegistryBuilder.create() + .register("http", PlainConnectionSocketFactory.INSTANCE) + .register("https", new SSLConnectionSocketFactory(sslcontext)) + .build(); + PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + HttpClients.custom().setConnectionManager(connManager); + //设置超时时间 + int timeout = 5; + RequestConfig config = RequestConfig.custom(). + setConnectTimeout(timeout * 1000). + setConnectionRequestTimeout(timeout * 1000). + setSocketTimeout(timeout * 1000).build(); + SocketConfig socketConfig = SocketConfig.custom() + .setSoKeepAlive(false) + .setSoLinger(1) + .setSoReuseAddress(true) + .setSoTimeout(10000) + .setTcpNoDelay(true).build(); + //创建自定义的httpclient对象 + client = HttpClients.custom().setConnectionManager(connManager).setDefaultRequestConfig(config).setDefaultSocketConfig(socketConfig).build(); +// CloseableHttpClient client = HttpClients.createDefault(); + // 2. 创建httppost实例 + HttpPost httpPost = new HttpPost(url); +// httpPost.setConfig(reqConfig); + httpPost.addHeader("Content-Type", "application/json;charset=utf-8"); + if(headers != null && headers.length > 0){ + Map tempHeaders = headers[0]; + for (String key : tempHeaders.keySet()) { + httpPost.setHeader(key,tempHeaders.get(key).toString()); + } + }else{ + httpPost.setHeader("Accept", "application/json, text/javascript, */*; q=0.01"); + httpPost.setHeader("Accept-Language","zh-CN,zh;q=0.9,en;q=0.8"); + httpPost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36"); + } + + try { + httpPost.setEntity(new StringEntity(params,"utf-8")); + response = client.execute(httpPost); + int notFundCode = 404; + int successCode = 200; + // 从响应模型中获取响应实体 + StatusLine statusLine = response.getStatusLine(); + System.out.println("响应状态为:" + response.getStatusLine()); + responseEntity = response.getEntity(); + if(statusLine.getStatusCode() == successCode){ + if (responseEntity != null) { + html=EntityUtils.toString(responseEntity,"utf-8"); + System.out.println("响应内容长度为:" + responseEntity.getContentLength()); + } + }else if(statusLine.getStatusCode() == notFundCode){ + html = "

页面404,正常结束请求即可

"; + }else{ + throw new Exception("请求错误,code码为:"+statusLine.getStatusCode()); + } + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:"+ThrowMessageUtil.getErrmessage(e); + + } + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:"+ThrowMessageUtil.getErrmessage(e); + }finally{ + try { + responseEntity.getContent().close(); + response.close(); + client.close(); + } catch (UnsupportedOperationException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + + return html; + } + public static String dosslPostForm(String url,Map param,Map ... headers) { + String html=""; + try { + //采用绕过验证的方式处理https请求 + SSLContext sslcontext = createIgnoreVerifySSL(); + + // 设置协议http和https对应的处理socket链接工厂的对象 + Registry socketFactoryRegistry = RegistryBuilder.create() + .register("http", PlainConnectionSocketFactory.INSTANCE) + .register("https", new SSLConnectionSocketFactory(sslcontext)) + .build(); + PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + HttpClients.custom().setConnectionManager(connManager); + //设置超时时间 + int timeout = 5; + RequestConfig config = RequestConfig.custom(). + setConnectTimeout(timeout * 1000). + setConnectionRequestTimeout(timeout * 1000). + setSocketTimeout(timeout * 1000).build(); + SocketConfig socketConfig = SocketConfig.custom() + .setSoKeepAlive(false) + .setSoLinger(1) + .setSoReuseAddress(true) + .setSoTimeout(10000) + .setTcpNoDelay(true).build(); + //创建自定义的httpclient对象 + CloseableHttpClient client = HttpClients.custom().setConnectionManager(connManager).setDefaultRequestConfig(config).setDefaultSocketConfig(socketConfig).build(); +// CloseableHttpClient client = HttpClients.createDefault(); + // 2. 创建httppost实例 + HttpPost httpPost = new HttpPost(url); +// httpPost.setConfig(reqConfig); + if(headers != null && headers.length > 0){ + Map tempHeaders = headers[0]; + for (String key : tempHeaders.keySet()) { + httpPost.setHeader(key,tempHeaders.get(key).toString()); + } + }else{ + httpPost.setHeader("Accept", "application/json, text/javascript, */*; q=0.01"); + httpPost.setHeader("Accept-Language","zh-CN,zh;q=0.9,en;q=0.8"); + httpPost.addHeader("content-type", "application/x-www-form-urlencoded"); + httpPost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36"); + } + + // 创建请求参数 + List list = new LinkedList<>(); + for (String key : param.keySet()) { + BasicNameValuePair param1 = new BasicNameValuePair(key,param.get(key).toString()); + list.add(param1); + } + // 使用URL实体转换工具 + try { + UrlEncodedFormEntity entityParam = new UrlEncodedFormEntity(list, "UTF-8"); + httpPost.setEntity(entityParam); + HttpResponse response = client.execute(httpPost); +// HttpResponse response = httpClient.execute(httpPost,localContext); + // 从响应模型中获取响应实体 + int notFundCode = 404; + int successCode = 200; + HttpEntity responseEntity = response.getEntity(); + StatusLine statusLine = response.getStatusLine(); + System.out.println("响应状态为:" + response.getStatusLine()); + if(statusLine.getStatusCode() == successCode){ + if (responseEntity != null) { + html=EntityUtils.toString(responseEntity,"utf-8"); + } + }else{ + throw new Exception("请求错误,code码为:"+statusLine.getStatusCode()); + } + + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:"+ThrowMessageUtil.getErrmessage(e); + } + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:"+ThrowMessageUtil.getErrmessage(e); + } + + + return html; + } + public static String httpSSLPostForm(String url,Map params,Map ...headers) { + String html=""; + try { + html = dosslPostForm(url,params,headers); + } catch (Exception e) { + e.printStackTrace(); + // TODO: handle exception + html = "Download failed error is:Exception!"; + } + int i = 1; + while(true){ + if(html.contains("Download failed error is:")){ + log.error("DownLoadUtil------------->download is failure,url is:"+url); + DateUtil.sleep(30000); + i++; + }else{ + break; + } + if(i > 5){ + break; + } + try { + html = dosslPostForm(url,params,headers); + } catch (Exception e) { + e.printStackTrace(); + // TODO: handle exception + html = "Download failed error is:Exception!"; + } + } + return html; + } + public static String httpSSLPost(String url,String params,Map ...headers) { + String html=""; + try { + html = dosslPost(url,params,headers); + } catch (Throwable e) { + e.printStackTrace(); + // TODO: handle exception + html = "Download failed error is:Exception!"; + } + int i = 1; + while(true){ + if(html.contains("Download failed error is:")){ + log.error("DownLoadUtil------------->download is failure,url is:"+url); + DateUtil.sleep(30000); + i++; + }else{ + break; + } + if(i > 5){ + break; + } + try { + html = dosslPost(url,params,headers); + } catch (Throwable e) { + e.printStackTrace(); + // TODO: handle exception + html = "Download failed error is:Exception!"; + } + } + return html; + } + + /** + * 模拟客户端get请求 + * @param url 模拟请求得url + * @param headers 头部信息,没有可以不传 + * @return + */ + public static String doGet(String url,Map ... headers){ + //设置超时时间 + int timeout = 15; + RequestConfig config = RequestConfig.custom(). + setConnectTimeout(timeout * 1000). + setConnectionRequestTimeout(timeout * 1000). + setSocketTimeout(timeout * 1000).build(); + SocketConfig socketConfig = SocketConfig.custom() + .setSoKeepAlive(false) + .setSoLinger(1) + .setSoReuseAddress(true) + .setSoTimeout(10000) + .setTcpNoDelay(true).build(); + HttpClientBuilder httpBuilder = HttpClientBuilder.create(); + httpBuilder.setUserAgent(ua); + HttpClient httpClient = httpBuilder.setDefaultSocketConfig(socketConfig).setDefaultRequestConfig(config).build(); + HttpGet httpGet = new HttpGet(url); + if(headers != null && headers.length > 0){ + Map tempHeaders = headers[0]; + for (String key : tempHeaders.keySet()) { + httpGet.setHeader(key,tempHeaders.get(key).toString()); + } + }else{ + httpGet.setHeader("Accept", "application/json, text/javascript, */*; q=0.01"); + httpGet.setHeader("Accept-Language","zh-CN,zh;q=0.9,en;q=0.8"); + } + String html=""; + try { + HttpResponse response = httpClient.execute(httpGet); + // 从响应模型中获取响应实体 + HttpEntity responseEntity = response.getEntity(); + StatusLine statusLine = response.getStatusLine(); + System.out.println("响应状态为:" + response.getStatusLine()); + int notFundCode = 404; + int successCode = 200; + int successCodeMax = 300; + if(statusLine.getStatusCode() >= successCode && statusLine.getStatusCode() < successCodeMax){ + if (responseEntity != null) { + html=EntityUtils.toString(responseEntity,"utf-8"); + if(html.equals("")){ + html = "Download failed error is:reslut is null"; + } + } + }else if(statusLine.getStatusCode() == notFundCode){ + html = "

页面404,正常结束请求即可

"; + }else{ + throw new Exception("请求错误,code码为:"+statusLine.getStatusCode()); + } + } catch (Exception e) { + e.printStackTrace(); + html = "Download failed error is:"+ThrowMessageUtil.getErrmessage(e); + } + return html; + + } + + /** + * 文件下载 + * @param fileURL 文件链接 + * @param destinationFilePath 文件存储地址 + * @throws IOException + */ + public static void downloadFile(String fileURL, String destinationFilePath) throws IOException { + // 设置连接超时和读取超时 + RequestConfig config = RequestConfig.custom() + // 设置连接超时为10秒 + .setConnectTimeout(10000) + // 设置读取超时为30秒 + .setSocketTimeout(30000) + .build(); + + // 创建 HttpClient 实例 + try (CloseableHttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(config) + .build()) { + + // 创建 HttpGet 请求 + HttpGet request = new HttpGet(URI.create(fileURL)); + + // 执行请求 + try (CloseableHttpResponse response = httpClient.execute(request)) { + // 获取响应的输入流 + InputStream inputStream = response.getEntity().getContent(); + try (FileOutputStream outputStream = new FileOutputStream(destinationFilePath)) { + byte[] buffer = new byte[4096]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + } + log.info("文件下载成功---{}" , destinationFilePath); + } + } + } + + /** + * 文件上传 + * @param filePath + * @param gofastUrl + * @return + */ +// public static String upLoadFile(String filePath,String gofastUrl) { +// File file = new File(filePath); +// String realFilename = filePath.substring(filePath.lastIndexOf(File.separator) + 1); +// MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM); +// builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"file\";filename=\"" + realFilename + "\""), +// RequestBody.create(MediaType.parse("image/png"), file) +// +// ).addFormDataPart("output", "json").build(); +// RequestBody body = builder.build(); +// Request request = new Request.Builder().url(gofastUrl).post(body).header("Expect", "100-continue").build(); +// OkHttpClient.Builder okBuilder = new OkHttpClient.Builder(); +// OkHttpClient client = okBuilder.connectTimeout(600, TimeUnit.MILLISECONDS) +// .readTimeout(600, TimeUnit.SECONDS).build(); +// Call call = client.newCall(request); +// String html = ""; +// Response response = null; +// try { +// response = call.execute(); +// html = response.body().string(); +// } catch (IOException e) { +// log.info("upload fail:{}", filePath); +// e.printStackTrace(); +// } finally { +// response.close(); +// } +// return html; +// } + + /** + * 文件上传 + */ + public static String uploadFile(String filePath, String url, Map params) { + OkHttpClient client = new OkHttpClient.Builder() + .connectTimeout(60, TimeUnit.SECONDS) + .readTimeout(60, TimeUnit.SECONDS) + .build(); + + try { + File file = new File(filePath); + MultipartBody.Builder builder = new MultipartBody.Builder() + .setType(MultipartBody.FORM); + + // 添加参数 + for (Map.Entry entry : params.entrySet()) { + builder.addFormDataPart(entry.getKey(), entry.getValue()); + } + + // 添加文件 + builder.addFormDataPart("file", file.getName(), + RequestBody.create(MediaType.parse("application/octet-stream"), file)); + + RequestBody requestBody = builder.build(); + Request request = new Request.Builder() + .url(url) + .post(requestBody) + .build(); + + Response response = client.newCall(request).execute(); + return response.body().string(); + + } catch (Exception e) { + log.error("文件上传异常", e); + return "{\"code\":500,\"message\":\"上传失败\"}"; + } + } + public static void main(String[] args) throws Exception { + + } + + +} diff --git a/funasr-service/src/main/java/com/bw/funasr/utils/FileUtil.java b/funasr-service/src/main/java/com/bw/funasr/utils/FileUtil.java new file mode 100644 index 0000000..74132d1 --- /dev/null +++ b/funasr-service/src/main/java/com/bw/funasr/utils/FileUtil.java @@ -0,0 +1,41 @@ +package com.bw.funasr.utils; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +/** + * 文件工具类 + * @author jian.mao + * @date 2023年7月14日 + * @description + */ +public class FileUtil { + + /** + * 数据写入文件 + * @param Path 文件路径 + * @param result 数据 + * @throws IOException + */ + public static void writeFile(String path,String result){ + try { + FileWriter fw = new FileWriter(path,true); + fw.write(result+"\n"); + fw.flush(); + fw.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void delFile(String path) { + try { + File file = new File(path); + file.delete(); + } catch (Exception e) { + // TODO: handle exception + e.printStackTrace(); + } + } +} diff --git a/funasr-service/src/main/java/com/bw/funasr/utils/ThrowMessageUtil.java b/funasr-service/src/main/java/com/bw/funasr/utils/ThrowMessageUtil.java new file mode 100644 index 0000000..a708a8a --- /dev/null +++ b/funasr-service/src/main/java/com/bw/funasr/utils/ThrowMessageUtil.java @@ -0,0 +1,23 @@ +package com.bw.funasr.utils; + +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * @author jian.mao + * @date 2023年3月22日 + * @description + */ +public class ThrowMessageUtil { + + /** + * 获取异常信息 + * @param t + * @return + */ + public static String getErrmessage(Throwable t){ + StringWriter stringWriter=new StringWriter(); + t.printStackTrace(new PrintWriter(stringWriter,true)); + return stringWriter.getBuffer().toString(); + } +} diff --git a/funasr-service/src/main/resources/bootstrap.yml b/funasr-service/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..01d0903 --- /dev/null +++ b/funasr-service/src/main/resources/bootstrap.yml @@ -0,0 +1,52 @@ +# ==================== 必须文件:bootstrap.yml ==================== +# 这个文件用于配置Nacos客户端,优先级最高 +spring: + application: + name: funasr-service # 服务名,对应Nacos中的Data ID + + cloud: + nacos: + # ======== 配置中心 ======== + config: + server-addr: 127.0.0.1:8848 # Nacos地址 + username: nacos # 用户名 + password: nacos # 密码 + group: public_dev # 分组 + namespace: opai # 命名空间(默认public) + file-extension: yaml # 配置文件格式 + timeout: 5000 # 超时时间(ms) + + # 核心配置:开启动态刷新 + refresh-enabled: true # 必须为true! + + # 主配置文件(从Nacos加载) + data-id: ${spring.application.name}.${spring.cloud.nacos.config.file-extension} + + # 共享配置文件(可选) + shared-configs[0]: + data-id: application.yaml # 公共配置 + group: public_dev # 公共分组 + namespace: opai + refresh: true # 公共配置也要刷新 + + # 扩展配置(可选) + # extension-configs[0]: + # data-id: datasource.yaml + # group: dev + # refresh: true + + # ======== 服务发现 ======== + discovery: + server-addr: ${spring.cloud.nacos.config.server-addr} + username: ${spring.cloud.nacos.config.username} + password: ${spring.cloud.nacos.config.password} + group: ${spring.cloud.nacos.config.group} + namespace: ${spring.cloud.nacos.config.namespace} + +logging: + level: + root: info + com.alibaba.nacos.client.config.impl: WARN + file: + path: ../logs + \ No newline at end of file diff --git a/funasr-service/src/main/resources/logback-spring.xml b/funasr-service/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..c1fea0f --- /dev/null +++ b/funasr-service/src/main/resources/logback-spring.xml @@ -0,0 +1,36 @@ + + + + + + + + + true + + ${logging.level} + + + ${log-path}/funasr-service.log + + + ${log-path}/funasr-service.log.%d{yyyy-MM-dd} + 7 + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %line %-5level %logger{50} - %msg%n + UTF-8 + + + + + + + + diff --git a/pom.xml b/pom.xml index 85ff50b..6ae1a57 100644 --- a/pom.xml +++ b/pom.xml @@ -7,11 +7,12 @@ pom opai-api - ocr-service - asr-service - translate-service - ai-service - document-convert-service + ocr-service + asr-service + translate-service + ai-service + funasr-service + document-convert-service