【问题标题】:Get bean from select tag on jsp page从jsp页面上的select标签获取bean
【发布时间】:2015-02-24 11:53:27
【问题描述】:

我在我的项目中使用 Spring、jsp 和 Hibernate。我有两个实体 EmployeeDepartment。部门是员工的一部分,他们是一对多的关系

    @Entity
    @Table(name = "employee")
    public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    @OneToOne
    @JoinColumn(name = "dep_id")
    private Department department;

我为视图创建控制器、DAO 和 jsp 页面。

我的问题:我想在我的 jsp 页面中更新 Employee 的数据。在此之前,我在模型中添加员工和部门列表

在控制器中:

 model.addAttribute("employee", employeeDao.find(id));
 model.addAttribute("departments", departmentDao.list());

在 JSP 中:

<form method="post">
   <select value="${employee.department}">
     <c:forEach items="${departments}" var ="dep">
        <option value="${dep}">${dep.name}</option>
     </c:forEach>
</form>

在控制器中(发布请求)

@RequestMapping(value = "/{id}", method = RequestMethod.POST)
    public String updateEmployee(@PathVariable("id") long id, Employee employee) {
        employee.setId(id);
        employeeDao.update(employee);

        return "redirect:/employees";
    }

但价值 employee.department=null 为什么?

当然,在jsp页面的“select”标签中我可以创建变量dep我的意思是:

<select name ="dep">
   <option value="${dep.id}">${dep.name}</option>
</select>

然后在使用部门 ID 的控制器中,我将能够从数据库中获取部门并更新员工。方法对吗?

【问题讨论】:

标签: java html spring jsp


【解决方案1】:

如果我们假设初始获取请求如下所示,您尚未发布完整的控制器:

@RequestMapping(value = "/{id}", method = RequestMethod.GET)
      public ModelAndView loadForEdit(@PathVariable("id") long id)
      model.addAttribute("employee", employeeDao.find(id));
      model.addAttribute("departments", departmentDao.list());
      return new ModelAndView(...);
}

然后在loadForEdit() 上,我们加载一个员工和部门进行编辑,并将它们设置在模型中以呈现编辑页面。

现在,在提交时,POST 方法 updateEmployee(...) 对之前的 Employee 和 Department 一无所知,因此框架只是将一个新实例传递给 updateEmployee(...)。

如果您按照以下内容进行重构,那么在调用 GET 和 POST 处理程序时,将执行带有 @ModelAttribute(value = "employee") 注释的方法。在第一种情况下,它将像以前一样添加到模型中,在第二种情况下,将检索 Employee,然后将绑定到更新值 amd 的字段传递给您的 POST 处理程序。

@RequestMapping(value = "/{id}", method = RequestMethod.Get)
public String loadForEdit(){
    return "nextView";
}

@RequestMapping(method = RequestMethod.POST)
public String updateEmployee(value = "/{id}", @ModelAttribute("employee") Employee employee)   
{
    return "redirect:/employees";
}

@ModelAttribute(value = "employee") 
public Employee getEmployee(@PathVariable("id") long id) 
{ 
    return  employeeDao.find(id);
}

@ModelAttribute(value = "departments") 
public List<Department>  getDepartments() 
{ 
    return  departmentDao.list());
}

在处理这个问题上有很大的灵活性:

请参阅“在方法参数上使用 @ModelAttribute”:

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html

@RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method =
> RequestMethod.POST) public String processSubmit(@ModelAttribute Pet
> pet) { } 

根据上面的例子,Pet 实例是从哪里来的? 有几种选择:

  1. 由于使用了@SessionAttributes,它可能已经在模型中 — 见 名为“使用@SessionAttributes 存储模型属性”的部分 在请求之间的 HTTP 会话中”。
  2. 它可能已经在模型中 由于同一控制器中的 @ModelAttribute 方法 — 解释 在上一节中。 [我的建议]
  3. 可以根据 URI 模板检索 变量和类型转换器(下面更详细地解释)。
  4. 可以使用其默认构造函数对其进行实例化。 [当前位置]

【讨论】:

    【解决方案2】:

    抱歉,我忘了公布解决的决定。感谢所有帮助我找到正确解决方案的人。 在控制器中:

     @RequestMapping(value = "/{id}", method = RequestMethod.GET)
        public String getEmployee(@PathVariable("id") long id, Model model) {
            model.addAttribute("employee", employeeDao.find(id));
            model.addAttribute("departments", departmentDao.list());
            return "employees/view";
        }
    

    然后我们需要编辑视图。在 JSP 页面上:

    <%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%>
    
    <sf:form modelAttribute="employee" method="post">
       <sf:select path="department" id="select-departments"  >
         <c:forEach items="${departments}" var="dep" varStatus="status">
           <option value="${dep.id}">${dep.name}</option>
         </c:forEach>
       </sf:select>
    </sf:form>
    

    我们还需要创建部门的编辑器:

    public class DepartmentEditor extends PropertyEditorSupport {
    
        private DepartmentDao departmentDao;
    
        public DepartmentEditor(DepartmentDao departmentDao) {
            this.departmentDao = departmentDao;
        }
    
        @Override
        public void setAsText(String text) throws IllegalArgumentException {
            long id = Long.parseLong(text);
            Department department = departmentDao.find(id);
            setValue(department);
        }
    }
    

    然后我们需要在控制器中添加一些代码:

     @InitBinder
        protected void initBinder(WebDataBinder binder) {
            binder.registerCustomEditor(Department.class, new DepartmentEditor(departmentDao));
        }
    @RequestMapping(value = "/{id}", method = RequestMethod.POST)
        public String updateEmployee(@PathVariable("id") long id, @ModelAttribute Employee employee) {
            employee.setId(id);
            employeeDao.update(employee);
            return "redirect:/employees";
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-26
      • 1970-01-01
      • 1970-01-01
      • 2016-04-19
      • 1970-01-01
      • 1970-01-01
      • 2013-11-29
      相关资源
      最近更新 更多