복붙노트

[SPRING] Spring MVC의 폼 사용 : 데이터를 바인딩하는 체크 박스

SPRING

Spring MVC의 폼 사용 : 데이터를 바인딩하는 체크 박스

이 주제에 관해 이미 질문이 있다는 것을 알고 있지만 다음 문제를 해결하는 방법을 찾지 못했습니다.

사용자 / 역할 관계가 있고 JSP에 사용 가능한 모든 역할을 확인란 항목으로 나열하려면 사용자에게 할당 된 확인란이 선택됩니다. 그러나 일치하는 항목은 검사되지 않습니다 (여기에서는 Spring 3.1을 사용하고 있습니다).

User 객체에서 추출 :

private Set<RoleEntity> roles = new HashSet<RoleEntity>();

Spring Controller에서 추출 (사용자 객체와 역할 목록을 Model에 추가) :

UserEntity userEntity = userEntityService.findById(UserEntity.class, new Long(id));
model.addAttribute("userAttribute", userEntity);

List<RoleEntity> roleList = roleEntityService.findAll();
model.addAttribute("roleList", roleList);

JSP에서 추출 :

<form:form modelAttribute="userAttribute" method="POST" action="${saveUrl}">
...

    <table align="center">
        <tr>
            <td>ID</td>
            <td>Role Name</td>
        </tr>
        <c:forEach items="${roleList}" var="role" varStatus="status">
            <tr>
                <td><form:checkbox path="roles" value="${role}" label="${role.id}" /></td>
                <td><c:out value="${role.name}" /></td>
            </tr>
        </c:forEach>
    </table>

...
</form:form>

Spring MVC 문서는 이것을 말한다 : 바운드 값이 array 또는 java.util.Collection 유형 인 경우 구성된 setValue (Object) 값이 바운드 Collection에 있으면 입력 (checkbox)은 'checked'로 표시됩니다.

그게 여기 없는가? 내가 여기서 무엇을 놓치고 있니?

고마워.

해결법

  1. ==============================

    1.내 생각 엔 RoleEntity 클래스에서 equals 및 hashcode 메서드에 대한 구현이 누락되었습니다.

    내 생각 엔 RoleEntity 클래스에서 equals 및 hashcode 메서드에 대한 구현이 누락되었습니다.

    이것은 맞지만 HashSet의 존재를 확인하기 위해서는 equals와 hashcode가 올바르게 구현되어 있어야합니다.

    그것이 문제인지를 확인하는 간단한 테스트와 마찬가지로이 줄을 다음과 같이 바꿉니다.

    model.addAttribute("roleList", roleList);
    

    이 행 :

    model.addAttribute("roleList", userEntity.getRoles());
    

    체크 박스를 모두 선택 했습니까? 그렇다면, 당신은 자신의 equals와 hashcode를 제공하지 않았으며, 기본 값이 사용되었다 (Object로부터 상속받은 것들).

    기본 동일성은 ID가 다른 변수와 동일한 인스턴스를 보유한다는 것을 의미하는 ID를 비교합니다. 평등이란 두 가지 다른 객체가 동일한 상태를 포함하거나 동일한 의미를 갖는 것을 의미합니다.

    model.addAttribute ( "roleList", userEntity.getRoles ())를 사용하면 기본 equals 메서드가 트리거되어 목록에 존재 여부를 확인하는 목록과 값이 동일하므로 두 개의 동일한 객체가 항상 동일하므로 true를 반환합니다.

    하지만 하나의 경우 userEntityService.findById를 사용하고 다른 객체를 의미하는 경우에는 roleEntityService.findAll을 사용합니다. 이 시점에서 정체성과 반대로 적절한 평등성 테스트를 사용해야합니다.

    당신은 equals / hashcode가 구현되어 있습니까?

    코드를 기반으로 다음은 작동하는 예제입니다.

    제어 장치:

    import java.util.Arrays;
    import java.util.Collections;
    import java.util.HashSet;
    import java.util.List;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    
    @Controller
    public class SomeController {
        @RequestMapping(value = "/something", method = { RequestMethod.GET, RequestMethod.POST })
        public String handle(Model model) {
    
            UserEntity userEntity = new UserEntity();
            userEntity.setRoles(new HashSet<RoleEntity>());
            Collections.addAll(userEntity.getRoles(), 
                                    new RoleEntity(1, "one"), 
                                    new RoleEntity(3, "three"));
            model.addAttribute("userAttribute", userEntity);        
    
            List<RoleEntity> roleList = Arrays.asList(
                                            new RoleEntity(1, "one"), 
                                            new RoleEntity(2, "two"), 
                                            new RoleEntity(3, "three")
                                        );
            model.addAttribute("roleList", roleList);
    
            return "view";
        }
    }
    

    사용자 등급 :

    import java.util.HashSet;
    import java.util.Set;
    
    public class UserEntity {
        private Set<RoleEntity> roles = new HashSet<RoleEntity>();
    
        public Set<RoleEntity> getRoles() {
            return roles;
        }
        public void setRoles(Set<RoleEntity> roles) {
            this.roles = roles;
        }
    }
    

    Roles 클래스 (equals 및 hashcode 메소드를주의 깊게 살펴보면 제거하면 더 이상 작동하지 않습니다).

    public class RoleEntity {
        private long id;
        private String name;
    
        @Override
        public int hashCode() {
            return new Long(id).hashCode();
        }
    
        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (! (obj instanceof RoleEntity)) {
                return false;
            }
            return this.id == ((RoleEntity)obj).getId();
        }
    
        public RoleEntity(long id, String name) {
            this.id = id;
            this.name = name;
        }
    
        public long getId() {
            return id;
        }
        public void setId(long id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
    

    전망:

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
    <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <form:form modelAttribute="userAttribute" method="POST" action="/something">
        <table align="center">
            <tr>
                <td>ID</td>
                <td>Role Name</td>
            </tr>
            <c:forEach items="${roleList}" var="role">
                <tr>
                    <td><form:checkbox path="roles" value="${role}" label="${role.id}" /></td>
                    <td><c:out value="${role.name}" /></td>
                </tr>
            </c:forEach>
        </table>
    </form:form>
    

    추신 JSP에 대한 하나의 관찰. 양식에 value = "$ {role}"을 수행하면 checkbox에 value = "your.pack.age.declaration.RoleEntity@1"과 같은 HTML 체크 박스 속성이 표시되어 나중에 다른 문제가 발생할 수 있습니다.

  2. from https://stackoverflow.com/questions/8700339/spring-mvc-usage-of-formcheckbox-to-bind-data by cc-by-sa and MIT license