如何使用Spring Boot在H2控制台中设置默认的JDBC URL值 [英] How to set the default JDBC URL value in H2 console using spring boot
问题描述
我已在春季启动时启用了H2控制台.但是,当我打开控制台连接页面时,默认URL是保存在H2控制台历史记录中的URL.如何在项目开始时配置项目以将URL填充为与 spring.datasource.url 相同的URL?目前,我在控制台中手动设置了url,但我想由项目本身自动设置它.
I have enable the H2 console in spring boot. However, when I open the console connection page the default url is the one staved in the H2 console history. How can i configure the project to populate the URL to be the same as spring.datasource.url on project start? Currently I set the url in the console manually but I would like to have it setup automatically by the project itself.
yaml:
spring:
h2:
console:
enabled: true
path: /admin/h2
datasource:
url: jdbc:h2:mem:foobar
更新: 我知道最后的连接设置已保存到〜/.h2.server.properties,但是我需要从启动应用程序中设置属性,可能会在其中几个之间切换
update: I know that the last connection settings are saved to ~/.h2.server.properties but what I need is to set the properties from the starting application potentially, potentially switching between several of them
推荐答案
没有提供用于填充设置的挂钩.
There is no hook provided to fill in settings.
好消息是我们可以用一些代码来更改它.
The good news is that we can change that with a bit of code.
当前状态
在WebApp.index()
String[] settingNames = server.getSettingNames();
String setting = attributes.getProperty("setting");
if (setting == null && settingNames.length > 0) {
setting = settingNames[0];
}
String combobox = getComboBox(settingNames, setting);
session.put("settingsList", combobox);
ConnectionInfo info = server.getSetting(setting);
if (info == null) {
info = new ConnectionInfo();
}
session.put("setting", PageParser.escapeHtmlData(setting));
session.put("name", PageParser.escapeHtmlData(setting));
session.put("driver", PageParser.escapeHtmlData(info.driver));
session.put("url", PageParser.escapeHtmlData(info.url));
session.put("user", PageParser.escapeHtmlData(info.user));
return "index.jsp";
我们想点击server.getSettingNames()
,并精确点击下面使用的server.getSettings()
.
We want to tap into server.getSettingNames()
, and precisely into server.getSettings()
used underneath.
synchronized ArrayList<ConnectionInfo> getSettings() {
ArrayList<ConnectionInfo> settings = new ArrayList<>();
if (connInfoMap.size() == 0) {
Properties prop = loadProperties();
if (prop.size() == 0) {
for (String gen : GENERIC) {
ConnectionInfo info = new ConnectionInfo(gen);
settings.add(info);
updateSetting(info);
}
} else {
for (int i = 0;; i++) {
String data = prop.getProperty(Integer.toString(i));
if (data == null) {
break;
}
ConnectionInfo info = new ConnectionInfo(data);
settings.add(info);
updateSetting(info);
}
}
} else {
settings.addAll(connInfoMap.values());
}
Collections.sort(settings);
return settings;
}
计划
- 禁用
H2ConsoleAutoConfiguration
创建的ServletRegistrationBean<WebServlet>
- 将其替换为带有
WebServlet
子类的config类
- 我们的
CustomH2WebServlet
将覆盖init
并注册CustomH2WebServer
(WebServer
的子类) - 在
CustomH2WebServer
中,我们将覆盖getSettings()
,然后完成
- disable
ServletRegistrationBean<WebServlet>
created byH2ConsoleAutoConfiguration
- replace it with our config class with a subclass of
WebServlet
- our
CustomH2WebServlet
will overrideinit
and registerCustomH2WebServer
(subclass ofWebServer
) - in
CustomH2WebServer
we overridegetSettings()
and we are done
代码
@EnableConfigurationProperties({H2ConsoleProperties.class, DataSourceProperties.class})
@Configuration
public class H2Config {
private final H2ConsoleProperties h2ConsoleProperties;
private final DataSourceProperties dataSourceProperties;
public H2Config(H2ConsoleProperties h2ConsoleProperties, DataSourceProperties dataSourceProperties) {
this.h2ConsoleProperties = h2ConsoleProperties;
this.dataSourceProperties = dataSourceProperties;
}
@Bean
public ServletRegistrationBean<WebServlet> h2Console() {
String path = this.h2ConsoleProperties.getPath();
String urlMapping = path + (path.endsWith("/") ? "*" : "/*");
ServletRegistrationBean<WebServlet> registration = new ServletRegistrationBean<>(
new CustomH2WebServlet(this.dataSourceProperties.getUrl()), urlMapping);
H2ConsoleProperties.Settings settings = this.h2ConsoleProperties.getSettings();
if (settings.isTrace()) {
registration.addInitParameter("trace", "");
}
if (settings.isWebAllowOthers()) {
registration.addInitParameter("webAllowOthers", "");
}
return registration;
}
}
package org.h2.server.web;
import javax.servlet.ServletConfig;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Enumeration;
public class CustomH2WebServlet extends WebServlet {
private final String dbUrl;
public CustomH2WebServlet(String dbUrl) {
this.dbUrl = dbUrl;
}
@Override
public void init() {
ServletConfig config = getServletConfig();
Enumeration<?> en = config.getInitParameterNames();
ArrayList<String> list = new ArrayList<>();
while (en.hasMoreElements()) {
String name = en.nextElement().toString();
String value = config.getInitParameter(name);
if (!name.startsWith("-")) {
name = "-" + name;
}
list.add(name);
if (value.length() > 0) {
list.add(value);
}
}
String[] args = list.toArray(new String[0]);
WebServer server = new CustomH2WebServer(dbUrl);
server.setAllowChunked(false);
server.init(args);
setServerWithReflection(this, server);
}
private static void setServerWithReflection(final WebServlet classInstance, final WebServer newValue) {
try {
final Field field = WebServlet.class.getDeclaredField("server");
field.setAccessible(true);
field.set(classInstance, newValue);
}
catch (SecurityException|NoSuchFieldException|IllegalArgumentException|IllegalAccessException ex) {
throw new RuntimeException(ex);
}
}
}
package org.h2.server.web;
import java.util.ArrayList;
import java.util.Collections;
class CustomH2WebServer extends WebServer {
private final String connectionInfo;
CustomH2WebServer(String dbUrl) {
this.connectionInfo = "Test H2 (Embedded)|org.h2.Driver|" +dbUrl+"|sa";
}
synchronized ArrayList<ConnectionInfo> getSettings() {
ArrayList<ConnectionInfo> settings = new ArrayList<>();
ConnectionInfo info = new ConnectionInfo(connectionInfo);
settings.add(info);
updateSetting(info);
Collections.sort(settings);
return settings;
}
}
spring.h2.console.enabled=false
spring.datasource.url=jdbc:h2:mem:foobar
除了需要通过反射设置的一个私有字段之外,一切都变得很模糊.
Everything went smoolthly, except of one private field that needed to be set via reflection.
提供的代码适用于H2 1.4.199
The code provided works with H2 1.4.199
这篇关于如何使用Spring Boot在H2控制台中设置默认的JDBC URL值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!