Spring MVC:带有动态bean对象的输入表单

时间:2016-11-13 16:52:27

标签: spring spring-mvc model-view-controller controller

我有一个类的层次结构:Employee - > (经理,服务员,库克)。 我正在尝试使用Spring MVC控制器构建一个Web表单,以便能够在DB中创建并保存所有继承Employee的类型。 因此,在推送表单时,我必须将一些Model绑定到View(JSP - 页面)。问题是我的用户将使用{Waiter,Cook,Manager}的下拉列表决定要创建的类型。基于此信息,我想创建实例并将其保存在DB中。 我怎么做? 标准方法意味着我绑定一个这样的表单:

    @RequestMapping("/new_employee")
    public ModelAndView showEmployeeForm(){
            return new ModelAndView("new_employee","employee",new Employee());
    }

但是在处理表单的处理方法中,我将被迫创建给定类型的另一个实例。水木清华。像这样:

    String pos = webRequest.getParameter("position");
    Employee employee;
    switch (pos) {
            case "1":
                    employee = new Manager();
                    break;
            case "2":
                    employee = new Chef();
                    break;
            case "3":
                    employee = new Waiter();
                    break;
            default:
                    throw new RuntimeException();
    }

是否有更可爱和可接受的做法?

1 个答案:

答案 0 :(得分:3)

  

问题是我的用户将决定使用哪个类型创建   {Waiter,Cook,Manager}的下拉列表。根据这些信息我   想要创建实例并将其保存在DB中。

我认为你的目标是松散地将设计结合起来,以增加新的员工类型。创造与在不修改现有类的情况下保存逻辑,您需要按照以下步骤操作:

(1)创建员工界面或抽象类类型

(2)创建经理,服务员,厨师类型(所有实现/扩展员工类型)

(3)创建EmployeeService接口类型并实施ManagerServiceWaiterService等。通过编写create所涉及的特定逻辑(如下所述,这是添加的如果您为每种类型都有复杂的创建逻辑,则可以获得更大的灵活性)

(4)添加showEmployeeForm()& createEmployee() Controller EmployeeService使用ApplicationContext动态获取相应的ApplicationContext对象(根据用户选择的输入检索对象)。请注意,我们有单独的服务类(bean),我们使用create()来获取正确的bean(Waiter服务,Manager服务,Chef服务)来调用相应的@Component public class Manager implements Employee { //define props }

代码如下:

(1)创建员工界面或抽象类类型

(2)创建经理,服务员,厨师类(所有实施/扩展员工类型)

public interface EmployeeService {
   public void create();
}

(2)EmployeeService接口:

@Service("ManagerService")
public class ManagerService extends EmployeeService {
   public void create(Manager manager) {
      //add Manager save logic
   }
}

** ManagerService类:**

@Service("WaiterService")
public class WaiterService extends EmployeeService {
   public void create(Waiter waiter) {
     //add Waiter save logic
   }
}

WaiterService类:

@Service("ChefService")
public void create(Chef chef) {
      //add Chef save logic
   }
}

ChefService类:

    @Controller
    public class EmployeeController {

        @Autowired
        private ApplicationContext appContext;

        @RequestMapping("/new_employee", method=RequestMethod.GET)
        public ModelAndView showEmployeeForm(){
          String position = webRequest.getParameter("position");

          Employee employee = (EmployeeService)appContext.getBean(position);
          //Put position to session
           session.setAttribute("position", position);
                return new ModelAndView("new_employee","employee", employee);
        }

        @RequestMapping("/create", method=RequestMethod.POST)
        public ModelAndView createEmployee() {

           //Get position from session and then getBean
           String position = session.getAttribute("position");
           EmployeeService empService = (EmployeeService)appContext.getBean(position);

           empService.create();
        }
    }

(3)控制器类方法:

var counter=0;
function call(number=-1){
  counter +=number;
  if(counter==0){
  alert("finished");
  }}
  

P.S。:我已经添加了具有不同EmployeeService类型的服务层   为了获得额外的灵活性,但是你可以使用它(原样)或者   这取决于你的create()逻辑的复杂程度   不同的员工类型。

<强>更新: 如果用户想要添加新类型的员工,那么在没有编程的情况下创建类型是不可能的吗?

以上设计符合/符合流行的OOP Open/Closed principle,它表示我们应该能够在不修改现有类的情况下添加新类(新员工类型或新功能)。因此,您可以添加任意数量的新员工类型,而无需修改现有类。