【问题标题】:H2 console error: No suitable driver found for 08001/0H2 控制台错误:找不到适合 08001/0 的驱动程序
【发布时间】:2017-02-12 17:31:25
【问题描述】:

您好,我在 H2 控制台数据库中查看我的架构时遇到问题:

我正在使用弹簧靴:

spring.datasource.initialize=true
spring.datasource.url=jdbc:h2:~/test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MV_STORE=FALSE;MVCC=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.h2.console.enabled=true

这是我的登录页面:

所以我在里面看到的是标准控制台视图,没有我的表格,但我的应用程序运行良好。

【问题讨论】:

  • 嗨@filemonczyk,你能解决这个问题吗?
  • tbh 我不记得解决方案了
  • 我建议使用直接连接到您的 H2 db right from your IDE...

标签: java spring spring-boot h2


【解决方案1】:

在 H2 控制台中使用整个字符串进行连接,即,您只会看到您的表格

jdbc:h2:~/test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MV_STORE=FALSE;MVCC=FALSE

【讨论】:

    【解决方案2】:

    就我而言,问题在于我实现了一个自定义过滤器(请参阅hereherehere),而自定义 HttpServletRequestWrapper 需要处理 H2 控制台登录请求,该请求附带表单数据(包括驱动类输入)并将其解析为参数:

    public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper {
    
    private String body;
    
    public MyHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
        this.body = IOUtils.toString(request.getReader());
        //...
    }
    
    @Override
    public Enumeration<String> getParameterNames() {
        if (!parsedParams)
            parseParams();
    
        List<String> result = Collections.list(super.getParameterNames());
        result.addAll(parameters.keySet());
    
        return Collections.enumeration(result);
    }
    
    private void parseParams() {
        if (!body.isEmpty()) {
            String[] rps = body.split("&");
    
            for (String rp : rps) {
                String[] kv = rp.split("=");
                try {
                    parameters.put(kv[0], kv.length > 1 ? new String[]{URLDecoder.decode(kv[1], "UTF-8")} : new String[]{""});
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
    
            parameters.setLocked(true);
            parsedParams = true;
        }
    }
    
    @Override
    public Map<String, String[]> getParameterMap() {
        if (!parsedParams)
            parseParams();
    
        Map<String, String[]> s = super.getParameterMap();
        return Stream.concat(parameters.entrySet().stream(), s.entrySet().stream()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    }
    
    @Override
    public String getParameter(String name) {
        return parameters.get(name) != null ? parameters.get(name)[0] : super.getParameter(name);
    }
    
    @Override
    public String[] getParameterValues(String name) {
        String[] s = super.getParameterValues(name);
        return ArrayUtils.addAll(s, parameters.get(name));
    }
    }
    

    【讨论】:

    • 有一个类似的问题,我想我找到了一个更简单(阅读更少的新代码行)的解决方法。在构造函数中调用处理参数的请求方法之一,例如getParameterNames 或 getParameter("anything")。出于某种原因,这在过滤器中不起作用。还没弄清楚为什么。
    • 同理,添加一个简单的记录器语句 logger.info(request.getParameterNames());成功了,理解其中的原理会很有趣
    • 确认:getParameterNames() 内部调用org.apache.catalina.connector.Request.parseParameters()。这做了很多编码和解析的事情。并且以某种方式初始化了一些......解决了问题:-)
    【解决方案3】:

    当我遇到这个问题时,我正在学习 Spring Boot 教程。在本教程中,我的 Spring Boot 大师在 application.properties 中使用了以下代码:

    spring.h2.console.enabled=true
    spring.datasource.platform=h2
    spring.datasource.url=jdbc:h2:mem:someName
    

    最后一行不是必须的,因为这些是spring boot的默认配置:

    spring.datasource.url=jdbc:h2:mem:testdb  
    spring.datasource.driverClassName=org.h2.Driver  
    spring.datasource.username=sa  
    spring.datasource.password=  
    spring.h2.console.enabled=false
    

    当我删除它时,一切都按预期工作。

    【讨论】:

      【解决方案4】:

      通常“测试连接”工作正常(登录表单后的绿线),但连接不工作。这可能是由处理标头引起的,这可能是由过滤器或安全配置引起的。比如我被这个打了两次:

      1. 我有同样的症状,问题是由使用日志记录引起的。 删除依赖项有助于在登录 h2-console 时摆脱No适合的驱动程序找到 08001/0 消息:

        <dependency>
            <groupId>org.zalando</groupId>
            <artifactId>logbook-spring-boot-starter</artifactId>
        </dependency>
        

      我不确定,是给定project 的错误,还是错误的用法/配置。

      1. 配置 OAuth2 对我也有影响。我需要从 web 和 http 安全中排除 h2-console uri。见一些info here。见sn-ps:

        @Configuration
        @EnableWebSecurity
        @EnableGlobalMethodSecurity(
                securedEnabled = true,
                jsr250Enabled = true,
                prePostEnabled = true
        )
        @RequiredArgsConstructor
        public class SecurityConfig extends WebSecurityConfigurerAdapter {
            @Override
            public void configure(WebSecurity web) {
                web.ignoring().antMatchers("/h2-console/**");
            }
            @Override
            protected void configure(HttpSecurity http) throws Exception {
                http
                        // only part of config is shown here...
                        .authorizeRequests()
                        .antMatchers("/",
                                "/error",
                                "/favicon.ico",
                                "/**/*.png",
                                "/**/*.gif",
                                "/**/*.svg",
                                "/**/*.jpg",
                                "/**/*.html",
                                "/**/*.css",
                                "/**/*.js",
                                "/h2-console/**")
                        .permitAll()
                        .antMatchers("/auth/**", "/oauth2/**").permitAll()
                        .anyRequest().authenticated()
                        .and()
                        .oauth2Login();
            }
        }
        

      【讨论】:

      • 亲爱的卢博,非常感谢!使用您的解决方案后,我也可以启动 h2-database 并且错误消失了。重要的是,真的不要像你说的那样使用依赖,并添加块:“@Override public void configure(WebSecurity web) { web.ignoring().antMatchers("/h2-console/**"); }"
      【解决方案5】:

      只是添加我在这里遇到的问题和解决方案,因为我没有找到任何明确的提及。

      我从 Spring Boot 2.1 更新到 2.2 时遇到了这个问题。 (测试时我发现即使从最新的 2.1.13.RELEASE 切换到 2.2.0.RELEASE 也会出现问题。)

      分析: 我们的应用程序同时使用 Jersey/JAX-RS 和 Spring Web。 要完成这项工作:

      • 在 Spring Boot 2.1 上,我们的应用程序将 Jersey 配置为使用 servlet 过滤器 使用 (spring.jersey.type=filter) 和 JerseyConfig 使用 ServletProperties.FILTER_FORWARD_ON_404 将无法处理的请求转发到 Spring Boot。 这似乎破坏了 Spring Boot 2.x 中的 h2-console

      • 对于 Spring Boot 2.2,我删除了“spring.jersey.type=filter”配置,因此 Jersey 使用 servlet。 为了使它与 Spring Web 配合得很好,我使用 @ApplicationPath("/api") 限制了 Jersey(我们所有的 JAX-RS 请求都以该前缀开头)

      【讨论】:

        【解决方案6】:

        在我看来,问题与日志如何处理表单请求有关。

        默认情况下,LogbookFilter 将处理带有 application/x-www-form-urlencoded 正文的请求,与任何其他请求没有区别,即您将在日志中看到请求正文。这种方法的缺点是您将无法使用任何 HttpServletRequest.getParameter*(..) 方法。有关更多详细信息,请参阅问题 #94。

        日志团队建议设置系统属性

        从 Logbook 1.5.0 开始,您现在可以使用 logbook.servlet.form-request 系统属性指定三种策略之一来定义 Logbook 如何处理这种情况:

        java -jar -Dlogbook.servlet.form-request=parameter server/target/server-1.0-SNAPSHOT.jar
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-11-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-08-27
          • 2012-07-07
          相关资源
          最近更新 更多