Olá, estou estendendo o exemplo do curso para tornar mais próximo de um sistema real e explorar outras funcionalidades,a intenção é que quando estiver pronto esse código seja disponibilizado para ajudar outras pessoas.
criei uma tela de cadastro de clientes, clientes tem uma relação bi direcional com endereços(um cliente pode ter vários endereços), na tela eu tenho os campos referentes ao cadastro do cliente e uma lista referente aos seus endereços:
lista.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>Lista de Clientes</title>
<link rel="stylesheet" type="text/css"
href="../bootstrap/css/bootstrap.css">
<link rel="stylesheet" type="text/css" href="../base.css">
<style type="text/css">
.link {
text-decoration: underline;
border: none;
background: none;
color: blue;
cursor: pointer;
}
</style>
</head>
<body>
<c:if test="${not empty mensagem}">
<div class="alert alert-success">${mensagem}</div>
</c:if>
<table class="table table-stripped table-bordered table-hover">
<thead>
<tr>
<th>Nome</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<c:forEach items="${clienteList}" var="cliente">
<tr>
<td>${cliente.nome}</td>
<td><a href="<c:url value="/cliente/${cliente.id}"/>">Editar</a></td>
<td>
<form action='<c:url value="/cliente"/>' method="post">
<input name="cliente.id" value="${cliente.id}" type="hidden" />
<button class="link" type="submit" name="_method" value="DELETE">remover</button>
</form>
</td>
</tr>
</c:forEach>
</tbody>
</table>
<a href="<c:url value='/cliente/criar'/>">Novo Cliente</a>
</body>
</html>
criar.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<link rel="stylesheet" type="text/css"
href="../bootstrap/css/bootstrap.css">
<link rel="stylesheet" type="text/css" href="../base.css">
<script type="text/javascript" charset="utf-8"
src="${pageContext.request.contextPath}/js/jquery.min.js"></script>
<script type="text/javascript" charset="utf-8"
src="${pageContext.request.contextPath}/js/scripts.js"></script>
</head>
<body>
<div class="container">
<h1>Novo Cliente</h1>
<form action="<c:url value="/cliente"/>" method="post">
<%@ include file="formulario.jsp"%>
<input type="submit" class="btn btn-primary" value="Adicionar" />
</form>
</div>
</body>
</html>
editar.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<link rel="stylesheet" type="text/css"
href="../bootstrap/css/bootstrap.css">
<link rel="stylesheet" type="text/css" href="../base.css">
<script type="text/javascript" charset="utf-8"
src="${pageContext.request.contextPath}/js/jquery.min.js"></script>
<script type="text/javascript" charset="utf-8"
src="${pageContext.request.contextPath}/js/scripts.js"></script>
</head>
<body>
<div class="container">
<h1>Editar Cliente</h1>
<form action="<c:url value="/cliente/${cliente.id}"/>" method="post">
<%@ include file="formulario.jsp"%>
<button type="submit" class="btn btn-primary" name="_method" value="PUT" >Atualizar</button>
</form>
</div>
</body>
</html>
formulario.jsp
Nome: <input class="form-control" type="text" name="cliente.nome" value="${cliente.nome}" />
<fieldset id="artista-container" style="width: 300px;">
<legend>
Endereços
<img src="${pageContext.request.contextPath}/img/adicionar.png" alt="+" onclick="adicionar();" />
</legend>
<c:forEach items="${cliente.enderecos}" var="endereco" varStatus="status">
<div class="artista">
<label>Logradouro:</label>
<input type="text" name="cliente.enderecos[${status.index}].logradouro" value="${endereco.logradouro}" />
<label>Bairro:</label>
<input type="text" name="cliente.enderecos[${status.index}].bairro" value="${endereco.bairro}" />
<input type="hidden" name="cliente.enderecos[${status.index}].id" value="${endereco.id}" />
<img src="${pageContext.request.contextPath}/img/remover.png" alt="-" class="button-remover" />
</div>
</c:forEach>
</fieldset>
<br/>
scripts.js
var model =
'<div class="artista">' +
'<label>Nome:</label>' +
'<input type="text" name="cliente.enderecos[0].logradouro" />' +
'<label>Bairro:</label>' +
'<input type="text" name="cliente.enderecos[0].bairro" />' +
'<img src="${pageContext.request.contextPath}/img/remover.png" alt="-" class="button-remover" />' +
'</div>';
$('.button-remover').live('click', function() {
$(this).parent().remove();
reorderIndexes();
});
function adicionar() {
$('#artista-container').append(model);
reorderIndexes();
};
function reorderIndexes() {
var regex = /\[[0-9]\]/g;
$('.artista').each(function(index) {
var $campos = $(this).find('input'), $input ,name ;
$campos.each(function() {
$input = $(this),
name = $input.attr('name');
$input.attr('name', name.replace(regex, '[' + index + ']'));
});
});
};
e por fim o controller
@Controller
public class ClienteController {
private final Result result;
private final ClienteDao dao;
private final Validator validator;
public ClienteController() {
this(null,null,null);
}
@Inject
public ClienteController(Result result, ClienteDao dao,Validator validator) {
this.result = result;
this.dao = dao;
this.validator = validator;
}
@Get
public void criar(){}
@Get
public List<Cliente> lista() {
return dao.lista();
}
@Post("/cliente")
public void adiciona(@Valid Cliente cliente) {
validator.onErrorUsePageOf(this).criar();
for(Endereco e :cliente.getEnderecos()){
e.setCliente(cliente);
}
dao.adiciona(cliente);
result.include("mensagem", "cliente adicionado com sucesso!");
result.redirectTo(this).lista();
}
@Put("/cliente/{cliente.id}")
public void altera(@Valid Cliente cliente) {
validator.onErrorUsePageOf(this).criar();
for(Endereco e :cliente.getEnderecos()){
e.setCliente(cliente);
}
dao.atualiza(cliente);
result.redirectTo(this).lista();
}
@Delete
@Path("/cliente")
public void remove(Cliente cliente){
Cliente clienteToRemove = dao.busca(cliente);
dao.remove(clienteToRemove);
result.redirectTo(this).lista();
}
@Get("/cliente/{id}")
public void edita(Long id) {
result.include("cliente",dao.carrega(id));
}
}
O código acima funciona, no entanto toda vez , tanto no incluir quanto no alterar eu tenho que percorrer o array de endereços do cliente e setar o cliente no endereço dentro do controller, a questão é, é correto implementar desta forma? não tem como setar o cliente do endereço direto na view e eu receber no meu controller a coleção já preenchida corretamente da forma que o jpa espera?