2015-07-21 44 views
1

我試圖讀取S3上託管的Spring批處理文件。我想直接從S3訪問文件,而不是作爲本地文件下載,然後閱讀。Spring Spring與Spring Cloud AWS S3爲EU存儲桶返回301

這裏是我的讀者:

class MyReader extends FlatFileItemReader<MyReadItem> { 

    @Value('${com.me.s3bucket}') 
    private String s3bucket; 

    MyReader (DefaultLineMapper<MyReadItem> myLineMapper, ResourceLoader resourceLoader) { 
     this.linesToSkip = 1 
     this.lineMapper = myLineMapper 
     this.resource = resourceLoader.getResource("s3://${s3bucket}/path/to/myfile.csv") 
    } 
} 

讀者在我的批處理配置文件有線了:

@Bean 
public ItemReader<MyReadItem> reader() { 
    return new MyReader(myLineMapper(), resourceLoader) 
} 

@Autowired 
ResourceLoader resourceLoader 

// myLineMapper ... 

當我運行的批處理作業,我得到一個301例外:

Caused by: com.amazonaws.services.s3.model.AmazonS3Exception: Moved Permanently (Service: Amazon S3; Status Code: 301; Error Code: 301 Moved Permanently; Request ID: 1DAB29F45F62E0D9) 

S3 301異常似乎是因爲該區域在請求發生時未被定義(example here),但我application.yaml文件顯示如下,我定義區域:

cloud: 
    aws: 
     region: 
      static: eu-west-1 
      auto: false 

這是怎麼回事?這個問題與bean綁定的順序有關,也許在配置文件被讀取之前?

爲了測試,我已經使用這個方法來下載S3作爲同一應用程序中的臨時文件,它工作正常:

@Value('${com.me.s3bucket}') 
private String s3bucket; 

public static final String PREFIX = "s3temp"; 
public static final String SUFFIX = ".tmp"; 

public File downloadS3File(String resourcePath) throws IOException { 
    Resource resource = this.resourceLoader.getResource("s3://${s3bucket}/${resourcePath}"); 

    InputStream inputStream = resource.getInputStream(); 

    final File tempFile = File.createTempFile(PREFIX, SUFFIX); 
    tempFile.deleteOnExit(); 
    try { 
     FileOutputStream out = new FileOutputStream(tempFile) 
     IOUtils.copy(inputStream, out); 
    } 
    finally { 
    } 

    return tempFile; 
} 

是否有使用資源加載時明確指定的區域什麼辦法?

回答

1

好吧,所以問題在於桶未設置且爲空。

@Value('${com.me.s3bucket}') 
private String s3bucket; 

我不知道這是爲什麼,但是,當我提出這一點的類和發送的值作爲作業參數,它的工作。