Bem acredito que eu não esteja usando boas praticas hehehe, mas uso uma div para mensagem da classe e outra pra mensagens do hibernate/vraptor.
esse metodo envia a mensagem após ação: result.include("mensagem", "Usuário já registrado");
esse imprime a mensagem no jsp:
<div >
${mensagem}
</div>
Validações do hibernate com anotations:
Esse pega erros de validação do hibernate:
<c:forEach var="error" items="${errors}">
<li><label class="erro">${error.message}</label></li>
</c:forEach>
Aí, quando adiciono o cliente, se der algum erro no registro do banco ele usa o forEach, e se ele executar a ação normalmente ele usa a DIV.
Não, você deve usar esse form que eu te passei, apenas alterando o endereço da tua action. Não ví teu JSP, mas pelo que noto dos erros rotineiros do pessoal no GUJ, sempre esquecem de colocar o enctype.
Já com o File foto anotado no Modelo(Cliente), input no jsp “file” e a função adiciona prontinha, queria saber como é que eu adiciono a rotina de inclusão do arquivo no Banco de Dados.
Ta aí o metodo que joga as informações no banco, a rotina de enviar aquivo pro banco entra aqui nesse metodo?
public void adiciona(Cliente cliente){
try{
validator.validate(cliente);
validator.onErrorUse(page()).of(ClienteController.class).cadastracliente();
new ClienteDao().adiciona(cliente);
result.include("mensagem", "Cliente cadastrado com sucesso");
result.use(Results.logic()).redirectTo(ClienteController.class).cadastracliente();
}catch (ConstraintViolationException e) {
result.include("mensagem", "Usuário já registrado");
result.use(Results.logic()).redirectTo(ClienteController.class).cadastracliente();
}
}
Depois que eu reparei q é o método para salvar o Cliente, que por sua vez possui campo Blob.
No fórum eu já vi método para salvar esse tipo de campo.
Desculpa a confusão. =)
Realmente, estava sem o io, adicionei o jar, removi a anotation de NotEmpty e ele cadastra no banco beleza, só que em vez de enviar o arquivo, aparece [BLOB - 0Bytes], será que falta algum metodo?
Provavelmente falta você gravar as informações dentro desse blob.
O Vraptor te retorna um objeto UploadFile (ou algo assim), sendo que o método getFile te retorna um InputStream. Usando o org.apache.commons.io.IOUtils.toByteArray(java.ui.InputStream) você pode obter um array de bytes para gravar nesse campo blob, assim o JPA salva para você o conteúdo do arquivo.
O JPA não consegue trabalhar direto com File, você precisa usar byte ao invés de File. Troque isso:
private File foto;
Por isso:
Assim o JPA vai serializar o conteúdo da foto para o banco de dados.
Além disso deixo duas obversações/dicas: sempre feche os streams, e veja se você não pode deixar o atributo de foto do cliente em outra classe, pois se você deixar na mesma tabela que os outros dados dependendo do tamanho do seu sistema pode ficar muito lento.
Vc viu o final do tópico Garcia? :lol:
Tá resolvido, só que eu não uso Blob, salvo numa pasta e gravo o nome, descrição e nome das fotos no banco. Fiz relacionamento @OneToMany entre imóvel e fotos, o que poderia ser feito pelo mdBatera tb.
Rapaz estive analisando aqui, e decidi que quero fazer exatamente isso!
Pelo o que garcia me falou não é bom eu colocar a imagem na mesma tabela do cadastro, ai faria outra tabela com id e o caminho da imagem e cadastraria o id da imagem com o id do cadastro não é isso?
Meu problema é, não tenho ideia de qual função e aonde chamar o arquivo, se é no controller ou criar um novo pacote ou nova classe no controller “upload”, estou perdido.
Se tu estás falando do ònibus, ví sim. Curto um monte carros/ônibus antigos. Quando faço o trajeto Porto Alegre / Caxias do Sul tem um lugar que tem dois daqueles rabecão dos caça fantasmas. Um dia desses quero passar lá para namorar um pouco os modelos, hahah. O modelo é um Cadilac Eldorado Ambulance.
Vocẽ precisará mudar pouca coisa. O que eu faço é ter uma classe chamada BinaryFile que tem um id, o conteúdo do arquivo, contenttype, etc.
[code]public class BinaryFile {
@Id
@GeneratedValue
private Long id;
private String name; //nome do arquivo
@Lob
private byte[] content; //conteúdo do arquivo
@Temporal(TemporalType.TIMESTAMP)
private Date creationDate; // data da criação
private String contentType; // cabeçalho mime do arquivo
[...]
}[/code]
Depois você relaciona o BinaryFile como OneToOne com o cliente:
Para você fazer o upload pode modificar seu controller para isso aqui:
[code] public void restore(UploadedFile file) {
InputStream input = file.getFile(); // abre o stream para ler o arquivo
byte[] content = IOUtils.toByteArray(input); // lê o conteúdo
IOUtils.closeQuietly(input); // fecha o stream