В моем 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">×</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">×</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">×</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 (при удалении модалов):
Это не похоже на загрузку, когда модал добавлен. И модал удаления, кажется, работает нормально. Что здесь может пойти не так?