宝兰德AppServer部署(SpringBoot4)
积木报表版本:示例工程
jimureport-example(SpringBoot 4.1.0,jimureport-spring-boot4-starter2.5.6)
JDK版本:17
宝兰德版本:BES Application Server Standard V11.0 SP5,安装介质
BES-APPSERVER-STANDARD-11.0-SP5-BN001.tar.gz
积木报表打成 war 包部署到宝兰德 BES AppServer(标准版),应用前缀为
/jimureport,部署后访问http://<服务器IP>:8080/jimureport/jmreport/list。
环境说明
| 项目 | 版本 |
|---|---|
| 操作系统 | TencentOS Server 3.3(x86_64) |
| JDK | OpenJDK 17.0.20 |
| BES AppServer | Standard V11.0(SP5 build 001.000),安装包自带试用授权 |
| 积木报表 | 示例工程 jimureport-example(SpringBoot 4.1.0):积木报表 2.5.6、积木BI 2.5.4、ChatBI 1.2.0 |
| 数据库 | MySQL 8.0.46(与 BES 部署在同一台服务器) |
SpringBoot 4 要求容器支持 Jakarta Servlet 6.1,BES 11.0 SP5 自带的
lib/jakartaee.jar已提供 Servlet 6.1 API。
一、BES AppServer 安装
服务器上已经装好 BES 的,跳过本节,直接看「二、积木报表打 war 包」。
1、上传并解压
将 BES-APPSERVER-STANDARD-11.0-SP5-BN001.tar.gz 上传到服务器(本文为 /root),创建安装目录后解压:
# 本地执行:上传安装包到服务器 /root
scp BES-APPSERVER-STANDARD-11.0-SP5-BN001.tar.gz root@<服务器IP>:/root/
# 服务器执行:创建安装目录并解压
cd /root
mkdir -p /opt/bes
tar -xzf BES-APPSERVER-STANDARD-11.0-SP5-BN001.tar.gz -C /opt/bes
该 tar.gz 没有顶层目录(第一层就是
bin/、conf/、lib/等),务必先创建安装目录再用-C指定解压位置,否则这些目录会散落到当前目录中。

2、指定 JDK
在 bin/env.properties 中指定 JDK17:
cd /opt/bes/bin
sed -i '$a JAVA_HOME=/usr/lib/jvm/java-17-openjdk' env.properties
cat env.properties

env.properties的最后一行没有换行符,直接用echo ... >> env.properties追加会和上一行ADMIN_PORT=1900拼在一起,JAVA_HOME 不生效。请用上面的sed '$a'追加,或者用vi编辑。JAVA_HOME按服务器上 JDK17 的实际路径填写。
3、启动 BES
startserver 在前台运行,退出终端就会停止,需要用 nohup 放到后台:
cd /opt/bes/bin
nohup ./startserver > /opt/bes/logs/startserver.out 2>&1 &
tail -f /opt/bes/logs/startserver.out
看到 Server startup in [xxxx] milliseconds 即启动完成:

停止 BES:
cd /opt/bes/bin && ./stopserver
4、确认端口
ss -tlnp | grep -E ':1900|:8080'
| 端口 | 说明 |
|---|---|
| 1900 | 管理控制台(HTTPS) |
| 8080 | 应用 HTTP 端口(http-listener-1),积木报表通过这个端口访问 |

5、登录管理控制台
地址:https://<服务器IP>:1900/console
用户名:admin
默认密码:B#2008_2108#es(首次登录强制修改)
控制台端口 1900 是 HTTPS,必须用
https://访问,用http://访问会被直接断开(浏览器报ERR_CONNECTION_CLOSED)。
控制台默认开启 Host 头校验,用公网 IP 访问会返回 HTTP 400。推荐用 SSH 隧道访问:在本地执行
ssh -L 1900:127.0.0.1:1900 root@<服务器公网IP>并保持窗口不关闭,然后浏览器访问https://127.0.0.1:1900/console(自签名证书点「高级 → 继续前往」)。必须用公网 IP 直接访问的,见文末附录。

首次登录会提示「检测到您的密码仍是默认密码,请先修改密码」,修改后用新密码重新登录:

登录后进入「实例总览」,可以看到版本号、HTTP 端口、JAVA HOME 和授权信息:

二、积木报表打 war 包
1、下载示例工程
git clone https://github.com/jeecgboot/JimuReport.git
# 国内访问慢可以用 Gitee:git clone https://gitee.com/jeecg/JimuReport.git
cd JimuReport/jimureport-example
本文使用 SpringBoot4 版示例工程(
pom.xml的 parent 为spring-boot-starter-parent4.1.0,依赖jimureport-spring-boot4-starter)。积木报表集成在自己项目里的,按下面同样的思路改造自己的项目即可。
2、修改pom.xml
打包格式由 jar 改为 war(加在 <version> 下面):
<artifactId>jimureport-example</artifactId>
<version>2.5</version>
<!-- 由 jar 改为 war -->
<packaging>war</packaging>
<build> 中指定 war 包名为 jimureport,并注释掉 spring-boot-maven-plugin(war 部署到外部容器,不需要打成可执行包):
<build>
<!-- war 包名,BES 部署时默认用它作为应用名称和应用前缀 -->
<finalName>jimureport</finalName>
<plugins>
<!-- SpringBoot启动 -->
<!--<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>-->
</plugins>
</build>
内嵌 Tomcat(
spring-boot-starter-tomcat,由spring-boot-starter-webmvc传递引入)保持默认 scope,不需要改成provided:war 部署时内嵌 Tomcat 不会启动,本文按默认 scope 实测通过。
3、修改启动类
JimuReportApplication 继承 SpringBootServletInitializer,BES 通过它拉起 Spring,不需要额外添加 web.xml:
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication(scanBasePackages = {"org.jeecg", "com.jeecg"})
public class JimuReportApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(JimuReportApplication.class);
}
// main 方法保持不变
}
war 部署时不会执行
main方法,控制台不会打印「JimuReport 积木报表平台 is running!」提示块,启动情况以日志为准(见「五、1」)。
4、登录页适配应用前缀
示例工程自带的登录页是按根路径写的,部署到 /jimureport 这类应用前缀下时需要改下面 3 处。不改的话,未登录时会跳到服务器根路径的 /login/login.html(根路径下的其他应用或 404),登录成功后又会跳到 /jimureport/jimureport/jmreport/list 导致 404。
① src/main/resources/static/login/login.html,表单提交地址和口令检查接口改为相对路径:
<!-- 原来是 action="/doLogin" -->
<form class="form-signin" method="get" action="../doLogin">
// 原来是 fetch('/isDefaultCredentials')
fetch('../isDefaultCredentials')
② src/main/java/com/jeecg/modules/jmreport/extend/JimuReportTokenServiceImpl.java,verifyToken 方法中跳转登录页的两行改为带上应用前缀:
// 原来是:
// String redirect = URLEncoder.encode(request.getRequestURI(), StandardCharsets.UTF_8);
// JimuSpringContextUtils.getHttpServletResponse().sendRedirect("/login/login.html?redirect=" + redirect);
String contextPath = request.getContextPath();
String redirect = URLEncoder.encode(request.getRequestURI().substring(contextPath.length()), StandardCharsets.UTF_8);
JimuSpringContextUtils.getHttpServletResponse().sendRedirect(contextPath + "/login/login.html?redirect=" + redirect);
部署时应用前缀填
/(部署在根路径)的,可以不改这 3 处。
5、修改配置文件
示例工程默认激活 dev 配置(见 application.yml 中的 spring.profiles.active),修改 src/main/resources/application-dev.yml:
spring:
datasource:
url: jdbc:mysql://${MYSQL-HOST:127.0.0.1}:${MYSQL-PORT:3306}/${MYSQL-DB:jimureport}?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
username: root
password: <数据库密码>
security:
user:
name: "${JIMU_ADMIN_USER:admin}"
# 登录口令,必须配置
password: "${JIMU_ADMIN_PASSWORD:<登录口令>}"
jeecg:
path:
# 上传文件的存放目录
upload: /opt/upload
jmreport:
# 自定义API接口的前缀 #{api_base_path}和#{domainURL}的值,改为部署后的访问地址
apiBasePath: http://<服务器IP>:8080/jimureport
登录口令必须配置。 口令留空或为
123456时,每次启动都会随机生成一个口令。war 部署时没有启动提示块,随机口令只能到日志里找(见附录)。
war 部署时
server.port、server.servlet.context-path不生效:访问端口由 BES 的 HTTP 监听器决定(8080),访问前缀由部署时填写的「应用前缀」决定。
示例工程已配置
spring.data.redis.listener.auto-startup: false,没有 Redis 也能正常启动(本文服务器上没有运行 Redis)。
正式上线前,参考《集成积木权限》中的「上线配置」调整
jeecg.jmreport.firewall等安全配置,并替换示例中的signatureSecret。
6、执行打包
在 jimureport-example 目录执行:
mvn clean package -DskipTests
产物:target/jimureport.war(约 290MB)。
三、初始化数据库
将示例工程中的初始化脚本 db/jimureport.mysql5.7.create.sql 上传到服务器并导入,脚本会自动创建 jimureport 库:
# 本地执行:上传脚本到服务器 /root
scp db/jimureport.mysql5.7.create.sql root@<服务器IP>:/root/
# 服务器执行(在 /root 目录下)
cd /root
mysql -uroot -p < jimureport.mysql5.7.create.sql
导入后执行下面的命令检查,jimureport 库中应有 58 张表:
mysql -uroot -p -e "show databases like 'jimureport'; select count(*) as table_count from information_schema.tables where table_schema='jimureport';"

脚本会先
DROP TABLE再建表,库中已有积木报表数据的,导入前先备份。
本文 MySQL 配置了
lower_case_table_names=1,与示例工程docker-compose.yml中的 MySQL 配置一致。
四、部署到 BES
1、上传 war 到服务器
# 服务器执行:创建存放目录
mkdir -p /data/deployFile
# 本地执行:上传 war
scp target/jimureport.war root@<服务器IP>:/data/deployFile/
war 约 290MB,通过控制台在浏览器中上传容易超时。建议先用 scp/SFTP 上传到服务器,部署时在控制台直接选择服务器上的文件。
2、部署应用
-
进入「应用管理 → 常用应用」,点击「部署」

-
部署类型选「部署为应用」。文件浏览器默认打开
/opt/bes/upload,点 3 次「返回上一级」回到根目录,依次进入data→deployFile,选中jimureport.war,点击「下一步」
-
应用名称
jimureport、应用前缀/jimureport默认取自文件名,类加载顺序保持默认的「子优先」
-
页面下拉到「支持组件」,勾选 JSONP,其余保持默认,点击「保存」

必须勾选 JSONP。 BES 是完整的 Jakarta EE 容器,会向应用暴露 JSON-B API;积木报表依赖的 Spring Data Redis(SpringBoot 4)启动时检测到 JSON-B,会创建
JsonbMessageConverter并查找 JSON-P 实现。不勾选 JSONP 时找不到实现,应用启动失败,报错Provider org.glassfish.json.JsonProviderImpl not found。这个报错与是否配置了 Redis 无关,完整报错见附录。支持组件只能在部署时设置。
- 十几秒后部署完成,「常用应用」列表中
jimureport的部署状态为「已启动」
五、访问积木报表
1、命令行验证
积木报表运行在 BES 的 HTTP 端口 8080,应用前缀为 /jimureport。先在服务器本机验证:
# 未登录访问报表工作台,应返回 302 并跳转到 /jimureport/login/login.html
curl -s -o /dev/null -w "%{http_code} %{redirect_url}\n" http://127.0.0.1:8080/jimureport/jmreport/list
# 登录页,应返回 200
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/jimureport/login/login.html
# 启动日志
grep "Started JimuReportApplication" /opt/bes/logs/jimureport-*.log

积木报表的日志写在
/opt/bes/logs/jimureport-日期.0.log:示例工程logback-spring.xml中的日志目录是../logs,相对的是 BES 的工作目录/opt/bes/bin。日志同时也会输出到 BES 的/opt/bes/logs/server.log。
2、浏览器访问
要从公网访问,需在云服务器安全组入站规则中放行 TCP:8080(来源建议限定为你的公网 IP)。不想对公网开放的,也可以用 SSH 隧道:ssh -L 8080:127.0.0.1:8080 root@<服务器公网IP>,然后把下面地址中的 <服务器IP> 换成 127.0.0.1。
-
访问报表工作台
http://<服务器IP>:8080/jimureport/jmreport/list,未登录会跳到登录页,输入账号admin和「二、5」中配置的登录口令
-
登录后进入报表工作台

-
修改示例数据源的密码。初始化脚本中内置了「积木库」「本地积木库」「填报数据源」3 个数据源,都指向
127.0.0.1:3306/jimureport,账号root,密码是示例环境的密码。数据库密码不同的,进入「系统配置 → 数据源维护」,逐个点击「编辑」,填写实际的数据库密码,「测试连接」成功后点击「确定」
不改的话,引用这些数据源的示例报表预览时页面空白,日志报
Access denied for user 'root'@'localhost'。
-
预览报表,例如示例模板「简单条件查询报表」(使用「积木库」数据源):
http://<服务器IP>:8080/jimureport/jmreport/view/1338744112815411200,数据正常显示,导出 Excel、PDF、Word 正常
-
点击右上角「进入BI工作台」,或访问
http://<服务器IP>:8080/jimureport/drag/list,进入 BI 工作台,大屏、仪表盘可正常预览

至此积木报表部署到宝兰德 BES AppServer 完成。
附录:常见问题
启动失败:Provider org.glassfish.json.JsonProviderImpl not found
现象:「常用应用」中 jimureport 的部署状态为「启动失败」:

/opt/bes/logs/server.log 中报错:
ERROR org.springframework.boot.SpringApplication - Application run failed
jakarta.json.JsonException: Provider org.glassfish.json.JsonProviderImpl not found
at jakarta.json.spi.JsonProvider.provider(JsonProvider.java:60)
at com.bes.johnzon.jsonb.JohnzonBuilder.build(JohnzonBuilder.java:131)
at jakarta.json.bind.JsonbBuilder.create(JsonbBuilder.java:69)
at org.springframework.messaging.converter.JsonbMessageConverter.<init>(JsonbMessageConverter.java:49)
at org.springframework.data.redis.serializer.DefaultRedisMessageConverters$DefaultBuilder.getDefaultConverters(DefaultRedisMessageConverters.java:153)
at org.springframework.data.redis.serializer.DefaultRedisMessageConverters$DefaultBuilder.build(DefaultRedisMessageConverters.java:131)
at org.springframework.data.redis.config.RedisListenerEndpointRegistrar.apply(RedisListenerEndpointRegistrar.java:229)
at org.springframework.data.redis.annotation.RedisListenerAnnotationBeanPostProcessor.afterSingletonsInstantiated(RedisListenerAnnotationBeanPostProcessor.java:149)
...
Caused by: java.lang.ClassNotFoundException: org.glassfish.json.JsonProviderImpl
原因:部署时「支持组件」没有勾选 JSONP。
解决:支持组件只能在部署时设置。在「常用应用」中勾选该应用,点击「解部署」,再按「四、2」重新部署,在「支持组件」中勾选 JSONP。
未登录时跳到了其他系统,或登录后 404
现象:访问 /jimureport/jmreport/list 被跳到 http://<服务器IP>:8080/login/login.html(根路径下的其他应用或 404),或者登录后地址变成 /jimureport/jimureport/jmreport/list 并返回 404。
原因:示例工程的登录页按根路径编写,部署到应用前缀下时没有修改。
解决:按「二、4」修改 3 处后重新打包、部署。
不知道登录口令
原因:没有配置 spring.security.user.password(或配置的是 123456),每次启动都会随机生成口令。
解决:在日志中查看本次启动的口令:
grep "登录口令" /opt/bes/logs/jimureport-*.log
建议按「二、5」配置固定口令后重新打包部署。
浏览器访问控制台返回 400
原因:控制台默认开启 Host 头校验,Host 头为公网 IP 时被拒绝。
解决:推荐使用 SSH 隧道访问(见「一、5」),无需修改配置。必须用公网 IP 直接访问的,先在安全组放行 TCP:1900,再给控制台关闭 Host 头校验。先备份控制台的 web.xml:
cp /opt/bes/lib/system/apps/console/WEB-INF/web.xml /opt/bes/lib/system/apps/console/WEB-INF/web.xml.bak
执行 vi /opt/bes/lib/system/apps/console/WEB-INF/web.xml,在 SecurityFilter 的 </filter-mapping> 之后插入:
<filter>
<filter-name>hostHeaderPreventionFilter</filter-name>
<filter-class>com.bes.enterprise.console.filter.HostHeaderPreventionFilter</filter-class>
<init-param>
<param-name>isCheckHost</param-name>
<param-value>false</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hostHeaderPreventionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
重启 BES 生效:
cd /opt/bes/bin && ./stopserver && nohup ./startserver > /opt/bes/logs/startserver.out 2>&1 &
关闭 Host 头校验会降低控制台安全性,安全组中 1900 端口的来源要限定为自己的 IP。
控制台上传 war 超时
原因:war 约 290MB,浏览器上传容易超时。
解决:先用 scp/SFTP 上传到服务器(如 /data/deployFile),部署时在文件浏览器中直接选择。
部署时报 OutOfMemoryError: Java heap space
原因:BES 默认堆为 -Xmx2048m,同一个 BES 中部署了多个应用时可能不够(本文环境与其他应用共用 BES,设置的是 -Xmx3072m)。
解决:先确认服务器可用内存足够,再编辑 conf/server.config 中 <java-config> 的 -Xmx 并重启 BES:
sed -i 's/-Xmx2048m/-Xmx3072m/' /opt/bes/conf/server.config
cd /opt/bes/bin && ./stopserver && nohup ./startserver > /opt/bes/logs/startserver.out 2>&1 &
部署失败后,BES 会回滚该应用的部署项,重启后不会自动拉起,需要在控制台重新「部署」一次。