2016-10-12 4 views
0

spring-batch-excel 확장명을 사용하는 응용 프로그램을 작성하여 사용자가 웹 인터페이스를 통해 업로드 한 Excel 파일을 읽으면 Excel 파일에서 주소를 구문 분석 할 수 있습니다. .스프링 배치 : 파일을 읽을 수 없습니다.

코드가 실행되면 오류는 발생하지 않지만 로그에 다음과 같은 오류 메시지가 표시됩니다. 내 프로세서와 글쓴이 (비록 결코 호출되지 않으며, 내가 상상할 수있는 것은 파일을 올바르게 읽지 않고 처리/쓰기 할 데이터를 반환하지 않는다)에 로그/syso가있다. 그리고 예, 파일에는 실제로 수천 개의 레코드가 있습니다.

Job: [FlowJob: [name=excelFileJob]] launched with the following parameters: [{file=Book1.xlsx}] 
Executing step: [excelFileStep] 
Job: [FlowJob: [name=excelFileJob]] completed with the following parameters: [{file=Book1.xlsx}] and the following status: [COMPLETED] 

다음은 오류가없는, 다음은 내 AddressExcelReader 잘 늦은 바인딩 작품 내 JobConfig

@Configuration 
@EnableBatchProcessing 
public class AddressExcelJobConfig { 

    @Bean 
    public BatchConfigurer configurer(EntityManagerFactory entityManagerFactory) { 
     return new CustomBatchConfigurer(entityManagerFactory); 
    } 

    @Bean 
    Step excelFileStep(ItemReader<AddressExcel> excelAddressReader, 
         ItemProcessor<AddressExcel, AddressExcel> excelAddressProcessor, 
         ItemWriter<AddressExcel> excelAddressWriter, 
         StepBuilderFactory stepBuilderFactory) { 
     return stepBuilderFactory.get("excelFileStep") 
       .<AddressExcel, AddressExcel>chunk(1) 
       .reader(excelAddressReader) 
       .processor(excelAddressProcessor) 
       .writer(excelAddressWriter) 
       .build(); 
    } 

    @Bean 
    Job excelFileJob(JobBuilderFactory jobBuilderFactory, 
        @Qualifier("excelFileStep") Step excelAddressStep) { 
     return jobBuilderFactory.get("excelFileJob") 
       .incrementer(new RunIdIncrementer()) 
       .flow(excelAddressStep) 
       .end() 
       .build(); 
    } 
} 

입니다. 새 ClassPathResource 및 FileSystemResource를 만드는 것 외에도 파일 이름이 지정된 리소스를로드하려고 시도했습니다. 모두 나에게 똑같은 결과를 준다.

@Component 
@StepScope 
public class AddressExcelReader implements ItemReader<AddressExcel> { 

    private PoiItemReader<AddressExcel> itemReader = new PoiItemReader<AddressExcel>(); 

    @Override 
    public AddressExcel read() 
      throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException { 
     return itemReader.read(); 
    } 

    public AddressExcelReader(@Value("#{jobParameters['file']}") String file, StorageService storageService) { 
     //Resource resource = storageService.loadAsResource(file); 
     //Resource testResource = new FileSystemResource("upload-dir/Book1.xlsx"); 
     itemReader.setResource(new ClassPathResource("/upload-dir/Book1.xlsx")); 
     itemReader.setLinesToSkip(1); 
     itemReader.setStrict(true); 
     itemReader.setRowMapper(excelRowMapper()); 
    } 

    public RowMapper<AddressExcel> excelRowMapper() { 
     BeanWrapperRowMapper<AddressExcel> rowMapper = new BeanWrapperRowMapper<>(); 
     rowMapper.setTargetType(AddressExcel.class); 
     return rowMapper; 
    } 

} 

다음은이 결코 (더 로그가 생성되지 않습니다) 놀이로 나지 않는, 다시 내 AddressExcelProcessor

@Component 
public class AddressExcelProcessor implements ItemProcessor<AddressExcel, AddressExcel> { 

    private static final Logger log = LoggerFactory.getLogger(AddressExcelProcessor.class); 

    @Override 
    public AddressExcel process(AddressExcel item) throws Exception { 
     System.out.println("Converting " + item); 
     log.info("Convert {}", item); 
     return item; 
    } 

} 

입니다.

@PostMapping("/") 
public String handleFileUpload(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) { 

    storageService.store(file); 

    try { 
     JobParameters jobParameters = new JobParametersBuilder() 
       .addString("file", file.getOriginalFilename().toString()).toJobParameters(); 
     jobLauncher.run(job, jobParameters); 
    } catch (JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException 
      | JobParametersInvalidException e) { 
     e.printStackTrace(); 
    } 

    redirectAttributes.addFlashAttribute("message", 
      "You successfully uploaded " + file.getOriginalFilename() + "!"); 

    return "redirect:/"; 
} 

:이 중요한 경우 내가 @PostMapping ("/")에서 FileUploadController에서 내 일을 시작 해요 파일 업로드, 첫번째 저장 파일을 처리하는 방법을 그리고, 이것이 다음 작업을 실행 그리고 여기에

하지 적어도

에 의해 마지막으로 내 AddressExcel POJO이다

import lombok.Data; 

@Data 
public class AddressExcel { 

    private String address1; 
    private String address2; 
    private String city; 
    private String state; 
    private String zip; 

    public AddressExcel() {} 

} 

은 UPDATE (2016년 10월 13일)는 NGHIA 마 님의 댓글에서 가, 나 또한 내 자신을 만들어 RowMapper를 사용하여 BeanWrapper를 사용하는 것이 문제인지 확인하십시오. 여전히 같은 결과.

public class AddressExcelRowMapper implements RowMapper<AddressExcel> { 

    @Override 
    public AddressExcel mapRow(RowSet rs) throws Exception { 
     AddressExcel temp = new AddressExcel(); 

     temp.setAddress1(rs.getColumnValue(0)); 
     temp.setAddress2(rs.getColumnValue(1)); 
     temp.setCity(rs.getColumnValue(2)); 
     temp.setState(rs.getColumnValue(3)); 
     temp.setZip(rs.getColumnValue(4)); 

     return temp; 
    } 

} 
+0

, 당신은 org.springframework.batch.item 구현하는 간단한 클래스를 가질 수 .excel.RowMapper를 사용하여 Reader가 실제로 데이터를 읽고 RowMapper에 있는지 확인하십시오. –

+1

당신은 분명히 'itemReader.setResource (new ClassPathResource ("/ upload-dir/Book1.xlsx"));' 맞다? 클래스 경로에 ubdirectory "upload-dir"을 포함하는 디렉토리가 있어야합니다. –

+0

리더를 디버그하여 파일을 찾아서 올바르게 열 었는지 확인 했습니까? –

답변

0

내가 내 ItemReader에 다음을 추가하는 것이었다 필요한 것 모든 : 대신 BeanWrapperRowMapper를 사용하는 문제 해결을위한

itemReader.afterPropertiesSet(); 
itemReader.open(new ExecutionContext()); 
+0

이것은 문제의 부분적인 해결책 일뿐입니다. 대리인을 스트림으로 등록하거나 질문에 대한 내 의견을 따르십시오. –

+0

작동하도록 ItemStreamReader를 구현할 필요가 없었습니다. 그게 나에게주는 유익은 무엇입니까? 미안하지만 왜 내가 묻는 지 모르겠다. – ThirstyForJava

+0

@ThirstyForJava : 위에서 언급 한 것처럼 시도 할 때마다 예외가 발생했습니다 : org.springframework.batch.item.ItemStreamException : 리더 초기화에 실패했습니다 그리고'Cause : java.lang.IllegalStateException : InputStream은 반드시 지원 표시/재설정, 또는 PushbackInputStream으로 랩핑 됨 어떻게해야합니까? 다른 대안이 있습니까? –

관련 문제