如何在不使用Spring Boot的情况下在spring-webmvc中启用h2-console?

huangapple go评论78阅读模式
英文:

How to enable h2-console in spring-webmvc without spring-boot?

问题

我的应用程序使用spring-webmvcspring-jdbc构建,但没有使用spring-boot。在我的application.properties中,我有以下配置:

spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

datasource.dbname=users
datasource.script=classpath:resources/users.sql

但是它无法启动h2-console,因为我没有添加spring-boot-devtools,但我是否需要它呢?所以我从org.h2.tools包中添加了一个Server bean,如下所示:

// The web server is a simple standalone HTTP server that
// implements the H2 Console application.  localhost:8082
@Bean(initMethod = "start", destroyMethod = "stop")
public Server h2Server() throws SQLException {
    return Server.createWebServer();
}

现在我可以通过localhost:8082访问Web控制台并连接到jdbc:h2:mem:users,但我认为这不是一个解决方案,而是一种变通方法,因为我使用EmbeddedDatabaseBuilder添加了DataSource bean,如下所示:

@Bean
public DataSource dataSource(
        @Value("${datasource.dbname}") String dbname,
        @Value("${datasource.script}") String script) {

    return new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.H2)
            .setName(dbname)
            .addScript(script)
            .build();
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
    return new JdbcTemplate(dataSource);
}

是否有一种spring方式在没有spring-boot的情况下启用spring-webmvc中的h2-console?还是这是启用它的正常方式?

pom.xml:

<!-- spring -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.9.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.9.RELEASE</version>
</dependency>

<!-- h2 database -->
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.200</version>
</dependency>

<!-- servlet-api -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>
英文:

My application is build with spring-webmvc and spring-jdbc without spring-boot. In my application.properties I have:

spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

datasource.dbname=users
datasource.script=classpath:resources/users.sql

But it does not start h2-console because I don't have spring-boot-devtools, but do I need it? So I added Server bean from org.h2.tools package like this:

// The web server is a simple standalone HTTP server that
// implements the H2 Console application.  localhost:8082
@Bean(initMethod = &quot;start&quot;, destroyMethod = &quot;stop&quot;)
public Server h2Server() throws SQLException {
    return Server.createWebServer();
}

And now I can access web-console at localhost:8082 and connect to jdbc:h2:mem:users, but I think this is not a solution, but a workaround, because I added the DataSource bean using the EmbeddedDatabaseBuilder like this:

@Bean
public DataSource dataSource(
        @Value(&quot;${datasource.dbname}&quot;) String dbname,
        @Value(&quot;${datasource.script}&quot;) String script) {

    return new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.H2)
            .setName(dbname)
            .addScript(script)
            .build();
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
    return new JdbcTemplate(dataSource);
}

Is there a spring way to enable h2-console in spring-webmvc without spring-boot? Or is this the normal way to enable it?

pom.xml:

&lt;!-- spring --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework&lt;/groupId&gt;
    &lt;artifactId&gt;spring-webmvc&lt;/artifactId&gt;
    &lt;version&gt;5.2.9.RELEASE&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework&lt;/groupId&gt;
    &lt;artifactId&gt;spring-jdbc&lt;/artifactId&gt;
    &lt;version&gt;5.2.9.RELEASE&lt;/version&gt;
&lt;/dependency&gt;

&lt;!-- h2 database --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;com.h2database&lt;/groupId&gt;
    &lt;artifactId&gt;h2&lt;/artifactId&gt;
    &lt;version&gt;1.4.200&lt;/version&gt;
&lt;/dependency&gt;

&lt;!-- servlet-api --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;javax.servlet&lt;/groupId&gt;
    &lt;artifactId&gt;javax.servlet-api&lt;/artifactId&gt;
    &lt;version&gt;4.0.1&lt;/version&gt;
&lt;/dependency&gt;

答案1

得分: 1

看起来您需要将org.h2.server.web.WebServlet注册到您的Servlet映射中。

根据WebServlet的注释:

此Servlet允许在诸如Tomcat或Jetty之类的标准Servlet容器中使用H2控制台。

另请参阅:

英文:

It appears you need to register a org.h2.server.web.WebServlet to your servlet mapping.

From the comments at WebServlet:

> This servlet lets the H2 Console be used in a standard servlet
> container such as Tomcat or Jetty.

See also:

答案2

得分: 1

Spring Boot负责处理h2-console的servlet注册,但是使用普通的Spring(非Spring Boot)也很容易解决,可以使用任何实现了'WebApplicationInitializer'接口的类,例如'AbstractSecurityWebApplicationInitializer'。例如,在Servlet 3.0+环境中(无需web.xml)添加分发器servlet和h2-console:

public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {

    @Override
    protected void beforeSpringSecurityFilterChain(ServletContext container) {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(AppConfig.class, SecurityConfig.class, WebConfig.class);
        context.setServletContext(container);
        ServletRegistration.Dynamic servlet = container.addServlet("dispatcher", new DispatcherServlet(context));
        servlet.setInitParameter("throwExceptionIfNoHandlerFound", "true");
        servlet.setLoadOnStartup(1);
        servlet.addMapping("/");

        ServletRegistration.Dynamic h2Console = container.addServlet("h2-console", new WebServlet());
        h2Console.setInitParameter("-webAllowOthers", "");
        h2Console.setLoadOnStartup(1);
        h2Console.addMapping("/h2/*", "/h2-console/*");
    }
}

在没有使用spring-boot的情况下,您需要手动配置maven(或gradle)依赖项,涵盖整个Spring Web层,包括Tomcat所需的那些库(如果没有嵌入式Tomcat),以及当然还有h2依赖:

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>${h2.version}</version>
</dependency>
英文:

Spring Boot takes care of the h2-console servlet registration magic, but it's pretty easy to solve with vanilla spring (not spring-boot) too, using any implementation of 'WebApplicationInitializer' such as 'AbstractSecurityWebApplicationInitializer'. For example, adding the dispatcher servlet and the h2-console in a Servlet 3.0+ environments (no web.xml):

public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {

    @Override
    protected void beforeSpringSecurityFilterChain(ServletContext container) {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(AppConfig.class, SecurityConfig.class, WebConfig.class);
        context.setServletContext(container);
        ServletRegistration.Dynamic servlet = container.addServlet(&quot;dispatcher&quot;, new DispatcherServlet(context));
        servlet.setInitParameter(&quot;throwExceptionIfNoHandlerFound&quot;, &quot;true&quot;);
        servlet.setLoadOnStartup(1);
        servlet.addMapping(&quot;/&quot;);

        ServletRegistration.Dynamic h2Console = container.addServlet(&quot;h2-console&quot;, new WebServlet());
        h2Console.setInitParameter(&quot;-webAllowOthers&quot;, &quot;&quot;);
        h2Console.setLoadOnStartup(1);
        h2Console.addMapping(&quot;/h2/*&quot;, &quot;/h2-console/*&quot;);
    }
}

Without spring-boot you'll need to manually configure maven (or gradle) dependencies for the entire Spring web tier, including those libraries required by Tomcat (if not embedded) and naturally, the h2 dependency:

&lt;dependency&gt;
	&lt;groupId&gt;com.h2database&lt;/groupId&gt;
	&lt;artifactId&gt;h2&lt;/artifactId&gt;
	&lt;version&gt;${h2.version}&lt;/version&gt;
&lt;/dependency&gt;

答案3

得分: 0

First, you need to define dataSource

    @Bean
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder()
            .generateUniqueName(false)
            .setName("testdb")
            .setType(EmbeddedDatabaseType.H2)
            .setScriptEncoding("UTF-8")
            .ignoreFailedDrops(true)
            .addScripts("sqlscripts/schema.sql", "sqlscripts/data.sql")
            .build();
    }

Then you can implement WebApplicationInitializer and override onStartup

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.h2.server.web.WebServlet;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;

public class ApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        //bootstrap dispatcher servlet
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(ApplicationConfig.class); // whatever config that you want to register

        ServletRegistration.Dynamic h2ServletRegistration = servletContext.addServlet(
            "h2-console",
            new WebServlet()
        );
        h2ServletRegistration.setLoadOnStartup(1);
        h2ServletRegistration.addMapping("/console/*");
    }
}

And since you use h2ServletRegistration.addMapping("/console/*");, remember to access the h2-console via the URL pattern like http://localhost:8080/<app-name>/console

My Spring version is 5.3.16 and H2 is 2.1.210

英文:

First, you need to define dataSource

    @Bean
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder()
            .generateUniqueName(false)
            .setName(&quot;testdb&quot;)
            .setType(EmbeddedDatabaseType.H2)
            .setScriptEncoding(&quot;UTF-8&quot;)
            .ignoreFailedDrops(true)
            .addScripts(&quot;sqlscripts/schema.sql&quot;, &quot;sqlscripts/data.sql&quot;)
            .build();
    }

Then you can implement WebApplicationInitializer and override onStartup

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.h2.server.web.WebServlet;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;

public class ApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        //bootstrap dispatcher servlet
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(ApplicationConfig.class); // whatever config that you want to register

        ServletRegistration.Dynamic h2ServletRegistration = servletContext.addServlet(
            &quot;h2-console&quot;,
            new WebServlet()
        );
        h2ServletRegistration.setLoadOnStartup(1);
        h2ServletRegistration.addMapping(&quot;/console/*&quot;);
    }
}

And since you use h2ServletRegistration.addMapping(&quot;/console/*&quot;);, remember to access to h2-console via the url pattern like http://localhost:8080/&lt;app-name&gt;/console

My spring version is 5.3.16 and h2 is 2.1.210

huangapple
  • 本文由 发表于 2020年10月23日 02:08:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/64488131.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定