S3에서 호스팅되는 Spring Batch에서 파일을 읽으려고합니다. 로컬 파일로 다운로드 한 다음 읽는 것이 아니라 S3에서 직접 파일에 액세스하고 싶습니다.
내 독자는 다음과 같습니다.
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 예외는 요청이 생성 될 때 지역이 정의되지 않았기 때문인 것으로 보이지만 ( 예 : 여기 ) 내 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;
}
리소스 로더를 사용할 때 명시 적으로 지역을 지정하는 방법이 있습니까?
좋습니다. 문제는 버킷이 설정되지 않고 null이라는 사실이었습니다.
@Value('${com.me.s3bucket}')
private String s3bucket;
왜 그런지 모르겠지만 이것을 클래스 밖으로 옮기고 값을 작업 매개 변수로 보냈을 때 작동했습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다