Ни BindingResult, ни простой целевой объект для имени компонента не доступны в качестве атрибута запроса при попытке загрузить модальный элемент начальной загрузки - PullRequest
0 голосов
/ 07 января 2019

В моем JSP я пытаюсь загрузить модальный загрузчик, чтобы сохранить и отредактировать объекты с соответствующими методами пружинного контроллера и атрибутами модели. Но когда я добавляю этот модал, я получаю следующие ошибки. Когда вкладки меняются, следующий запрос передается контроллеру пружины, который затем передает модальный атрибут в представление и, если это так, показывается соответствующий модал.

http://localhost:8080/admin/setting/systemRole/load

Ошибка в журнале tomcat:

DEBUG org.springframework.web.servlet.DispatcherServlet - Could not complete request
org.apache.jasper.JasperException: An exception occurred processing JSP page /WEB-INF/jsp/settings.jsp at line 181

178:                 <form:form method="post" modelAttribute="user" action="save">
179:                     <div class="form-group">
180:                         <label class="col-form-label">User Name</label>
181:                         <form:input type="text" required="required" class="form-control" path="username"/>
182:                         <h6 class="fieldError"><form:errors path="username"/></h6>
183:                     </div>
184:                     <div class="form-group">

Но он отлично работает для следующего запроса, когда я переключаю вкладку на пользователей.

http://localhost:8080/admin/setting/systemUser/load

Когда я удаляю модальный код из кода, остальные части интерфейса работают нормально.

Вид (settings.jsp):

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<jsp:include page="header_new.jsp"/>

<div class="page-title-area">
    <div class="container-fluid">
       <div class="row">
           <div class="col-sm-11 col-sm-offset-1 page-title-section">
               <h2 class="page-title">
                  <span>Settings</span>
               </h2>
                <ul class="page-title__nav common-list nav nav-tabs" style="margin-bottom: -5px">
                   <li <c:if test="${userTabActive}"> class="active" </c:if>><a data-toggle="tab"
                                                                             onclick="loadUsers()">Users</a></li>
                   <li <c:if test="${roleTabActive}"> class="active" </c:if>><a data-toggle="tab"
                                                                             onclick="loadRoles()">Roles</a></li>
                </ul>
            </div>
        </div>
    </div>
 </div>

<script>

    function loadUsers() {
       window.location = '/admin/setting/systemUser/load';

   }

    function loadRoles() {
       window.location = '/admin/setting/systemRole/load';

}

    $(document).ready(function () {
       $('#usersTable').DataTable({})
       $('#rolesTable').DataTable({})
    });

    function loadUser(id) {
       window.location = 'loadUser?id=' + id;
   }

    function loadRole(id) {
       window.location = 'loadRole?id=' + id;
   }


    function deleteUser(id) {
       $('#user-id').val(id);
    $('#userDeleteModal').modal("show");
}

    var checkPasswords = function () {
    if (document.getElementById('password').value ==
        document.getElementById('confirm-password').value) {
        document.getElementById('passwordsMatchMessage').style.color = 'green';
        document.getElementById('passwordsMatchMessage').innerHTML = 'Passwords are matching';
        document.getElementById("submitButton").disabled = false;
    } else {
        document.getElementById('passwordsMatchMessage').style.color = 'red';
        document.getElementById('passwordsMatchMessage').innerHTML = 'Passwords are not matching';
        document.getElementById("submitButton").disabled = true;
       }
    }
</script>


<c:if test="${loadUserModal}">
   <script>
      window.alert("user edit modal");
      $("#userSaveModal").modal()
      document.getElementById('userModalLabel').innerHTML = 'Edit User';
      document.getElementById('password').value = '';
   </script>
</c:if>

<c:if test="${saveUser}">
    <script>
       window.alert("user save modal");
       $("#userSaveModal").modal()
       document.getElementById('userModalLabel').innerHTML = 'Save User';
    </script>
</c:if>

<c:if test="${loadRoleModal}">
    <script>
       window.alert("role modal");
       $("#roleSaveModal").modal()
       document.getElementById('roleModalLabel').innerHTML = 'Save Role';
    </script>
</c:if>

<!-- Begin page content -->
<div class="container-fluid">
   <div class="row">
       <jsp:include page="components/common/sidemenu.jsp">
        <jsp:param name="activeTab" value="settings"/>
       </jsp:include>
     <div class="tab-content">
        <div id="merchants" class="tab-pane fade active">
            <c:if test="${errorView ne 'E1020'}">
                <div class="col-md-11 col-md-offset-1">
                    <div class="page-card" style="padding-right: 20px;margin-left: 20px;margin-top: 20px">
                     </div>
                 </div>
              </c:if>
          </div>
       </div>
    </div>
</div>

<c:if test="${viewUsers}">
    <div class="tab-content">
        <div class="tab-pane fade in active">

         <div class="container-fluid">
            <div style="padding-top: 10px; padding-right: 20px">
                <button type="button" class="btn btn-primary" style="float: right;" onclick="loadUser(0)"><i
                        class="fa fa-plus" style="margin-right: 5px"></i>New User
                </button>
            </div>
            <div class="row">
                <div class="col-md-11 col-md-offset-1">
                    <div class="page-card">
                        <div class="page-card__body">
                            <div class="table-responsive">
                                <table id="usersTable" class="table table-bordered table-striped dataTable">
                                    <thead>
                                    <tr>
                                        <th>User Name</th>
                                        <th>Name</th>
                                        <th>Status</th>
                                        <th>Role</th>
                                        <th>Action</th>
                                    </tr>
                                    </thead>
                                    <tbody>
                                    <c:forEach items="${users}" var="user">
                                        <tr>
                                            <td>${user.username}</td>
                                            <td>${user.name}</td>
                                            <td>${user.state}</td>
                                            <td>${user.role.roleName}</td>
                                            <td>
                                                <button type="button" class="btn btn-primary" data-toggle="modal"
                                                        onclick="loadUser('${user.id}')">
                                                    <i class="fa fa-edit"></i> Edit
                                                </button>
                                                <button type="button" data-toggle="modal" id="delete"
                                                        onclick="deleteUser('${user.id}')" name="delete"
                                                        class="btn btn-danger">
                                                    <i class="fa fa-trash-o"></i> Delete
                                                </button>
                                            </td>
                                        </tr>
                                    </c:forEach>
                                    </tbody>
                                </table>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
         </div>
      </div>
   </div>
</c:if>

<c:if test="${viewRoles}">
   <div class="tab-content">
      <div class="tab-pane fade in active">

         <div class="container-fluid">
             <div style="padding-top: 10px; padding-right: 20px">
                 <button type="button" class="btn btn-primary" style="float: right;" onclick="loadRole(0)"><i
                        class="fa fa-plus" style="margin-right: 5px"></i>Add Role
                 </button>
             </div>
             <div class="row">
                <div class="col-md-11 col-md-offset-1">
                    <div class="page-card">
                        <div class="page-card__body">
                            <div class="table-responsive">
                                <table id="rolesTable" class="table table-bordered table-striped dataTable">
                                    <thead>
                                    <tr>
                                        <th>Name</th>
                                        <th>Permissions</th>
                                        <th>Action</th>
                                    </tr>
                                    </thead>

                                    <tbody>
                                    <c:forEach items="${roles}" var="role">
                                        <tr>
                                            <td>${role.roleName}</td>
                                            <td>
                                                <a href="#" data-toggle="popover" data-container="body"
                                                   data-content="<c:forEach var="permission" items="${role.permissionList}">
                                        ${permission.name}
                                    </c:forEach>">View Permissions</a>
                                            </td>
                                            <td>
                                                <button type="button" class="btn btn-primary" data-toggle="modal"
                                                        onclick="loadRole('${role.id}')">
                                                    <i class="fa fa-edit"></i> Edit
                                                </button>
                                                    <%--<button type="button" class="btn btn-primary" data-toggle="modal"--%>
                                                    <%--onclick="editRole('${role.id}','${role.roleName}')" ><i class="fa fa-edit"></i> Edit--%>
                                                    <%--</button>--%>
                                                    <%--<button type="button" data-toggle="modal" id="delete"--%>
                                                    <%--onclick="deleteRole('${role.id}')" name="delete" class="btn btn-danger">--%>
                                                    <%--<i class="fa fa-trash-o"></i> Delete--%>
                                                    <%--</button>--%>
                                            </td>
                                        </tr>
                                    </c:forEach>
                                    </tbody>
                                </table>
                            </div>
                        </div>
                    </div>
                </div>
             </div>
         </div>
      </div>
   </div>
</c:if>



<div class="modal fade" id="userDeleteModal" tabindex="-1" role="dialog" aria-labelledby="userDeleteModalLabel"
 aria-hidden="true">
   <div class="modal-dialog" role="document">
      <div class="modal-content">
         <div class="modal-header">
             <h5 class="modal-title" id="modalLabel">Delete Record</h5>
             <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                <span aria-hidden="true">&times;</span>
             </button>
          </div>
          <div class="modal-body">
            Are you sure you need to remove this record ?
          </div>
          <form id="systemUserDeleteForm" method="post" class="w3-margin" action="remove">
             <input style="visibility: hidden !important;" id="user-id" name="id">

            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
                <button type="submit" class="btn btn-primary">Delete</button>
             </div>
          </form>
       </div>
   </div>
</div>


<div class="modal fade" id="userSaveModal" tabindex="-1" role="dialog" aria-labelledby="userSaveModalLabel"
 aria-hidden="true">
   <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
            <div class="col-md-4">
                <h5 class="modal-title" id="userModalLabel"></h5>
            </div>
            <div class="col-md-8">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
         </div>
         <div class="modal-body">
            <form:form method="post" modelAttribute="user" action="save">
                <div class="form-group">
                    <label class="col-form-label">User Name</label>
                    <form:input type="text" required="required" class="form-control" path="username"/>
                    <h6 class="fieldError"><form:errors path="username"/></h6>
                </div>
                <div class="form-group">
                    <label for="name" class="col-form-label">Name</label>
                    <form:input type="text" required="required" class="form-control" path="name"/>
                    <h6 class="fieldError"><form:errors path="name"/></h6>
                </div>
                <div class="form-group">
                    <label>Role</label>
                    <form:select class="form-control"
                                 required="required" path="role.id">
                        <c:forEach items="${roles}" var="role">
                            <form:option value="${role.id}" label="${role.roleName}" />
                        </c:forEach>
                    </form:select>
                </div>
                <div class="form-group">
                    <label for="state">Status</label>
                    <form:select class="form-control"
                                 required="required" path="state">
                        <form:option value="ACTIVE" label="ACTIVE"/>
                        <form:option value="INACTIVE" label="INACTIVE"/>
                    </form:select>
                </div>
                <c:if test="${saveUser}">
                    <div class="form-group">
                        <label class="col-form-label">Password</label>
                        <form:input onkeyup='checkPasswords();' type="password" class="form-control"
                                    path="password"/>
                        <h6 class="fieldError"><form:errors path="password"/></h6>
                    </div>
                    <div class="form-group">
                        <label class="col-form-label">Confirm Password</label>
                        <input onkeyup='checkPasswords();' type="password" class="form-control" />
                    </div>
                    <span id='passwordsMatchMessage'></span>
                </c:if>
                <c:if test="${not saveUser}">
                    <%--hidden input value is passed for editing record to avoid getting a null value for the password for user object--%>
                    <form:input type="hidden" path="password"/>
                </c:if>
                <form:input type="hidden" name="id" path="id"/>

                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                    <button type="submit" id="submitButton" class="btn btn-primary">Submit</button>
                </div>
             </form:form>
         </div>
      </div>
   </div>
</div>



<div class="modal fade" id="roleSaveModal" tabindex="-1" role="dialog" aria-labelledby="roleSaveModalLabel"
 aria-hidden="true">
   <div class="modal-dialog" role="document">
     <div class="modal-content">
        <div class="modal-header">
            <div class="col-md-4" style="float: left">
                <h5 class="modal-title" id="roleModalLabel"></h5>
            </div>
            <div class="col-md-8">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
        </div>
        <div class="modal-body">
            <form:form method="post" modelAttribute="role" action="save">
                <div class="form-group">
                    <label for="role-name" class="col-form-label">Role Name</label>
                    <form:input type="text" required="required" class="form-control" id="role-name"
                                path="roleName"/>
                    <h6 class="fieldError"><form:errors path="roleName"/></h6>
                </div>
                <div class="form-group">
                    <label class="col-form-label">Permissions</label>
                    <c:forEach items="${permissions}" var="permission">
                        <div class="check-box" style="padding-left: 20px">
                            <c:choose>
                                <c:when test="${permission.checked}">
                                    <form:checkbox value="${permission.id}"
                                                   path="checkedPermissions" checked="checked"/>
                                    <label style=" margin-left: 10px">${permission.name}</label>
                                </c:when>
                                <c:otherwise>
                                    <form:checkbox value="${permission.id}"
                                                   path="checkedPermissions"/>
                                    <label style=" margin-left: 10px">${permission.name}</label>
                                </c:otherwise>
                            </c:choose>
                        </div>
                    </c:forEach>
                </div>
                <form:input type="hidden" id="id" name="id" path="id"/>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                    <button type="submit" class="btn btn-primary">Submit</button>
                </div>
             </form:form>
         </div>
      </div>
   </div>
</div>

Контроллер пользователей:

@Controller
@RequestMapping("/setting/systemUser")
public class SystemUserController {

private final static Logger logger = LoggerFactory.getLogger(SystemUserController.class);

@Autowired
@Qualifier("systemUserValidator")
private Validator validator;
@Autowired
private SystemUserService systemUserService;
@Autowired
private SystemRoleService systemRoleService;
@Autowired
private UserDetailsHelper userDetailsHelper;

@InitBinder
private void initBinder(WebDataBinder binder) {
    binder.setValidator(validator);
}

@RequestMapping(value = "/load", method = RequestMethod.GET)
public String viewRoles(Model model) {
    loadData(model);
    return "settings";
}

@RequestMapping(value = "/save", method = RequestMethod.POST)
public String saveUser(Model model, @Validated @ModelAttribute("user") SystemUser user, BindingResult result) {
    logger.info("User save/update request received [{}]", user.toString());
    if (result.hasErrors()) {
        model.addAttribute("users", systemUserService.getAllUsers());
        model.addAttribute("roles", systemRoleService.getAllUserRoles());
        model.addAttribute("loadUserModal", true);
        return "settings";
    }
    systemUserService.saveSystemUser(user);
    loadData(model);
    return "settings";
}

@RequestMapping(value = "/remove", method = RequestMethod.POST)
public String deleteRole(Model model, @RequestParam("id") Long id) {
    SystemUser user = systemUserService.getSystemUser(id);
    logger.info("User remove request received [{}]", user.toString());
    systemUserService.deleteUser(user);
    loadData(model);
    return "settings";
}

@RequestMapping(value = "/loadUser", method = RequestMethod.GET)
public String loadUser(Model model, @RequestParam("id") Long id) {
    loadData(model);
    model.addAttribute("user", systemUserService.getSystemUser(id));
    model.addAttribute("loadUserModal", true);
    if (id == 0){
        model.addAttribute("saveUser", true);
    }
    model.addAttribute("userTabActive", true);
    model.addAttribute("viewUsers", true);
    return "settings";
}

private void loadData(Model model) {
    model.addAttribute("userDetails", userDetailsHelper.getSystemUser().getUsername());
    model.addAttribute("users", systemUserService.getAllUsers());
    model.addAttribute("roles", systemRoleService.getAllUserRoles());
    model.addAttribute("user", new SystemUser());
    model.addAttribute("userTabActive", true);
    model.addAttribute("viewUsers", true);
  }
}

Контроллер ролей:

@Controller
@RequestMapping("/setting/systemRole")
public class SystemRoleController {

@Autowired
@Qualifier("systemRoleValidator")
private Validator validator;
@Autowired
private SystemRoleService roleService;
@Autowired
private UserDetailsHelper userDetailsHelper;

@InitBinder
private void initBinder(WebDataBinder binder) {
    binder.setValidator(validator);
}

@RequestMapping(value = "/load", method = RequestMethod.GET)
public String viewRoles(Model model) {
    loadData(model);
    return "settings";
}

@RequestMapping(value = "/save", method = RequestMethod.POST)
public String saveRole(Model model, @Validated @ModelAttribute("role") SystemRole role, BindingResult result) {
    logger.info("Role save/update request received [{}]", role.toString());
    if (result.hasErrors()) {
        model.addAttribute("roles", roleService.getAllUserRoles());
        model.addAttribute("permissions", roleService.getAllPermission());
        model.addAttribute("loadRoleModal", true);
        return "settings";
    }
    roleService.saveSystemRole(role);
    loadData(model);
    return "settings";
}

@RequestMapping(value = "/delete", method = RequestMethod.POST)
public String deleteRole(Model model, @RequestParam("id") Long id) {
    roleService.deleteRole(roleService.getUserRole(id));
    loadData(model);
    return "settings";
}


@RequestMapping(value = "/loadRole", method = RequestMethod.GET)
public String loadRole(Model model, @RequestParam("id") Long id) {
    loadData(model);
    model.addAttribute("loadRoleModal", true);
    model.addAttribute("role", roleService.getUserRole(id));
    SystemRole role = roleService.getUserRole(id);
    model.addAttribute("permissions", roleService.getAllPermission(role));
    return "settings";
}


private void loadData(Model model) {
    model.addAttribute("roles", roleService.getAllUserRoles());
    model.addAttribute("permissions", roleService.getAllPermission());
    model.addAttribute("role", new SystemRole());
    model.addAttribute("userDetails", userDetailsHelper.getSystemUser().getUsername());
    model.addAttribute("roleTabActive", true);
    model.addAttribute("viewRoles", true);
   }

}

Класс модели SystemRole:

@Entity(name = "system_user_role")
public class SystemRole implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "name")
private String roleName;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
@JoinTable(name = "system_role_permission", joinColumns = {
        @JoinColumn(name = "id", nullable = false)},
        inverseJoinColumns = {@JoinColumn(name = "permission_id", nullable = false)})
private List<Permission> permissionList = new ArrayList<Permission>();

@Transient
private List<Long> checkedPermissions = new ArrayList<>();

public SystemRole() {
}

Виды HTML (при удалении модалов):

roles view

users view

Это не похоже на загрузку, когда модал добавлен. И модал удаления, кажется, работает нормально. Что здесь может пойти не так?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...