如何将对象从控制器传递到Spring Batch中的步骤

时间:2017-11-08 14:16:33

标签: spring spring-boot spring-batch

我想将reqData表单My Controller类传递给我的工作步骤,有没有办法实现相同的任何帮助将不胜感激。我有一个HttpRequestData的物体,我已经在控制器中复活了。谢谢

HttpRequestController.java

package com.npst.imps.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.npst.imps.utils.HttpRequestData;
import com.npst.imps.utils.TransactionResponseData;
import javax.servlet.http.HttpSession;
@RestController
public class HttpRequestController {
    TransactionResponseData transactionResponseData;
    @Autowired
    HttpSession session;
    JobExecution jobExecution;
    @Autowired
    JobLauncher jobLauncher;
    @Autowired
    Job fundtrans;
    String test;
    @RequestMapping("/impsft")
    public String handleHttpRequest(@RequestBody HttpRequestData reqData) throws Exception {
        Logger logger = LoggerFactory.getLogger(this.getClass());

        try {
            JobParameters jobParameters = new JobParametersBuilder().addLong("time", System.currentTimeMillis()).toJobParameters();
            jobExecution = jobLauncher.run(fundtrans, jobParameters);   
            ExecutionContext context= jobExecution.getExecutionContext();
            //context.put("reqData", reqData);
            transactionResponseData=(TransactionResponseData) context.get("transactionData");
            //System.out.println(context.get("transactionResponseData"));
        } catch (Exception e) {
            logger.info(e.getMessage());
            e.printStackTrace();
        }
        return reqData+" "+transactionResponseData.getMsg()+",Tid="+transactionResponseData.getTid();
    }
}

以下是我的步骤

我希望在我的步骤类中获得相同的reqData,并且从这里开始我将把doAfter方法的步骤执行对象放入其中。

PrepareTransactionId.java

package com.npst.imps.action;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.StepExecutionListener;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.npst.imps.service.TransactionService;
import com.npst.imps.utils.GenericTicketKey;
import com.npst.imps.utils.HttpRequestData;
import com.npst.imps.utils.TicketGenerator;
import com.npst.imps.utils.TransactionResponseData;
@Service
public class PrepareTransactionId implements Tasklet,StepExecutionListener{
    static Logger logger = LoggerFactory.getLogger(PrepareTransactionId.class);
    String appId;
    private static TicketGenerator ticketGenerator = null;
    private static GenericTicketKey genericTicketKey = null;
    @Autowired
    HttpSession session;
    @Autowired
    TransactionService transactionService;
    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        try {
            DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
            Date date = new Date();
            String ticket;  
            System.out.println("transactionService:: PrepareTransactionId"+transactionService);
            TransactionResponseData  transactionData=new TransactionResponseData();     

            System.out.println("reqData::"+reqData);
            long value=transactionService.getMaxTid(appId);
            logger.info("Max id From db::"+value);
            if (value == 0) {
                value = System.currentTimeMillis() / 10000;
                long l = value;
                ticket=l+"";
            }
            long l = value + 1; 
            ticketGenerator = TicketGenerator.getInstance(9999999999L, 0, l);
            genericTicketKey = new GenericTicketKey(0, false, 10);
            ticket = ticketGenerator.getNextEdgeTicketFor(genericTicketKey);
            stepExecution.getJobExecution().getExecutionContext().put("ticket", ticket);    
            ticket=appId+ticket;
            System.out.println("tid::"+ticket);
            stepExecution.getJobExecution().getExecutionContext().put("tid", ticket);
            stepExecution.getJobExecution().getExecutionContext().put("reqData", reqData);
            transactionData.setMsg("Request Recived...");
            transactionData.setTid(ticket+"");
            transactionData.setNodeId(appId);
            transactionData.setReqtime(dateFormat.format(date));;
            stepExecution.getJobExecution().getExecutionContext().put("transactionData", transactionData);  
            logger.info("Request Recived with tid::"+ticket);
            ExitStatus exist=new ExitStatus("SUCCESS", "success");
            return exist.replaceExitCode("SUCCESS");
        }
        catch(Exception e) {
            e.printStackTrace();
            return ExitStatus.FAILED;
        }
    }

    public String getAppId() {
        return appId;
    }

    public void setAppId(String appId) {
        this.appId = appId;
    }

    @Override
    public void beforeStep(StepExecution arg0) {
        // TODO Auto-generated method stub
    }
    @Override
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
        return null;
    }

}

2 个答案:

答案 0 :(得分:0)

TL; DR->您不能。

JobParameters实例只能包含以下类型的值:

  • String
  • Long
  • Date
  • Double

其背后的原因主要是持久性。请记住,所有春季批处理元数据(包括作业参数)都将进入数据源。

要使用自定义对象,您需要确保您的对象是不可变的并且是线程安全的。

JobParameters文档指出:

  

代表批处理作业的运行时参数的值对象。因为   参数在JobParameters之外没有单独的含义   它们包含在其中,它是一个值对象而不是一个实体。   参数对象可以是   为了确定是否与其他人可靠地比较   一个JobParameters对象等于另一个。此外,因为这些   参数将需要保留,添加的类型至关重要   被限制。此类是不可变的,因此是线程安全的。

JobParametersBuilder文档状态也是如此:

  

用于创建JobParameters的Helper类。 有用,因为所有   JobParameter对象是不可变的,必须实例化   分别确保类型安全。创建后,就可以在   与java.lang.StringBuilder相同(除了顺序无关),方法是   添加各种参数类型并一次创建有效的JobParameters   完成。


但是我保证我的物品还可以。我可以使用它们吗?

可以,但是Spring开发人员很久以前决定不支持此功能。

spring forums中对此进行了讨论,甚至创建了JIRA ticket-状态无法修复。


相关链接

答案 1 :(得分:-2)

我不会建议传递完整的HttpRequestData。而不是仅传递需要批量信息。您可以使用JobParameters传递此信息。

示例代码

JobParameters parameters = new JobParametersBuilder().addString("key1",HttpRequestData.gteData)
                                                    .addString("key2",HttpRequestData.gteData)
                                                    .addString("key3",HttpRequestData.gteData)                                                 
                                                   .toJobParameters();   

现在,您可以从StepExecution

获取JobParameters

将自定义对象放入JobParameters

HashMap<String, JobParameter>();
           JobParameter myParameter = new JobParameter(your custom object);
           map.put("myobject", myParameter);
           JobParameters jobParameters = new JobParameters(map);