是否存在逐步执行流程的模式/方式?

时间:2018-01-03 07:36:35

标签: java spring

我在服务器端有一个Java和Spring应用程序。该服务器具有很少的模块,其中一个负责一个流程执行。模块中的一个具有从一个端点开始并且步骤很少的过程。

这样的事情:

@RestController
@AllArgsConstructor
@RequestMapping(value = "movie")
public class MovieController {

    private final MovieService movieService;

    @GetMapping("step1")
    public ResponseEntity step1() {
        return movieService.step1();
    }

    @GetMapping("step2")
    public ResponseEntity step2() {
        return movieService.step2();
    }

    @GetMapping("step3")
    public ResponseEntity step3() {
        return movieService.step3();
    }

    @GetMapping("step4")
    public ResponseEntity step4() {
        return movieService.step4();
    }

    @GetMapping("step5")
    public ResponseEntity step5() {
        return movieService.step5();
    }
}

如您所见,在这种情况下,每个步骤都可以从UI启动。但是现在我需要添加从一个端点运行所有步骤的能力。所有步骤都取决于上一步骤的状态,如果上一步骤失败,则永远不必开始下一步骤。这就是为什么我在寻找执行所有步骤的最佳方式。

我不喜欢这样:

@PostMapping("run")
public ResponseEntity runProcess() {
    movieService.step1();
    movieService.step2();
    movieService.step3();
    movieService.step4();
    return movieService.step5();
}

我想到了Spring Batch,我可以将movieService的每个方法分离到Spring Batch Steps,但是有什么意义吗?

实施此类问题的正确方法是什么?

3 个答案:

答案 0 :(得分:2)

我会选择State pattern和一个类来嵌入逻辑。因此,您可以根据需要多次调用更改状态函数,也可以在模式中嵌入逻辑("如果出现故障")。

答案 1 :(得分:0)

Spring MVC附带AbstractWizardFormController类,可以轻松处理向导形式;

See an example here

public class UserController extends AbstractWizardFormController{

    public UserController(){
        setCommandName("userForm");
    }

    @Override
    protected Object formBackingObject(HttpServletRequest request)
        throws Exception {

        return new User();
    }
    @Override
    protected ModelAndView processFinish(HttpServletRequest request,
        HttpServletResponse response, Object command, BindException errors)
        throws Exception {

        //Get the data from command object
        User user = (User)command;
        System.out.println(user);

        //where is the finish page?
        return new ModelAndView("ResultForm", "user", user);
    }

    @Override
    protected ModelAndView processCancel(HttpServletRequest request,
        HttpServletResponse response, Object command, BindException errors)
        throws Exception {

        //where is the cancel page?
        return new ModelAndView("WelcomePage");
    }

    @Override
    protected void validatePage(Object command, Errors errors, int page) {

        UserValidator validator = (UserValidator) getValidator();

        //page is 0-indexed
        switch (page) {
           case 0: //if page 1 , go validate with validatePage1Form
            validator.validatePage1Form(command, errors);
            break;
           case 1: //if page 2 , go validate with validatePage2Form
            validator.validatePage2Form(command, errors);
            break;
           case 2: //if page 3 , go validate with validatePage3Form
            validator.validatePage3Form(command, errors);
            break;
        }
    }
}

答案 2 :(得分:0)

您可以创建自定义异常,并在每种方法失败时抛出该异常。例如。

<强>服务

   public ResponseEntity step...() {
        if(failure){
          throw new CustomException("Error can't complete step 1");
        }
        return movieService.step1();
    }

<强>控制器:

public String runProcess() {
    try {
        movieService.step1();
        movieService.step2();
        movieService.step3();
        movieService.step4();
        movieService.step5();
    }catch(CustomException e){
      return e.getMessage();
    }

}