仿牛客社区——7.19生成长图

news2024/11/15 11:03:36

 采用异步方式,通过任务方式,将次命令丢到消息队列中进行执行

关于wkhtmltopdf的配置(applaction.properties)

#关于wk的配置(生成长图

wk.image.command=D:/wkhtmltopdf/bin/wkhtmltoimage

wk.image.storage=D:/wkData/wk-images

生成主题常量

//主题:分享

String TOPIC_SHARE="share";

 

 wkconfig

在项目第一次启动的时候生成储存对应长图的目录

@Configuration
public class WkConfig {
	//在服务启动时生成图片目录
	private final static Logger logger= LoggerFactory.getLogger(WkConfig.class);

	@Value("${wk.image.storage}")
	private String wkImageStorage;
	@PostConstruct
	public void init(){

		//创建wk图片目录
		File file=new File(wkImageStorage);
		if(!file.exists()){
			file.mkdir();
			logger.info("创建wk图片目录:"+wkImageStorage);
		}
	}
}

controller

@Controller
public class ShareController implements CommunityConstant {

	private static final Logger logger = LoggerFactory.getLogger(ShareController.class);


	@Autowired
	private EventProducer eventProducer;

	//域名
	@Value("${community.path.domain}")
	private String domain;

	//项目名
	@Value("${server.servlet.context-path}")
	private String contextPath;

	//存储路径
	@Value("${wk.image.storage}")
	private String wkImageStorage;

	@RequestMapping(value = "/share", method = RequestMethod.GET)
	@ResponseBody
	public String shareImage(String htmlUrl) {

		String fileName = CommunityUtil.generateUUID();  //文件名

		Event event = new Event()
				.setTopic(TOPIC_SHARE)
				.setData("htmlUrl", htmlUrl)  //请求路径
				.setData("fileName", fileName) //文件名
				.setData("suffix", ".png"); //文件后缀

		//异步方式:通过事件发送
		eventProducer.fireEvent(event);

		//返回访问路径
		Map<String, Object> map = new HashMap<>();
		map.put("shareUrl", domain + contextPath + "/share/image/" + fileName);
		// eg: http://localhost:8080/community/share/image/33365834673863

		return CommunityUtil.getJsonString(0, null, map);
	}

	//获取长图(直接给浏览器返回一个图片,需要用response处理
	@RequestMapping(value = "/share/image/{fileName}", method = RequestMethod.GET)
	public void getImage(@PathVariable(name = "fileName") String fileName, HttpServletResponse response) {
		if (StringUtils.isBlank(fileName)) {
			throw new IllegalArgumentException("文件名不能为空!");
		}

		response.setContentType("image/png");

		//从本地读取文件
		File file = new File(wkImageStorage + "/" + fileName + ".png");

		try {
			OutputStream os = response.getOutputStream();
			FileInputStream is=new FileInputStream(file); //文件流:读取文件
			byte[] buffer=new byte[1024];
			int len=0;
			while((len=is.read(buffer))!=-1){
				os.write(buffer,0,len);
			}
		} catch (IOException e) {
			logger.error("获取长图失败:"+e.getMessage());
		}


	}
}

consumer

	//存储路径
	@Value("${wk.image.storage}")
	private String wkImageStorage;

	@Value("${wk.image.command}")
	private String wkImageCommand;

@KafkaListener(topics = TOPIC_SHARE)
	public void handleShare(ConsumerRecord record){
		//先进行判断record是否为空:未发事件或者发送的事件为空
		if(record==null|| record.value()==null){
			logger.error("发送的消息为空!");
			return;
		}

		//事件不为空:将事件转换为Event对象
		Event event= JSONObject.parseObject(record.value().toString(),Event.class);
		//判断对象是否为空
		if(event==null){
			logger.error("消息格式错误!");
			return;
		}

		String htmlUrl= (String) event.getData().get("htmlUrl");
		String fileName= (String) event.getData().get("fileName");
		String suffix= (String) event.getData().get("suffix");
		//生成长图命令
		String cmd=wkImageCommand+" --quality 75 "+htmlUrl+" "+wkImageStorage+"/"+fileName+suffix;
		try {
			Runtime.getRuntime().exec(cmd);
			logger.info("生成长图成功:"+cmd);
		} catch (IOException e) {
			logger.error("生成长图失败:"+e.getMessage());
		}

	}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/697051.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

婴儿摇篮音乐芯片 N9300-S16:为宝宝带来高品质的音乐体验

​对于父母来说&#xff0c;给婴儿提供一个安稳舒适的睡眠环境是至关重要的。宝宝的睡眠品质对于其健康和发展至关重要。在成长过程中&#xff0c;音乐对婴儿的情绪、认知和智力发展都有积极的影响。因此&#xff0c;厂家在婴儿摇篮中选择一款合适的婴儿摇篮音乐芯片尤为重要。…

共见·价值成就|亚马逊云科技中国峰会宣布三大举措全面升级

2023年6月27日&#xff0c;亚马逊云科技举办一年一度的中国合作伙伴峰会。本届峰会以“共见价值成就”为主题&#xff0c;面向合作伙伴发布智荟出海计划、可持续发展伙伴计划、合作伙伴解决方案工厂以及获客激励计划等多项计划&#xff0c;以进一步强化合作伙伴“33战略”&…

ASEMI代理ST可控硅BTA16的工作原理与应用分析

编辑-Z 本文将对可控硅BTA16的工作原理与应用进行详细的分析。首先&#xff0c;我们将介绍可控硅BTA16的基本概念和工作原理&#xff0c;然后&#xff0c;我们将探讨其在电力电子设备中的应用&#xff0c;接着&#xff0c;我们将分析其在电力调节中的作用&#xff0c;最后&…

edge自带断网游戏

在没有网络时你会不会很无聊&#xff1f;博主告诉你一个edge浏览器自带的断网小游戏&#xff0c;让你在断网时也能玩游戏&#xff01; 网址&#xff1a; 打开edge://surf这个断网游戏网站即可游玩&#xff1a; 作弊码既隐藏模式&#xff1a; 输入microsoft&#xff08;意思就…

C语言学习(二十八)---字符串相关函数

在上一节的内容结束后&#xff0c;有关指针的内容就告一段落了&#xff0c;指针是开发中非常重要的一环&#xff0c;大家务必要对其深入理解并且掌握&#xff0c;今天我们将继续往下学习&#xff0c;主要学习字符串操作相关的函数&#xff0c;分为不限制长度和限制长度两种&…

vetcor使用移动构造取代拷贝构造实现push_back

昨天说到&#xff1a;vector变量push_back一个对象或变量的时候&#xff0c;本质上是执行拷贝构造&#xff0c;但我想使用移动构造&#xff0c;而不是拷贝构造&#xff0c;本文就修改调试过程&#xff0c;详细分析如何实现移动构造。 昨天的代码如下&#xff1a;(如果有人想测…

Keil5 创建工程

一、 在桌面新建一个 TEST 的文件夹&#xff0c;然后在 TEST 文件夹里面新建 USER 文件夹&#xff0c;将工程名 字设为 test&#xff0c;保存在这个 USER 文件夹里面,选择对应芯片的安装包 启动代码作用&#xff1a; 1、堆栈&#xff08;SP&#xff09;的初始化&#xff1b; 2…

java.util.concurrent.Executionexception 异常

报错截图&#xff1a; 今天运行时发生了如下报错。自己捣鼓半天也没发现问题出在哪儿&#xff0c;感谢大佬的帮助&#xff0c;记录下来防止再犯。。 caused by org.apache.flink.client.program.programInvocationException: Job failed。程序调用异常。网上找了很多解决方法…

Qt 中线程池的使用

1. 线程池的原理 我们使用线程的时候就去创建一个线程&#xff0c;这样实现起来非常简便&#xff0c;但是就会有一个问题&#xff1a;如果并发的线程数量很多&#xff0c;并且每个线程都是执行一个时间很短的任务就结束了&#xff0c;这样频繁创建线程就会大大降低系统的效率&…

第14章-Python-人工智能-语言识别-调用百度语音识别

百度语音识别API是可以免费试用的&#xff0c;通过百度账号登录到百度智能云&#xff0c;在语音技术页面创建的应用&#xff0c;生成一个语音识别的应用&#xff0c;这个应用会给你一个APIKey和一个Secret Key&#xff0c;如图14.1所示。 我们在自己的程序中用 API Key 和 Secr…

轻松搞定 Git

目录 前言 一、下载 二、安装 三、基本使用 四、git的基本原理 五、通过案例学习git 5.1 创建空的项目文件夹 5.2 初始化git 5.3 创建项目文件 5.4 查看git状态 5.5 添加到暂存区 5.6 提交到本地仓库 5.7 查看git提交到本地仓库的记录 5.8 .gitignore文件 六、分…

mysql基础2——增、删、改、查

文章目录 一、DDL操作1.1 数据库操作1.2 表操作1.3 用户操作1.4 查看命令show1.5 获取帮助 二、DCL操作2.1 用户授权2.2 查看授权2.3 取消授权 三、DML操作3.1 插入insert3.2 查询select3.2.1 常规查询3.2.2 条件查询3.2.3 order by用法3.2.4 group by用法3.2.5 内连接&左连…

输入年月日,日期; 求这个日期在这一年中是第几天

输入年月日,日期; 求这个日期在这一年中是第几天 1.问题 输入年月日,日期; 求这个日期在这一年中是第几天 2.代码 利用Java中的库函数 LocalDate 是Java 8引入的一个日期类&#xff0c;用于表示日期&#xff0c;不包含时间和时区信息 到时候直接调用方法可以获取对应的天数 p…

javaee ajax请求后台 不刷新页面

jsp页面 Reg.jsp <% page language"java" contentType"text/html; charsetUTF-8"pageEncoding"UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd&qu…

【Python】经过一个点P3的一条直线垂直于已知直线,求交点坐标

一个高中数学题目&#xff0c;已经点P1和点P2构成直线&#xff0c;经过P3点做已知直线的垂线&#xff0c;求垂线与已知直线的交点坐标。 p1 [100, 15] p2 [16, 85] p3 [-50, 100] if p2[0] - p1[0] 0:# p1 p2 构成垂线&#xff0c;那么垂直线就是一条水平线x p1[0]y p3…

kafka3.x 入门 常用命令(二)

创建主题 kafka-topics.sh --bootstrap-server hadoop100:9092 --create --partitions 1 --replication-factor 3 --topic first查看主题列表 kafka-topics.sh --bootstrap-server hadoop100:9092 --list查看主题详情 kafka-topics.sh --bootstrap-server hadoop100:9092 --…

element-ui—textarea多行输入框—字数限制及优化

属性作用 show-word-limit &#xff1a;是否显示数字显示 maxlength“300”&#xff1a;设置最大值 class“public-showWordLimit”&#xff1a; 优化数字的显示的位置 :autosize “{ minRows: 2, maxRows: 8 }” &#xff1a;根据输入字符长度设置动态高度 2.代码案例 <…

vue3+vite安装配置element-plus

配置 element-plus 1. 安装 yarn add element-plus element-plus/icons-vue2. 按需引入插件 yarn add unplugin-vue-components unplugin-auto-import -D3. 配置vite.config.ts // vite.config.ts import AutoImport from unplugin-auto-import/vite import Components fro…

MySQL数据库的主从复制与读写分离

MySQL数据库的主从复制与读写分离 一、主从复制原理1、MySQL支持主从复制类型2、主从复制的原理3、主从复制的架构4、mysql主从复制延迟4、slave从服务器的配置5、验证主从复制的效果6、从服务器的故障问题解决1、遇到Slave_IO_Running:NO的情况2、遇到Slave_SQL_Running&#…

C++ - 哈希的应用

前面的文章中我们讲解了如何进行哈希表的构建以及使用实现的哈希表来模拟实现unordered_map&#xff0c;在本文中我们将继续来讲解一下哈希的应用。 位图 问题引入 首先我们来引入一个问题&#xff1a;给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&am…