Hi I am new to Grails and PostgreSQL. I am trying to make a form that stores user's data and I want to be able to upload multiple photos.
service:
Cars carInstance = new Cars()
carInstance.carimg = params.carimg.getBytes()
gsp:
<input type="file" id="carimg" name="carimg" multiple />
and I call saveCar
action in controller that save all the data user will input.
And I want to display the data with the image in a showCar
gsp this way :
<img src="${createLink(controller: 'garage', action: 'getImage', params: ['id': Cars.id])}"/>
The getImage
action which gets the image and passes it to on to gsp is this :
def getImage(){
def item = Cars.get(params.id.toLong())
byte[] imageInByte=item.carimg
response.contentType = 'image/png'
response.outputStream << imageInByte
response.outputStream.flush() }
In the gsp it appears as a blank border with an image in left corner that means image not found probably. If I convert binary data to string it displays the correct photo name. Any suggestions? The problem is in the way I store the image or the way I try to display a binary data to image?
What is Cars.id
in your case? Maybe it is an array of cars and you need to iterate over it?
<g:each in="${Cars.list()}" var="car">
<img src="${createLink(controller: 'garage', action: 'getImage', params: ['id': car.id])}"/>
</g:each>
EDIT 1:
Based on your responses I create a sample grails(2.5.6) project.
Domain:
class Car {
String name
byte[] photo
static constraints = {
photo maxSize: 1024 * 1024 * 2
}
}
In Controller I have 2 methods:
def show(Car carInstance) {
respond carInstance
}
def showImage(int id) {
def item = Car.get(id)
byte[] imageInByte = item.photo
response.contentType = 'image/png'
response.outputStream << imageInByte
response.outputStream.flush()
}
And gsp page with:
<g:fieldValue bean="${carInstance}" field="name"/>
<img src="${createLink(controller: 'Car', action: 'showImage', params: [id: carInstance.id])}"/>
And image was rendered successfully.
EDIT 2:
Sorry, I miss what you try to do it with multiple images.
First of all you need to create additional Domain to store photos:
class CarPhoto {
byte[] photo
static belongsTo = [car: Car]
static constraints = {
photo maxSize: 1024 * 1024 * 2
}
}
and add this dependencies to Car Domain:
class Car {
String name
static hasMany = [photos: CarPhoto]
static constraints = {}
}
After that you need to apply those changes to showImage action:
def showImage(long id, long photo_id) {
def car = Car.get(id)
def photo = CarPhoto.findByCarAndId(car, photo_id)
byte[] imageInByte = photo.photo
response.contentType = 'image/png'
response.outputStream << imageInByte
response.outputStream.flush()
}
And to the gsp page:
<g:each in="${carInstance.photos}" var="photo">
<img src="${createLink(controller: 'Car', action: 'showImage', params: [id: carInstance.id, photo_id: photo.id])}"/>
</g:each>
Also you need to change your upload methods. You can find info here.