gpt4 book ai didi

java - 如何使用 Spring 在文件中嵌入 HSQLDB 到 WebApp

转载 作者:行者123 更新时间:2023-12-04 07:04:05 25 4
gpt4 key购买 nike

我有一个带有 Spring 的 webApp,当我在服务器模式下使用 HSQLDB 时它可以正常工作,但在文件模式下,它只通过了单元测试。这是我的数据源:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />

<property name="url" value="jdbc:hsqldb:hsql://localhost/images" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>

我只是改变这一行
   <property name="url" value="jdbc:hsqldb:hsql://localhost/images" />    
( -- Server mode)

为了这
     <property name="url" value="jdbc:hsqldb:file:data/images" />      
(-- In file)

它只是通过了单元测试,但在 web appp 中失败了。

我想在文件模式下,当我运行 webapp 时,HSQLDB 找不到数据库的文件。

我已经尝试将数据库的数据放在 webapp 的根目录和 web-inf 内部,但它不起作用。

最佳答案

好吧,如果你像这样将数据库放在 jar 中:

<property name="url" value="jdbc:hsqldb:res:/data/images" />

您只能将其用作只读,如果您尝试插入或修改数据库将失败。

一种解决方案是在 web.xml 中放置一个监听器,这样当应用程序启动时,它将使用应用程序 web 的根路径进行初始化。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>maf</display-name>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>


<!--This is to get root of the aplication-->

<listener>
<listener-class>
org.atoms.HsqlDatabaseListener
</listener-class>
</listener>


<!--Este listener se encarga de inicializar todo el contenedor de Spring y mantener una variable en el
ServletContext que apunta a dicho contenedor -->

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>




</web-app>

听者:
package org.atoms;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;


/**
*
* @author atomsfat
*/
public class HsqlDatabaseListener implements ServletContextListener {

private ServletContext context = null;

public void contextInitialized(ServletContextEvent event) {
context = event.getServletContext();

String prefix = event.getServletContext().getRealPath("/");

System.out.println("database root " + prefix);
com.atoms.HsqlDatabasePathResolver.getInstance(prefix);


}

public void contextDestroyed(ServletContextEvent event) {
context = event.getServletContext();

}

另一个类:
package com.atoms;


/**
*
* @author atomsfat
*/
public class HsqlDatabasePathResolver {


private static HsqlDatabasePathResolver instance ;
private static String applicationPath = "";

private HsqlDatabasePathResolver() {
}

/** Get Instance.
*/
static public synchronized HsqlDatabasePathResolver getInstance(String applicationPath) {

if (instance == null) {

HsqlDatabasePathResolver.applicationPath =
HsqlDatabasePathResolver.normalizePath(applicationPath);
instance = new HsqlDatabasePathResolver();



System.out.println("Inizalizando path : " + HsqlDatabasePathResolver.applicationPath);

}
return instance;
}

public String getApplicationPath() {
return applicationPath;
}



public String getUrlDatabase(String urlDatabase) {


return HsqlDatabasePathResolver.replaceAll(urlDatabase,"{apppath}", applicationPath);
}


/**

*
* replace the "\" character by "/" and remove relative paths
*
* @param path
* @return
*/
public static String normalizePath(String path) {
if (path == null) {
return null;
}
String normalized = path;
if (normalized.equals("/.")) {
return "/";
}
if (normalized.indexOf('\\') >= 0) {
normalized = normalized.replace('\\', '/');
}
if (!normalized.startsWith("/") && normalized.indexOf(':') < 0) {
normalized = "/" + normalized;
}
do {
int index = normalized.indexOf("//");
if (index < 0) {
break;
}
normalized = normalized.substring(0, index) + normalized.substring(index + 1);
} while (true);
do {
int index = normalized.indexOf("/./");
if (index < 0) {
break;
}
normalized = normalized.substring(0, index) + normalized.substring(index + 2);
} while (true);
do {
int index = normalized.indexOf("/../");
if (index >= 0) {
if (index == 0) {
return null;
}
int index2 = normalized.lastIndexOf('/', index - 1);
normalized = normalized.substring(0, index2) + normalized.substring(index + 3);
} else {
return normalized;
}
} while (true);
}




public static String replaceAll(String str, String match, String replace) {
if (match == null || match.length() == 0) {
return str;
}
if (replace == null) {
replace = "";
}
if(match.equals(replace))return str;
StringBuffer ret=new StringBuffer();
int i = str.indexOf(match);
int y = 0;
while (i >= 0)
{
//System.out.println("i:"+i+" y:"+y);
ret.append(str.substring(y, i));
ret.append(replace);
//str = str.substring(y, i) + replace + str.substring(i + match.length());
y = i + match.length();
i = str.indexOf(match,y);
}
ret.append(str.substring(y));
return ret.toString();
}



}

这是我在 spring 中使用的配置:
    <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd">

<!-- La definición del Datasource -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" lazy-init="true"
destroy-method="close">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />

<property name="url">
<ref bean="dataBaseUrl"/>
</property>

<property name="username" value="sa" />
<property name="password" value="" />
</bean>

<!-- La definición del Factory de Session con Anotaciones -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" lazy-init="false">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.HSQLDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>Atoms.hbm.xml</value>
</list>

</property>
</bean>
<!--HibernaTemplate-->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<!-- Definición de los DAO`s -->

<bean id="ipBlancaDao" class="org.atoms.impl.AtomsDaoHibernateImpl">
<property name="hibernateTemplate" ref="hibernateTemplate" />
</bean>


<!--If your are not running in Web this will initialize with the directory from the process was started note that this classes is a singleton so if you are running in web the listener already have initialize the class with the path of the class-->


<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>


<bean id="hsqlDatabasePathResolver" class="com.atoms.HsqlDatabasePathResolver" factory-method="getInstance" lazy-init="false">
<constructor-arg>
<value>${user.dir}</value>
</constructor-arg>
</bean>

<!--This bean just replace {apppath} whit the absolute path-->

<bean id="dataBaseUrl" class="java.lang.String" factory-bean="hsqlDatabasePathResolver" lazy-init="false"
factory-method="getUrlDatabase">
<constructor-arg>
<value>jdbc:hsqldb:mem:{apppath}/WEB-INF/data/maf</value>
</constructor-arg>

</bean>
</beans>

是的,这项工作是一团糟,我认为解决方案是监听器,有了它,您可以获得 appWeb 的路径。如果有人可以使这个简单,请张贴答案。

关于java - 如何使用 Spring 在文件中嵌入 HSQLDB 到 WebApp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1380882/

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