Java P
Java P

Reputation: 2281

Injecting xml file into spring bean

I am trying to read xml file from remote location in my DAO.

<bean id="queryDAO"
      class="com.contextweb.openapi.commons.dao.reporting.impl.QueryDAOImpl">
  <property name="dataSource" ref="myDS"/>
  <property name="inputSource" ref="xmlInputSource"/>
</bean>

<bean id="fileInputStream" class="java.io.FileInputStream">
  <constructor-arg index="0" type="java.lang.String"
                   value="${queriesFileLocation}"/>
</bean>
<bean id="xmlInputSource" class="org.xml.sax.InputSource">
  <constructor-arg index="0" >
    <ref bean="fileInputStream"/>
  </constructor-arg>
</bean>

I am able to read XML for first time. For subsequent requests, inputstream is exhausted.

Upvotes: 1

Views: 1570

Answers (3)

Santosh
Santosh

Reputation: 17893

You are using FileInputStream thats where the problem lies. Once you have read the data in the stream there is no way you can read the contents again. The stream has reached its end.

Solution to this problem would be to use another class BufferedInputStream which supports resetting of stream pointing to anywhere in the file.

Following example shows that BufferedInputStream opened only once and can be used to read the file multiple times.

BufferedInputStream bis = new BufferedInputStream (new FileInputStream("test.txt"));

        int content;
        int i = 0;

        while (i < 5) {

            //Mark so that you could reset the stream to be beginning of file again when  you want to read it.
            bis.mark(0);

            while((content = bis.read()) != -1){

                //read the file contents.
                System.out.print((char) content);
            }
                System.out.println("Resetting ");
                bis.reset();
                i++;

        }

    }

There is catch. Since you are not using this class yourself but dependent on org.xml.sax.InputSource to do it, you need to create your own InputSource by extending this class and override getCharacterStream() and getByteStream() methods to mark() reset() the stream to start of the file.

Upvotes: 1

Adam
Adam

Reputation: 36703

Perhaps you could try inlining the FileInputStream so it forces a new instance each time?

<bean id="queryDAO" class="com.contextweb.openapi.commons.dao.reporting.impl.QueryDAOImpl">
    <property name="dataSource" ref="contextAdRptDS"/>
    <property name="inputSource">
        <bean class="org.xml.sax.InputSource">
            <constructor-arg index="0" >
                    <bean class="java.io.FileInputStream">
                        <constructor-arg index="0" type="java.lang.String" value="${queriesFileLocation}"/>
                    </bean>
            </constructor-arg>
        </bean>
    </property>
</bean>

Upvotes: 0

sundar
sundar

Reputation: 1760

Hope you know that in spring, by default all bean objects are singleton. So try to mention fileInputStream and xmlInputSource as non-singleton by setting the field singleton="false" in those bean declarations.

Upvotes: 2

Related Questions