简体   繁体   English

从jsp页面上的select标签获取bean

[英]Get bean from select tag on jsp page

I use Spring, jsp and Hibernate in my project. 我在我的项目中使用Spring,jsp和Hibernate。 I have two entities Employee and Department . 我有两个实体员工部门 Dapartment is a part of Employee and they have relationship one-to-many Dapartment是Employee的一部分,他们有一对多的关系

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

I create controller, DAO and jsp pages for view. 我为视图创建了控制器,DAO和jsp页面。

My problem: I want to update data of Employee in my jsp page. 我的问题:我想在我的jsp页面中更新Employee的数据。 Before this I add Employee and list of departments in model 在此之前,我在模型中添加Employee和部门列表

In controller: 在控制器中:

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

In JSP: 在JSP中:

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

In controller (post request) 在控制器(发布请求)

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

        return "redirect:/employees";
    }

but value employee.department=null Why? 但是值employee.department = null为什么?

Of course, on jsp page in "select" tag I can create variable dep I mean: 当然,在“select”标签的jsp页面上我可以创建变量dep我的意思是:

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

and then in controller using id of department i will be able to get department from database and update Employee. 然后在使用部门ID的控制器中,我将能够从数据库获取部门并更新Employee。 Is it right way? 这是对的吗?

You have not posted your full Controller however if we assume the initial get request looks like: 您尚未发布完整的Controller,但是如果我们假设初始获取请求如下所示:

@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(...);
}

Then on loadForEdit() we load an Employee and Departments for edit and set them in the model for rendering the edit page. 然后在loadForEdit()加载一个Employee和Departments进行编辑,并在模型中设置它们以呈现编辑页面。

Now, on submit, the POST method updateEmployee(...) knows nothing about this previous Employee and Department and therefore the framework is simply passing in a new instance to updateEmployee(...). 现在,在提交时,POST方法updateEmployee(...)对此前一个Employee和Department一无所知,因此框架只是将一个新实例传递给updateEmployee(...)。

If you refactor along the lines of the following, then on the call to both the GET and POST handlers, the method annotated with @ModelAttribute(value = "employee") will execute. 如果您按照以下方式进行重构,那么在调用GET和POST处理程序时,将执行使用@ModelAttribute(value =“employee”)注释的方法。 In the first case it will be added to the model, as previously, and in the second case the Employee will be retrieved, the fields bound to the updated values amd will then be passed to your POST handler. 在第一种情况下,它将被添加到模型中,如前所述,在第二种情况下将检索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());
}

There is a lot of flexibility on how you can handle this: 如何处理这个问题有很多灵活性:

See 'Using @ModelAttribute on a method argument' in: 请参阅:在方法参数中使用@ModelAttribute:

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html 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) { } 

Given the above example where can the Pet instance come from? 鉴于以上示例,Pet实例可以来自何处? There are several options: 有几种选择:

  1. It may already be in the model due to use of @SessionAttributes — see the section called “Using @SessionAttributes to store model attributes in the HTTP session between requests”. 由于使用@SessionAttributes,它可能已经在模型中 - 请参阅“使用@SessionAttributes在请求之间的HTTP会话中存储模型属性”一节。
  2. It may already be in the model due to an @ModelAttribute method in the same controller — as explained in the previous section. 由于同一控制器中的@ModelAttribute方法,它可能已经在模型中 - 如上一节中所述。 [My suggestion] [我的建议]
  3. It may be retrieved based on a URI template variable and type converter (explained in more detail below). 可以基于URI模板变量和类型转换器来检索它(下面更详细地解释)。
  4. It may be instantiated using its default constructor. 它可以使用其默认构造函数进行实例化。 [current position] [当前位置]

Sory, I forgot to publish the decision to solve. 索里,我忘了发表解决的决定。 Thanks to all who helped me to find right solution. 感谢所有帮助我找到正确解决方案的人。 In controller: 在控制器中:

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

Then we need to edit view. 然后我们需要编辑视图。 On JSP-page: 在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>

We also need to create department's editor: 我们还需要创建部门的编辑器:

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

And at the and we need to add some code in controller: 并且我们需要在控制器中添加一些代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM