gpt4 book ai didi

spring - 如何使用 spring boot 在 H2 控制台中设置默认的 JDBC URL 值

转载 作者:行者123 更新时间:2023-11-30 12:03:20 24 4
gpt4 key购买 nike

我已经在 spring boot 中启用了 H2 控制台。但是,当我打开控制台连接页面时,默认 url 是 H2 控制台历史记录中的那个。我如何配置项目以在项目启动时将 URL 填充为与 spring.datasource.url 相同?目前我在控制台中手动设置 url,但我希望它由项目本身自动设置。

亚姆:

spring:
h2:
console:
enabled: true
path: /admin/h2


datasource:
url: jdbc:h2:mem:foobar

更新:我知道最后的连接设置保存到 ~/.h2.server.properties 但我需要的是潜在地从启动应用程序设置属性,可能在其中几个之间切换

最佳答案

没有提供用于填写设置的 Hook 。

好消息是我们可以用一些代码来改变它。

当前状态

登录屏幕是在 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()在下面使用。

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;
}

计划

  • 禁用ServletRegistrationBean<WebServlet>创建者 H2ConsoleAutoConfiguration
  • 将其替换为我们的子类 WebServlet 的配置类
  • 我们的 CustomH2WebServlet将覆盖 init并注册 CustomH2WebServer (WebServer 的子类)
  • CustomH2WebServer我们覆盖 getSettings()我们完成了

代码

@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

除了需要通过反射设置一个私有(private)字段外,一切都进行得很顺利。

提供的代码适用于 H2 1.4.199

关于spring - 如何使用 spring boot 在 H2 控制台中设置默认的 JDBC URL 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57809925/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com