圣杯。将文件上传到临时文件夹并在 gsp 中显示它们

Grails. Upload files to temp folder and display them in gsp

我的目的是上传图像并将它们存储在临时文件夹中。然后我想在 .gsp 视图中显示这些图像。我一直试图让它工作的过程是这样的:

首先,从输入上传文件:

<input id="inputImg" type="file" accept="image/*">

创建文件:

def saveFile(MultipartFile inputImg) {

    def contentType = inputImg.getContentType()
    def originalFilename = inputImg.getOriginalFilename()
    def extension = FilenameUtils.getExtension(originalFilename)

    String tempPath = System.getProperty("java.io.tmpdir") + "/uploads"

    File file = new File("$tempPath/$originalFilename")
    FileUtils.forceMkdirParent(file)
    inputImg.transferTo(file)

    if (contentType == 'application/octet-stream') {
        contentType = MimeTypeUtils.getContentTypeByFileName(originalFilename)
    }

    Path filePath = Paths.get(file.toString())
    Path path = Paths.get(tempPath)
    Path relativePath = path.relativize(filePath)

    Avatar avatar = new Avatar(
            path: relativePath.toString(),
            contentType: contentType,
            name: originalFilename,
            extension: extension
    )
}

一旦存储在临时文件夹中,我就找到了这个解决方案,但我不确定这是否是最好的方法。在将图像发送到视图之前,我正在尝试使用 base64 编码处理图像:

def filename = user?.avatar?.name
def file = new File("$tempPath/$filename")
def base64file = file?.readBytes()?.encodeBase64()

最后在 gsp 中显示:

<img alt="img" src="data:image/*;base64,${base64file}"/>

我想知道是否有另一种最佳方法来执行此过程,我不知道我是否遗漏了什么或者这不是一个管理文件和图像的好方法...

您使用的是采用 Base64 编码的内联图像,这对于显示相对较小的图像(最多 5k)很有用。这种方法的优点是您可以在单个 HTTP 连接中转储带有图像的页面。

如果图像变得相当大 (> 1MB),那么您将无法使用缓存和其他不错的功能,因此您必须一遍又一遍地通过线路发送数据,这会降低用户体验。

另一种方法是在单独的请求中传送每个图像。

您可以像这样定义一个控制器操作:

class ImageController {

  def image(String id){
    def file = new File("$tempPath/$id")
    if( !file.exists() )
      render status: 404
    else{
      response.contentType  = 'image/jpeg'
      response.withOutputStream{ it << file.readBytes() }
    }
  }
}

然后在您的 GSP 中输入:

<img alt="img" src="${g.createLink( controller:'image', action:'image', id:user.avatar.name )}"/>