背景:项目中需要对业务中的某些HQL语句做一些预处理,因此必须在分析HQL语句的过程中能够根据Java的反射机制动态获知某些实体类的信息。例如:from Person where name like '%张%',我们必须设法根据Person能够加载它对应的实体类。
想来想去还是在将*.hbm.xml这些配置文件交给spring的LocalSessionFactoryBean处理之前最好我们自己的系统能先处理一下,以便缓存某些配置信息以备需要的时候能够方便的取到。
首先要解决的一点就是spring中配置SessionFactory的Bean不能像下面这样定义了:
<bean id="unieapSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="unieapDatasource" />
</property>
<property name="mappingResources">
<list>
<value>com/neuqsoft/czgs/common/entity/Demo.hbm.xml</value>
<value>com/neuqsoft/czgs/common/entity/PERSON.hbm.xml</value>
……
</list>
</property>
</bean>
原因在于如果这样定义的话我们的系统无法截取实体配置文件这些资源文件,为了解决这个问题我很自然地想到了spring中的FactoryBean这个接口,于是下面的类应运而生了。
public class HibernateMappingResourceFactoryBean implements FactoryBean {
private List _list;
public Object getObject() throws Exception {
return _list;
}
public Class getObjectType() {
return List.class;
}
public boolean isSingleton() {
return true;
}
public void set_list(List _list) {
this._list = _list;
EntityManager.getInstance().registerAll(_list);
}
}
它的作用有两个:一是用于配置一个List的实例bean,二是将List中的所有资源文件注册到EntityManager中,有关EntityManager我们稍后会提到它的作用。
需要指出的是,使用spring可以很方便地向某个Bean中注入List类型的属性(通过list元素),但却不能简单地配置一个类型为List的Bean,所以我们这里利用FactoryBean接口以及list元素来达到可以配置一个List类型的Bean的目的。
HibernateMappingResourceFactoryBean以及LocalSessionFactoryBean在spring中的配置片段如下。
<bean id="bizHibernateMappingResource" class="HibernateMappingResourceFactoryBean">
<property name="_list">
<list>
<value>com/neuqsoft/czgs/common/entity/Demo.hbm.xml</value>
<value>com/neuqsoft/czgs/common/entity/PERSON.hbm.xml</value>
……
</list>
</property>
</bean>
<bean id="unieapSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="unieapDatasource" />
</property>
<property name="mappingResources" ref="bizHibernateMappingResource"/>
</bean>
这样以来既不妨碍spring中的LocalSessionFactoryBean加载Hibernate的配置文件又不妨碍我们自己的系统加载这些配置文件,而且配置也较为简单,可谓一举两得。
但是接下来在解析XML的过程中我却又遇到了麻烦,总是报告java.net.ConnectException: Connection timed out: connect 错误,可以肯定这是由于网络连接引起的,上班时间我们公司不能上外网,问题是解析XML文件究竟和网络连接有什么关系呢?
要找出错误的原因还得从源代码查起,下面是EntityManager类中registerAll方法的源代码(修改前)。
public void registerAll(List resourceList){
if(resourceList!=null){
try{
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(false);
factory.setValidating(false);
DocumentBuilder builder=factory.newDocumentBuilder();
for(int i=0;i<resourceList.size();i++){
String resourcePath=(String)resourceList.get(i);
try{
URL url=getResource(resourcePath);
File is=new File(url.getFile());
org.w3c.dom.Document w3cDocument=builder.parse(is);
DOMReader reader=new DOMReader();
Document document=reader.read(w3cDocument);
parseDocument(document);
}catch(Exception e){
throw new RuntimeException("Error:"+resourcePath,e);
}
}
}catch(ParserConfigurationException e){
e.printStackTrace();
} catch (FactoryConfigurationError e) {
e.printStackTrace();
}
}
}
错误是从org.w3c.dom.Document w3cDocument=builder.parse(is);这一行开始的,无疑是解析XML的错误了,为了彻底弄清楚错误的原因,我打开一个实体配置文件(Demo.hbm.xml)仔细研究了一下,发现在文档类型定义中确实有URL:
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
于是我猜想会不会是XML解析器在解析XML的时候发现文档类型定义中的systemId是URL,那么就会尝试建立连接以便通过连接读取DTD的内容呢,如果是这样的话,那么等下班后能够上网了,这个问题就应该消失,巧的是正在这时下班的时间到了,于是我开始重新启动服务器,一切尽在意料之中,错误消失了。
现在的问题是上班的时间怎么办,有没有一种机制可以改变XML解析器分析文档类型定义时默认的行为呢,答案是肯定的,那就是通过定制实体解析器来改变其默认的行为。我首先把Hibernate的文档类型定义hibernate-mapping-3.0.dtd这个文件拷贝到我们的工程的类路径中,接下来将EntityManager中的registerAll方法改成下面这样,上班的时候启动服务器也不会报网络连接异常这样可恶的错误了。
public void registerAll(List resourceList){
if(resourceList!=null){
try{
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(false);
factory.setValidating(false);
DocumentBuilder builder=factory.newDocumentBuilder();
builder.setEntityResolver(new EntityResolver(){
public InputSource resolveEntity(String publicID, String systemID)
throws SAXException, IOException {
InputStream is=getClass().getResourceAsStream("hibernate-mapping-3.0.dtd");
return new InputSource(is);
}
});
for(int i=0;i<resourceList.size();i++){
String resourcePath=(String)resourceList.get(i);
try{
URL url=getResource(resourcePath);
File is=new File(url.getFile());
org.w3c.dom.Document w3cDocument=builder.parse(is);
DOMReader reader=new DOMReader();
Document document=reader.read(w3cDocument);
parseDocument(document);
}catch(Exception e){
throw new RuntimeException("Error:"+resourcePath,e);
}
}
}catch(ParserConfigurationException e){
e.printStackTrace();
} catch (FactoryConfigurationError e) {
e.printStackTrace();
}
}
}
The article is end.
分享到:
相关推荐
当你尝试通过Shell连接到Linux虚拟机时,如果发现连接失败,首先应该检查的是SSH服务是否正在运行。SSH(Secure Shell)是一种加密的网络传输协议,用于远程登录、文件传输等操作,是Linux系统中常用的远程管理工具...
报错:Exception in thread “main” java.net.ConnectException: Call From hdp-1/192.168.234.129 to hdp-1:8020 failed on connection exception: java.net.ConnectException: Connection refused; For more ...
网上的调用例子太多了,有的要用cmd来解析webserive,有的没有包,有的代码报错。学习及测试花了4天,终于完成了。 1直接把项目放到 myeclipse的工作区间加载就行。然后將axis-1_4包下的lib文件夹里的包 都加載到...
Java调用.NET WebService是跨平台通信的一种常见方式,尤其在企业级应用中,不同技术栈的应用需要相互交互数据时,这种技术尤为实用。Apache Axis是Java中常用的用于调用Web服务的工具,它提供了方便的API来创建和...
- I/O exception (java.net.ConnectException) caught when processing request: Connection timed out: connect - Retrying request - I/O exception (java.net.ConnectException) caught when processing request:...
Error running app: Unable to open debugger port (localhost:8601): java.net.ConnectException “Connection refused: connect” 2.出现场景: 原有项目中加入了ndk以后,debug出现问题(想
当检测到对方断开连接或存在异常时,应主动关闭本端连接。 3. **处理效率** 高效的Socket编程通常需要多个线程来管理连接。接收线程负责接收数据,心跳线程发送和接收心跳信息,而Worker线程处理接收到的消息。短...
《Spark源码分析3——驱动器、主节点与执行器之间的连接》 在Spark的分布式计算框架中,驱动器(Driver)、主节点(Master)和执行器(Executor)是核心组件,它们之间的通信和协作构成了Spark作业执行的基础。本文将深入...
JPedal是一款强大的PDF解析器,它允许开发者在Java应用程序中处理PDF文档,包括阅读、渲染、转换和提取PDF内容。这个"JPedal Source源码Eclipse项目"提供了JPedal库的完整源代码,使得开发人员可以深入理解其内部...
常见的工具有Apache Axis、JAX-WS(Java API for XML Web Services)、SOAP UI等。这些工具简化了服务的创建、部署和测试过程。 7. **Apache Axis**: Apache Axis是一个开源的Web服务框架,用于生成和运行SOAP...
6. **网络异常处理**:在Java网络编程中,理解并正确处理`java.io.IOException`、`java.net.ConnectException`等异常是非常关键的。 7. **网络安全**:包括SSL/TLS加密、数字证书、HTTPS协议等,这些都是构建安全...
本书对MATLAB的每个函数或指令的含义进行了描述,对其语法格式或参数作了说明,并尽可能对每个指令都给出实例供参考。
然而,在这种长连接中,可能会出现各种异常情况,影响到数据的传输和通信。下面将详细介绍这些异常情况,并提供解决方法。 java.net.BindException: Address already in use 该异常发生在服务器端进行 new ...
Java的`java.net.UnknownHostException`、`java.net.ConnectException`、`java.io.IOException`等异常,需要程序员妥善捕获并处理,确保程序的健壮性。 在学习Java网络编程时,还需要了解并发编程,因为通常网络...
`java.util.concurrent.ExecutionException` 是Java并发编程中一个常见的异常,通常在执行Future对象的get()方法时抛出。这个异常表明在异步任务的执行过程中发生了异常。当我们使用ExecutorService提交任务并尝试...
accs_token是企业微信提供的访问令牌(Access Token),它是调用企业微信API时的身份凭证,用于验证请求的合法性。获取accs_token通常需要企业微信的AppID和AppSecret,这两个参数在企业微信开发者中心注册应用后...
如果抛出异常,如`java.net.ConnectException`,则端口可能被占用或不可达。 下面是一个简单的Java代码示例,用于扫描指定的TCP端口: ```java import java.io.IOException; import java.net.InetSocketAddress; ...
jlibmodbus库适用于Java语言开发使用Modbus传输协议,支持Modbus RTU、Modbus TCP、Modbus ASCII、Modbus on Android Things device。 压缩包文件: jlibmodbus-1.2.9.7.zip jlibmodbus-1.2.9.7.tar.gz jlibmodbus_...
redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused: connect at redis.clients.jedis.Connection.connect(Connection.java:164) at redis.clients.jedis....