tutorial respond documentacion docs html grails

html - respond - grails documentation 3.3 2



Grails: muestra la imagen creada en gsp (8)

Soy muy nuevo en Grails, por lo que probablemente haya una respuesta muy simple a esta pregunta. Intento mostrar una imagen creada dinámicamente en un gsp. La imagen NO se almacena en una base de datos, se crea sobre la marcha en el controlador.

Lo que esencialmente tengo es un gsp que tiene un formulario que toma un conjunto de entradas de usuario (requestGraph.gsp). Al enviar el formulario, los parámetros se envían a la acción displayGraph en el controlador que consulta información de una base de datos completamente fuera de Grails y crea un gráfico utilizando la biblioteca JFreeChart. Me gustaría mostrar esta imagen dentro de displayGraph.gsp o algo así.

Básicamente, en requestGraph.gsp tengo un fragmento similar a:

<g:form action="displayGraph"> <!-- ... bunch of labels and boxes --> <g:submitButton name="displayGraph" value="Display Graph" /> </g:form>

Dentro del controlador tengo algo como:

def requestGraph = {} def displayGraph = { //... code that uses params to make an image byte array and assigns to var img return [image : img] }

Dentro de displayGraph.gsp:

<body> <h1>Graph Title</h1> <!-- ??? How to dislpay image? --> </body>

Intenté canalizar la imagen directamente a la secuencia de salida en la acción DisplayGraph. Esto funciona, pero luego pierdo el control de todos los formatos de página en displayGraph.gsp.

La mayoría de los tutoriales que he encontrado crean una acción dedicada para canalizar la imagen a un vapor de salida y luego llaman esa acción usando una etiqueta. El problema es que mi imagen no está almacenada en una base de datos y no veo forma de pasar la matriz de bytes de la imagen (o incluso los parámetros del formulario) para crear / renderizar la imagen. ¿Puede alguien ayudarme con esto? Gracias.


mi sugerencia en realidad tiene dos partes.

1) Use la solución recomendada por Rob anterior para generar el artefacto gráfico, sin embargo , guárdela en un archivo estático con un identificador único que se devuelve como parte de la respuesta del envío del formulario, luego renderizar el gráfico no es diferente que representar cualquier otra imagen.

Sugeriría que el identificador se construya a partir de los parámetros específicos pasados ​​en el formulario enviado para que puedan ser utilizados como un mecanismo de caché para volver a representar el gráfico sin reconstruirlo.

2) crear un servicio, tal vez un servicio de Quartz , que periódicamente limpia los gráficos estáticos que se crearon para la aplicación


Por alguna razón, las soluciones anteriores no muestran ninguna imagen. Solía:

<img src=''${createLink(controller: "myController", action: "displayGraph")}'' />

en lugar.


Si escribe los bytes en la secuencia de salida, puede tratar el controlador / acción como la fuente de la imagen en su GSP. Aquí hay un ejemplo rápido y no probado:

// controller action def displayGraph = { def img // byte array //... response.setHeader(''Content-length'', img.length) response.contentType = ''image/png'' // or the appropriate image content type response.outputStream << img response.outputStream.flush() }

A continuación, puede acceder a su imagen en el src de una etiqueta <img> como esta:

<img src="${createLink(controller: ''myController'', action: ''displayGraph'')}"/>

Actualización :

Después de volver a leer su pregunta, esto puede funcionar o no, parece que podría estar mostrando el gráfico como resultado de la presentación de un formulario. Esto solo funcionará si está almacenando el estado en el servidor en alguna parte (en lugar de solo obtenerlo de la única solicitud donde se envía el formulario). Si almacena suficiente estado en el servidor para generar el gráfico, entonces deberá proporcionar algunos parámetros adicionales a su controlador para obtener la imagen correcta, por ejemplo, src="${g.link(controller: ''myController'', action: ''displayGraph'', params: [''id'': 1234])}" , donde id es la forma de recuperar el estado del gráfico.


El siguiente código funciona en Grails 2.x.

HomeController.groovy

class HomeController { def index() { } def viewImage(){ def file = new File(params.title) def img = file.bytes response.contentType = ''image/png'' // or the appropriate image content type response.outputStream << img response.outputStream.flush() } }

views / home / index.jsp

<%@ page contentType="text/html;charset=ISO-8859-1" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/> <meta name="layout" content="main"/> <title>View Image</title> </head> <body> <div class="body"> <img src="<g:createLink controller="home" action="viewImage" params="[title: ''C:/pictures/myimage.png'']"/>"/> </div> </body> </html>


Usé FileUploadService para guardar el archivo de imagen en Grails. Si obtiene imágenes del directorio, intente esto:

<img style="height: 120px;width: 102px;"src="${resource(dir:''personImages'', file: personalDetailsInstance.id + ''.png'')}" />


Solo una mejora de la respuesta de @ Rob:

Otra opción que es un poco más agradable, puedes renderizar la imagen directamente desde la acción de tu controlador:

// controller action def displayGraph = { def img // a byte[], File or InputStream render(file: img, contentType: ''image/png'') }

Ver también: http://grails.org/doc/latest/ref/Controllers/render.html


Creo que no se trata de Grails, sino de HTML. Tú podrías:

  1. Realice la acción dedicada que permite que la imagen de las tuberías acepte ciertos parámetros y genere la imagen en esa acción;
  2. Incrustar codificado en base64 en HTML, como aquí :

    <img src = "data: image / gif; base64, R0lGODlhUAAPAKIAAAsL ... etc ..." alt = "wow" />


Tu gsp:

<img src="${createLink(controller: "image", action: "draw")}" />

Su controlador:

def draw() { byte[] imageInBytes = imageService.getImageInBytes() //should return byte array response.with{ setHeader(''Content-length'', imageInBytes.length.toString()) contentType = ''image/jpg'' // or the appropriate image content type outputStream << imageInBytes outputStream.flush() } }