2015-06-21 63 views
1

HI我有一個簡單的Java Spring IO項目,其中類應該從csv文件中讀取,並且對於每個記錄讀取,參數都存儲在一個帳戶對象列表中。 我正在使用強制IDE Luna,讀取文件的類CsvAccountDao與xml文件的第一個bean中定義的csv文件位於同一個包中。 xml文件也位於相同的包中。這裏是Bean文件:Spring中的類路徑探針:未找到文件異常

<?xml version="1.0" encoding="UTF-8"?> 

<beans xmlns="https://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> 

    <bean id="accountDao" 
    class="com.springinpractice.ch01.model.dao.csv.CsvAccountDao"> 
    <property name="csvResource" value="accounts.csv"></property> 
    </bean> 
    <bean id="accountService" 
      class="com.springinpractice.ch01.service.AccountService"> 
      <property name="accountDao" ref="accountDao"</property>  
     </bean> 
</beans> 

,這裏是類文件CscAccountDao:

package com.springinpractice.ch01.model.dao.csv; 
import java.io.BufferedReader; 
import java.io.FileReader; 
import java.math.BigDecimal; 
import java.text.DateFormat; 
import java.text.SimpleDateFormat; 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 
import org.springframework.core.io.Resource; 
import com.springinpractice.ch01.model.Account; 
import com.springinpractice.ch01.model.dao.AccountDao; 

public class CsvAccountDao implements AccountDao { 
    private Resource csvResource; 

    public CsvAccountDao() { 
     // TODO Auto-generated constructor stub 
    } 
    public void setCsvResource(Resource csvFile){ 
     this.csvResource = csvFile; 
    } 
    @Override 
    public List<Account> findAll() throws Exception { 
     List<Account> results = new ArrayList<Account>(); 

     DateFormat fmt = new SimpleDateFormat("MMddyyyy"); 
     BufferedReader br = new BufferedReader(
       new FileReader(csvResource.getFile())); 
     String line; 
     while((line = br.readLine()) != null){ 
      String[] fields = line.split(","); 

      String accountNo = fields[0]; 
      BigDecimal balance = new BigDecimal(fields[1]); 
      Date lastPaidOn = fmt.parse(fields[2]); 
      Account account = 
         new Account(accountNo, balance, lastPaidOn); 
      results.add(account); 
     } 
     br.close(); 
     return results; 
    } 

} 

記下方法setCsvResource CSV文件分配給資源對象是異常的問題開始的地方。我得到的堆棧跟蹤,說一個異常錯誤:

Jun 20, 2015 7:59:42 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons 
INFO: Pre-instantiating singletons in org.s[email protected]177e4b0: defining beans [accountDao,accountService]; root of factory hierarchy 
Exception in thread "main" java.io.FileNotFoundException: class path resource [accounts.csv] cannot be resolved to URL because it does not exist 

Q)是否有一個問題,我將不得不更新,其中第一豆加入了全路徑使用accounts.csv XML文件?既然類,xml和csv文件都在同一個包中,我認爲我不需要更具體。謝謝

謝謝

+0

檢查此http:// stackoverflow。com/questions/7484594/spring-3-0-inject-files-as-resources – Satya

+0

謝謝Satya我將該軟件包添加到我的應用程序COntext XML文件中的account.csv文件中,並且它工作正常。 – user1548875

回答

2

一些背景資源加載。

在Java中,要加載類路徑資源,請在具有資源名稱的類加載器上調用getResourcegetResourceAsStream。資源名稱爲:

資源的名稱是用'/'分隔的路徑名,用於標識資源。

所以從您使用包獲取資源:

classloader.getResource("org/com/resource.jpg") 

一個Java類,也有方便的方法來從它的類加載器加載資源。如果使用ClassA.class.getResource("resource.jpg"),它將在ClassA的'/'加入包之前加上「resource.jpg」並委託給類加載器。如果你的資源字符串以'/'開始,它將被解釋爲絕對路徑,那麼將刪除開頭的'/',然後委託給類加載器。

那麼,我們會彈出提供accounts.csv作爲要轉換爲資源的值。 Spring使用DefaultResourceLoader來查找您的資源。下面是使用它來找到你的資源的邏輯:

@Override 
public Resource getResource(String location) { 
    Assert.notNull(location, "Location must not be null"); 
    if (location.startsWith("/")) { 
     return getResourceByPath(location); 
    } 
    else if (location.startsWith(CLASSPATH_URL_PREFIX)) { 
     return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader()); 
    } 
    else { 
     try { 
      // Try to parse the location as a URL... 
      URL url = new URL(location); 
      return new UrlResource(url); 
     } 
     catch (MalformedURLException ex) { 
      // No URL -> resolve as resource path. 
      return getResourceByPath(location); 
     } 
    } 
} 

你的情況,它屬於所有的方式通過對catch(MalformedURLException ex),然後嘗試看看它的類路徑的資源。當最終要求ClasspathResource輸入URL或輸入流時,它會將"account.csv"傳遞給類加載器。類加載器正在類路徑的根目錄中查找它。

所以在你的spring xml中,你需要告訴它它是什麼包。它不會相對於xml。因此,將其更改爲「/package/account.csv」或「classpath:/package/account.csv」

僅供參考:我正在查看Spring 4.0.9.RELEASE和oracle jdk8。

+0

感謝Roby和Satya我將該包添加到我的應用程序COntext XML文件中的account.csv文件中,並且它工作正常。 – user1548875