Classe fundido excepção no Groovy
-
16-09-2019 - |
Pergunta
Eu quero fazer upload de uma imagem usando um Groovy on Grails. A página do meu gsp é a seguinte (estou mostrando uma versão simplificada do original)
<g:form controller="post" action="save" enctype="multipart/form-data">
My picture <input type="file" name="myPicture" />
<g:submitButton name="submit" value="Save"/>
</g:form>
A minha classe de domínio é o seguinte:
class Post {
byte[] myPicture
static mapping = {
myPicture type: "blob"
}
Eu preciso desse mapeamento de outra forma o MySQL irá criar um smallblob que é pequeno para caber as imagens
static constraints = {
myPicture(nullable:false)
}
}
No controlador eu tenho uma ação chamada de economia que é a seguinte:
def save = {
def post = loadPost(params.id)
post.properties = params
if(post.save()) {
print "hallo world"
redirect(action:'list', params:params)
} else {
render(view:'edit', model:[post:post])
}
}
A exceção é lançada quando eu tentar salvar a imagem no DB.
2009-04-27 18:16:07,319 [20806951@qtp0-0] ERROR errors.GrailsExceptionResolver - java.lang.ClassCastException: [B cannot be cast to java.sql.Blob
org.codehaus.groovy.runtime.InvokerInvocationException: java.lang.ClassCastException: [B não pode ser convertido para java.sql.Blob
Qualquer dica por que é isso?
BTW, eu já vi em um tutorial que as imagens foram tratadas como strings, mas não funcionou também.
Solução
tentar desta forma:
def save = {
def post = loadPost(params.id)
def f = request.getFile('myPicture')
post.myPicture = f.getBytes()
post.pictureType = f.getContentType()
if(post.save()) {
Outras dicas
Eu encontrei uma pergunta semelhante em Nabble:
http://www.nabble.com/MySQL-and-Blobs -td16116885.html
Duas soluções possíveis são sugeridas:
- Alterar as restrições de propriedade blob para um grande tamanho máximo, para impedi-lo de usar "TINYBLOB".
- Use a implementação Hibernate Blob em vez de byte [] para o tipo de declaração da propriedade. Isso exigirá que você transmitir dados para o Blob, em vez de atribuição direta, mas o post acima dá código para fazê-lo.
Você pode tentar usar da Primavera MultipartFile dentro do seu método loadPost()
?
Aqui está um exemplo do docs :
def upload = {
def f = request.getFile('myFile')
if(!f.empty) {
f.transferTo( new File('/some/local/dir/myfile.txt') )
response.sendError(200,'Done');
}
else {
flash.message = 'file cannot be empty'
render(view:'uploadForm')
}
}
Eu acredito que você pode acessar f.bytes
diretamente.