我有一个带有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)
它只是通过单元测试,并在网络应用程序中失败。
我认为在文件模式下,当我运行webapp时,HSQLDB找不到数据库的文件。
我已经尝试将数据库的数据放在webapp的根目录和web-inf内部,但它不起作用。
答案 0 :(得分:2)
好吧,如果你把数据库放在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();
}
}
这是我在春天使用的配置:
<?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的路径。如果有人可以这么简单,请发表答案。
答案 1 :(得分:1)
我在这里找到了答案:
http://coding.derkeiler.com/Archive/Java/comp.lang.java.databases/2003-11/0096.html
我将de数据放在我的项目persistenceLayerWithData.jar的jar中。
然后我将此属性设置为数据源:
<property name="url" value="jdbc:hsqldb:res:/data/images" />
我将jar添加到web-inf / lib并进行战争(所有这些都使用maven)并在tomcat中部署并且它可以工作,我也将它部署在websphere 7中并且也可以工作。
但是当我运行whit mvn jetty时:运行它并不是我认为在运行jetty whit maven时它不会将jar放入claspath。
答案 2 :(得分:0)
您应该使用绝对文件路径。运行Web应用程序时,“当前”(或“工作”)目录很可能是应用程序服务器的bin
文件夹。因此,当您为HSQLDB URL指定相对路径时,它会尝试从该处加载此文件,而不是相对于您的webapp根目录。