如何在Spring批处理中将对象从控制器传递到步骤

如何在Spring批处理中将对象从控制器传递到步骤,spring,spring-boot,spring-batch,Spring,Spring Boot,Spring Batch,我想将reqData从我的控制器类传递到我工作的各个步骤,是否有任何方法可以实现同样的效果?如有任何帮助,将不胜感激。我有一个HttpRequestData对象,我已经在controller中恢复了它。谢谢 HttpRequestController.java package com.npst.imps.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.b

我想将
reqData
从我的控制器类传递到我工作的各个步骤,是否有任何方法可以实现同样的效果?如有任何帮助,将不胜感激。我有一个
HttpRequestData
对象,我已经在controller中恢复了它。谢谢

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();
    }
}
下面是我的阶梯课

我想在我的step类中获得相同的reqData,从这里开始,我将把doAfter方法的step执行对象放在里面

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;
    }

}

我不建议传递完整的HttpRequestData。而不是只需要通过信息来批处理。可以使用JobParameters传递此信息

示例代码

JobParameters parameters = new JobParametersBuilder().addString("key1",HttpRequestData.gteData)
                                                    .addString("key2",HttpRequestData.gteData)
                                                    .addString("key3",HttpRequestData.gteData)                                                 
                                                   .toJobParameters();   
现在在步骤中,您可以从
StepExecution

将自定义对象放入JobParameters

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

JobParameter myParameter=新的JobParameter(自定义对象); map.put(“myobject”,myParameter); JobParameters JobParameters=新的JobParameters(映射);
TL;医生->你不能。 实例只能保存以下类型的值:

  • String
  • Long
  • 日期
  • Double
其背后的原因主要是持久性。请记住,所有spring批处理元数据(包括作业参数)都会进入数据源

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

文件规定:

表示批处理作业的运行时参数的值对象。因为 这些参数在JobParameters之外没有单独的含义 它们包含在中,它是一个值对象,而不是一个实体。 参数对象可以 为了确定是否 一个JobParameters对象等于另一个。而且因为这些 参数需要持久化,添加的类型至关重要 限制使用。此类是不可变的,因此是线程安全的。

文件还指出:

用于创建作业参数的帮助器类有用,因为所有 JobParameter对象是不可变的,必须实例化 单独使用以确保类型安全。一旦创建,它就可以在 同样的是java.lang.StringBuilder(除了顺序无关之外) 添加各种参数类型并一次性创建有效的JobParameters 完成了


但我保证我的东西没问题。我能用吗? 可以,但是Spring开发人员很久以前就决定不支持这个特性了

这在中进行了讨论,甚至创建了一个-状态无法修复


相关链接

是否有方法传递对象是的,传递对象的更新答案为JobParameter JobParameter myParameter=new JobParameter(reqdata);它不允许在jobparameter构造函数中传递自定义对象。@NaveenKumarMishra您有权。基于JobParameter的spring文档:
只有以下类型可以是参数:String、Long、Date和Double