当前位置: 首页 > news >正文

宝塔做网站安全吗做网站龙华

宝塔做网站安全吗,做网站龙华,淘金企业网站建设服务,常州seo本篇是关于把springboot生成的jar打到electron里,在生成的桌面程序启动时springboot服务就会自动启动。 虽然之后并不需要这种方案,更好的是部署[一套服务端,多个客户端]...但是既然搭建成功了,也记录一下。 前端文件 1、main.js…

本篇是关于把springboot生成的jar打到electron里,在生成的桌面程序启动时springboot服务就会自动启动。

虽然之后并不需要这种方案,更好的是部署[一套服务端,多个客户端]...但是既然搭建成功了,也记录一下。

前端文件

1、main.js

const { app, BrowserWindow, ipcMain, Notification, Menu,dialog} = require('electron/main')
const path = require('node:path')
const childProcess = require('child_process');
const fs = require('fs')let win = null;       // Electron主窗口实例
let backendProcess = null;   // Java子进程实例
const BACKEND_PORT = 8080;   // 后端固定端口(可配置)
const JAR_FILENAME = 'helloworld-0.0.1-SNAPSHOT.jar'; // JAR文件名(需与resources目录下的文件一致)function writeFile(_, data) {fs.writeFileSync('D:/hello.txt', data)
}function readFile() {const res = fs.readFileSync('D:/hello.txt').toString();return res
}/*** 获取JAR包路径(兼容开发/生产环境)*/
function getJarPath() {if (app.isPackaged) {// 生产环境:打包后,资源目录为process.resourcesPathreturn path.join(process.resourcesPath, 'resources', JAR_FILENAME);} else {// 开发环境:资源目录为项目根目录的`resources`文件夹return path.join(__dirname, 'resources', JAR_FILENAME);}
}/*** 4. 启动Java子进程(核心逻辑)*/
function startBackend() {const jarPath = getJarPath();// 检查JAR包是否存在(避免启动失败)if (!fs.existsSync(jarPath)) {dialog.showErrorBox('错误', `JAR包不存在:${jarPath}`);app.quit();return;}// 构造Java启动参数(可添加Spring Boot配置,如端口、环境)const args = ['-jar',jarPath,`--server.port=${BACKEND_PORT}`,          // 指定后端端口(避免冲突)`--spring.profiles.active=prod`           // 指定生产环境配置(可选)];// 构造子进程选项(跨平台优化)const options = {windowsHide: true,  // Windows下隐藏命令行窗口(避免弹出黑框)env: { ...process.env }, // 传递环境变量cwd: path.dirname(jarPath) // 设置子进程工作目录(避免相对路径问题)};// 启动子进程(使用spawn,适合长时间运行的进程)backendProcess = childProcess.spawn('java', args, options);// 5. 监听后端输出(调试用)backendProcess.stdout.on('data', (data) => {console.log('[Backend]', data.toString().trim());});// 6. 监听后端错误(如Java未安装、端口冲突)backendProcess.stderr.on('data', (data) => {const errorMsg = data.toString().trim();console.error('[Backend Error]', errorMsg);// 处理端口冲突(示例)if (errorMsg.includes(`Port ${BACKEND_PORT} is already in use`)) {dialog.showErrorBox('错误', `后端端口${BACKEND_PORT}已被占用,请关闭占用程序后重试。`);app.quit();}});// 7. 后端退出事件(如异常崩溃)backendProcess.on('exit', (code) => {console.log('[Backend]', `进程退出,代码:${code}`);backendProcess = null;// 若后端异常退出,关闭Electron应用if (code !== 0 && app.isReady()) {dialog.showErrorBox('错误', '后端进程异常退出,请重启应用。');app.quit();}});
}function createWindow() {const win = new BrowserWindow({width: 1000,height: 800,title: '简单网页',webPreferences: {preload: path.join(__dirname, 'preload.js')}})ipcMain.on('file-save', writeFile)ipcMain.handle('file-read', readFile)// 加载前端页面(兼容开发/生产环境)if (app.isPackaged) {console.log('pro')} else {console.log('dev')}//自定义菜单项let menuTemp = [{label: '文件',submenu: [{label: '打开文件',click() {console.log('打开一个具体的文件')}},{ label: '打开文件夹' },{label: '关于',role: 'about'}]},{ label: '编辑' }]//生成自定义菜单let menu = Menu.buildFromTemplate(menuTemp)Menu.setApplicationMenu(menu)win.loadFile('index.html')// 创建并显示通知const notification = new Notification({title: '主进程通知',body: '恭喜你,学会了求雨之术,风来~雨来~'}).show();// 确保在窗口创建后调用 openDevToolswin.webContents.on('did-finish-load', () => {win.webContents.openDevTools();});// 定时发送时间给渲染进程(每1秒)setInterval(() => {if (win && !win.isDestroyed()) {win.webContents.send('main-time', new Date().toLocaleTimeString());}}, 1000);
}
app.whenReady().then(() => {startBackend();       // 启动后端(先启动后端,再创建窗口)createWindow();   // 创建主窗口})// 应用退出前确保后端进程终止
app.on('will-quit', () => {if (backendProcess) backendProcess.kill();
}); 

2、index.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="Content-Security-Policy" content="default-src 'self'; connect-src 'self' http://localhost:8080;">
<link rel="stylesheet" href="styles.css">
</head><body><div id="time">当前时间:加载中...</div><div class="hint">注意:输入内容,可以保存到d:/hello.txt,点击读取,可以读取该文件内容</div><input id="input" type="text"><button id="btn2">向D盘输入hello.txt</button><br><br><hr><button id="btn3">读取D盘hello.txt</button><br><br><hr><button id="sendRequest">点击发送请求</button><div id="result"></div><script type="text/javascript" src="./render.js"></script>
</body></html>

3、render.js

const timeElement = document.getElementById('time');
const btn2 = document.getElementById('btn2');
const btn3 = document.getElementById('btn3');
const btn4 = document.getElementById('sendRequest');
const resultDiv = document.getElementById('result');
const input = document.getElementById('input');btn2.onclick = () => {myAPI.saveFile(input.value)
}btn3.onclick = async () => {let data = await myAPI.readFile()alert(data)
}// 定义常量
const API_URL = 'http://localhost:8080/getcode';
const METHOD = 'GET';// 绑定按钮点击事件
btn4.onclick = async () => {try {// 发送 GET 请求const response = await fetch(API_URL, { method: METHOD });// 检查响应状态if (!response.ok) {throw new Error(`HTTP error! status: ${response.status}`);}// 解析字符串数据const data = await response.text(); // 使用 text() 方法解析字符串// 将数据回显到页面上resultDiv.innerHTML = `<p class="success">请求成功!<br>返回数据:</p><pre>${data}</pre>`;} catch (error) {resultDiv.innerHTML = `<p class="error">请求失败,请检查网络或后端服务是否正常运行!</p>`;}
};// 监听主进程发送的时间消息
myAPI.onMainTime((time) => {timeElement.textContent = `当前时间:${time}`;
});

4、preload.js

const { contextBridge, ipcRenderer } = require('electron')contextBridge.exposeInMainWorld('myAPI', {saveFile: (data) => {ipcRenderer.send('file-save', data)},readFile: () => {return ipcRenderer.invoke('file-read')},// 监听主进程发送的时间消息onMainTime: (callback) => {ipcRenderer.on('main-time', (event, time) => callback(time))}
})

5、package.json

  "scripts": {"start": "electron .","build": "electron-builder --win --x64","package": "electron-packager . construction --win --out build --arch=x64 --version1.0.0 --overwrite --icon=static/images/128.ico","make": "electron-forge make"},"build": {"appId": "com.xiaoyumao.demo","extraResources": {"from": "resources/helloworld-0.0.1-SNAPSHOT.jar","to": "resources/helloworld-0.0.1-SNAPSHOT.jar"},"win": {"target": [{"target": "nsis","arch": ["x64"]}]},"nsis": {"oneClick": false,"perMachine": true,"allowToChangeInstallationDirectory": true}},

Electron中集成jar

1、先得有jar包

使用springboot技术,快速生成一个web应用。写一个getcode接口,

    @GetMapping("/getcode")public String getcode(){UUID randomUUID = UUID.randomUUID();String uuidWithoutHyphens = randomUUID.toString().replace("-", "");return "随机编码:"+uuidWithoutHyphens;}

在浏览器测试的访问一下

没啥问题后,用maven进行打包,生成可以独立运行的jar


2、child_process启动jar

由Electron主进程(Node环境)创建的独立进程,来启动jar

child_process.spawn()

用于创建一个子进程并实时监听其输入和输出。

java -jar C:\Users\lenovo\electron-basics\resources\helloworld-0.0.1-SNAPSHOT.jar --server.port=8080

3、resource目录

还需要在package.json配置extraResources ,用于在构建 Electron 应用程序时将额外的资源文件打包到最终的应用程序安装包中。它的主要作用是确保应用程序所需的资源文件能够正确地随应用一起发布,而不会丢失。

    "extraResources": {"from": "resources/helloworld-0.0.1-SNAPSHOT.jar","to": "resources/helloworld-0.0.1-SNAPSHOT.jar"},

在 Electron 中,process.resourcesPath 指向的是应用程序的资源目录。

    if (app.isPackaged) {// 生产环境:打包后,资源目录为process.resourcesPathreturn path.join(process.resourcesPath, 'resources', JAR_FILENAME);} 

在这里资源文件都放在了electron本身生成的resources目录中


4、假如没有JAVA_HOME环境

有些情况就是,电脑它没有javahome环境,或者有但是配置的不是我们想要的jdk1.8。。

所以我决定打包的时候把jre环境也打进去,jar启动原理就是下面这样的

C:\Users\lenovo\electron-basics\resources\jre\bin\java -jar C:\Users\lenovo\electron-basics\resources\helloworld-0.0.1-SNAPSHOT.jar --server.port=8080

在resource目录下把jre环境放进去。

package.json就得改变了

    "extraResources": [{"from": "resources/jre","to": "resources/jre"},{"from": "resources/helloworld-0.0.1-SNAPSHOT.jar","to": "resources/helloworld-0.0.1-SNAPSHOT.jar"}],

在main.js中,关于启动jar包的命令、对java环境的检查等都要用xxx\jre\bin\java去检查

在安装软件后,目录是这样的

现在就算没有JAVA_HOME,也照样可以运行


JSP应用

如果项目之前是用jsp写的,那么能不能啥都不改的情况下,直接访问l

http://www.dtcms.com/a/566487.html

相关文章:

  • safetensors转为gguf,并在ollama中部署
  • 做二手车按揭的网站艺术培训机构
  • 如何给网站做右侧导航互联网网络推广公司
  • 公司网站优化推广宁波企业名称查询网站
  • 做淘宝客网站服务器高新网站建设
  • Mysql 读书笔记
  • 网上做任务佣金高的网站wordpress付费浏览
  • Flutter---卡片交换器
  • MAC-SQL 算法一
  • 大连爱得科技网站建设公司怎么样在线设计平台都有哪些比较好用的
  • 【2051】【例3.1】偶数
  • 北京网站开发外包做网站看什么书
  • 怎么做网站推广临沂世界网站
  • C# 使用XML文件保存配方数据
  • 小说网站自主建设网站域名申请
  • 西安谁家的集团门户网站建设比较好上海公司车牌
  • Spring配置数据源
  • Product Hunt 每日热榜 | 2025-11-02
  • 基于图像的三维重建
  • 越秀区做网站河南网站建设价格与方案
  • 什么网站的新闻做参考文献中信建设有限责任公司属于央企吗
  • 硬件工程师-基础知识(一)
  • 都匀经济开发区建设局网站无锡电子商务网站制作
  • html5 input[type=date]如何让日期中的年/月/日改成英文
  • 嘉兴城乡建设局网站株洲seo优化哪家好
  • 【开题答辩全过程】以 法律类教辅平台为例,包含答辩的问题和答案
  • 商务网站建设哪家好免费聊天不充值软件
  • 网站 用cms 侵权免费的网站域名查询565wcc
  • 群晖 NAS 办公套件:用Synology Calendar 高效管理日程与任务
  • 屋领网站固链北京市小程序开发