简体   繁体   English

如何基于密钥实现CsvProcessing的工厂设计模式

[英]How to Implement Factory Design Pattern for CsvProcessing based on Key

I have written a controller which is a default for MototuploadService(for Motor Upload), but I need to make one Factory Design so that based on parentPkId , need to call HealUploadService, TempUploadService, PersonalUploadService etc which will have separate file processing stages. 我已经写了一个MototuploadService(用于Motor Upload)的默认控制器,但是我需要进行一次工厂设计,以便基于parentPkId调用HealUploadService,TempUploadService,PersonalUploadService等,这将具有单独的文件处理阶段。

controller is below. 控制器在下面。

@RequestMapping(value = "/csvUpload", method = RequestMethod.POST)
    public List<String> csvUpload(@RequestParam String parentPkId, @RequestParam List<MultipartFile> files)
            throws IOException, InterruptedException, ExecutionException, TimeoutException {
        log.info("Entered method csvUpload() of DaoController.class");
        List<String> response = new ArrayList<String>();
        ExecutorService executor = Executors.newFixedThreadPool(10);
        CompletionService<String> compService = new ExecutorCompletionService<String>(executor);
        List< Future<String> > futureList = new ArrayList<Future<String>>();
        for (MultipartFile f : files) {
            compService.submit(new ProcessMutlipartFile(f ,parentPkId,uploadService));
            futureList.add(compService.take());
        }       
        for (Future<String> f : futureList) {
            long timeout = 0;
            System.out.println(f.get(timeout, TimeUnit.SECONDS));
            response.add(f.get());
        }
        executor.shutdown();
        return response;
    }

Here is ProcessMutlipartFile class which extends the callable interface, with CompletionService's compService.submit() invoke this class, which in turn executes call() method, which will process a file. 这是ProcessMutlipartFile类,它扩展了可调用的接口,CompletionService的compService.submit()调用了该类,该类又执行了call()方法,该方法将处理文件。

public class ProcessMutlipartFile implements Callable<String>
{
   private MultipartFile file; 
   private String temp;
   private MotorUploadService motUploadService;
   public ProcessMutlipartFile(MultipartFile file,String temp, MotorUploadService motUploadService )
   {
       this.file=file;
       this.temp=temp;
       this.motUploadService=motUploadService;
   }

   public String call() throws Exception 
   {

    return   motUploadService.csvUpload(temp, file);
    }

}

Below is MotorUploadService class, where I'm processing uploaded CSV file, line by line and then calling validateCsvData() method to validate Data, which returns ErrorObject having line number and Errors associated with it. 下面是MotorUploadService类,我在其中MotorUploadService处理上载的CSV文件,然后调用validateCsvData()方法来验证Data,该数据返回具有行号和与之关联的Errors的ErrorObject。 if csvErrorRecords is null, then error-free and proceed with saving to Db. 如果csvErrorRecords为null,则无错误,然后继续保存到Db。 else save errorList to Db and return Upload Failure. 否则将errorList保存到Db并返回Upload Failure。

@Component
public class MotorUploadService {

@Value("${external.resource.folder}")
     String resourceFolder;

    public String csvUpload(String parentPkId, MultipartFile file) {

    String OUT_PATH = resourceFolder;

    try {
            DateFormat df = new SimpleDateFormat("yyyyMMddhhmmss"); 
            String filename = file.getOriginalFilename().split(".")[0] + df.format(new Date()) + file.getOriginalFilename().split(".")[1];
            Path  path = Paths.get(OUT_PATH,fileName)
            Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
        }
        catch(IOException e){
            e.printStackTrace();
            return "Failed to Upload File...try Again";
        }
        List<TxnMpMotSlaveRaw> txnMpMotSlvRawlist = new ArrayList<TxnMpMotSlaveRaw>();

        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(file.getInputStream()));
            String line = "";
            int header = 0;
            int lineNum = 1;
            TxnMpSlaveErrorNew txnMpSlaveErrorNew = new TxnMpSlaveErrorNew();
            List<CSVErrorRecords> errList = new ArrayList<CSVErrorRecords>();
            while ((line = br.readLine()) != null) {
                // TO SKIP HEADER
                if (header == 0) {
                    header++;
                    continue;
                }
                lineNum++;
                header++;
                // Use Comma As Separator
                String[] csvDataSet = line.split(",");

                CSVErrorRecords csvErrorRecords = validateCsvData(lineNum, csvDataSet);
                System.out.println("Errors from csvErrorRecords is " + csvErrorRecords);

                if (csvErrorRecords.equals(null) || csvErrorRecords.getRecordNo() == 0) {
                    //Function to Save to Db

                } else {
                    // add to errList
                    continue;
                }
            }
            if (txnMpSlaveErrorNew.getErrRecord().size() == 0) {
                //save all
                return "Successfully Uploaded " + file.getOriginalFilename();   
            } 
            else {
                // save the error in db;
                return "Failure as it contains Faulty Information" + file.getOriginalFilename();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
            return "Failure Uploaded " + file.getOriginalFilename();
        }

    }

    private TxnMpMotSlaveRaw saveCsvData(String[] csvDataSet, String parentPkId) {
        /*
            Mapping csvDataSet to PoJo
            returning Mapped Pojo;
        */
    }

    private CSVErrorRecords validateCsvData(int lineNum, String[] csvDataSet) {
        /*
        Logic for Validation goes here
        */
    }

}

How to make it as a factory design pattern from controller , so that if 如何通过controller将其作为工厂设计模式,以便

 parentPkId='Motor' call MotorUploadService,
    parentPkId='Heal' call HealUploadService 

I'm not so aware of the Factory Design pattern, please help me out. 我不太了解Factory Design模式,请帮帮我。 Thanks in advance. 提前致谢。

If I understood the question, in essence you would create an interface, and then return a specific implementation based upon the desired type. 如果我理解这个问题,从本质上讲,您将创建一个接口,然后根据所需类型返回特定的实现。

So 所以

public interface UploadService {
  void csvUpload(String temp, MultipartFile file) throws IOException;
}

The particular implementations 具体的实现

public class MotorUploadService implements UploadService
{
  public void csvUpload(String temp, MultipartFile file) {
    ...
  }
}

public class HealUploadService implements UploadService
{
  public void csvUpload(String temp, MultipartFile file) {
    ...
  }
}

Then a factory 然后是工厂

public class UploadServiceFactory {
  public UploadService getService(String type) {
    if ("Motor".equals(type)) {
      return new MotorUploadService();
    }
    else if ("Heal".equals(type)) {
      return new HealUploadService();
    }
  }
}

The factory might cache the particular implementations. 工厂可能会缓存特定的实现。 One can also use an abstract class rather than an interface if appropriate. 如果合适,也可以使用抽象类而不是接口。

I think you currently have a class UploadService but that is really the MotorUploadService if I followed your code, so I would rename it to be specific. 我想你现在有一类UploadService但是这是真的MotorUploadService如果我跟着你的代码,所以我将其重命名为具体。

Then in the controller, presumably having used injection for the UploadServiceFactory 然后在控制器中,大概已经对UploadServiceFactory使用了注入

...
for (MultipartFile f : files) {
  UploadService uploadSrvc = uploadServiceFactory.getService(parentPkId);
  compService.submit(new ProcessMutlipartFile(f ,parentPkId,uploadService));
  futureList.add(compService.take());
} 

So with some additional reading in your classes: 因此,在您的课堂上再加上一些阅读内容:

public class ProcessMutlipartFile implements Callable<String>
{
   private MultipartFile file; 
   private String temp;
   private UploadService uploadService;

   // change to take the interface UploadService
   public ProcessMutlipartFile(MultipartFile file,String temp, UploadService uploadService )
   {
       this.file=file;
       this.temp=temp;
       this.uploadService=uploadService;
   }

   public String call() throws Exception 
   {
     return   uploadService.csvUpload(temp, file);
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM