2015-06-21 2 views
1

HI У меня есть простой проект Spring Java IO, где класс должен читать из файла csv и для каждой записи читать, параметры хранятся в списке объектов учетной записи. Я использую Force IDE Luna, а класс CsvAccountDao, который читает файл, находится в том же пакете, что и файл csv, который определен в первом компоненте XML-файла. Файл xml также находится под одним и тем же пакетом. Вот файл боб:Путь к шаблону класса весной: файл не найден Исключение

<?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) Есть ли проблема, где я бы обновил файл XML, где первый компонент использует accounts.csv, добавив полный путь? Поскольку оба класса, xml и csv-файлы находятся в одном пакете, я думал, что мне не нужно быть более конкретным. Thanks

Thanks

+0

проверьте этот http: // stackoverflow.com/questions/7484594/spring-3-0-inject-files-as-resources – Satya

+0

Спасибо Satya Я добавил пакет к значению в моем XML-файле приложения COntext для файла account.csv, и он сработал. – user1548875

ответ

2

Некоторые фоне загрузки ресурсов.

В Java для загрузки ресурса пути к классу вы вызываете getResource или getResourceAsStream на загрузчик классов с именем ресурса. Имя ресурса:

Имя ресурса - это имя пути, разделенное «/», которое идентифицирует ресурс.

Так, чтобы получить ресурс из пакета, который вы используете:

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" в загрузчик классов. Классный загрузчик ищет его в корневой части пути к классам.

Итак, в вашем весеннем xml вам нужно сказать, в каком пакете он находится. Он не будет относиться к xml. Поэтому измените его на «/package/account.csv» или «classpath: /package/account.csv»

Для справки: Я ищу Spring 4.0.9.RELEASE и oracle jdk8.

+0

Спасибо Roby и Satya Я добавил пакет к значению в моем XML-файле приложения COntext для файла account.csv, и он сработал. – user1548875

Смежные вопросы