本示例有两个工作页面,一个用来显示文档信息列表,一个用来上传文档到服务器。
该文档对象将保存到这里域模型中
package com.tutorial
class Document {
String filename
byte[] filedata
Date uploadDate = new Date()
static constraints = {
filename(blank:false,nullable:false)
filedata(blank: true, nullable:true, maxSize:1073741824)
}
}
filedata使用byte[]类型,允许最大值在constraints{}中定义
使用一个列表存放上传到服务器的文档信息,下面是列表的controller和view
package com.tutorial
class DocumentController {
def index() {
redirect(action: "list", params: params)
}
def list() {
params.max = 10
[documentInstanceList: Document.list(params), documentInstanceTotal: Document.count()]
}
}
访问index时重定向到list,下面是list.gsp
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="main">
<title>Document List</title>
</head>
<body>
<div class="nav" role="navigation">
<ul><li><g:link class="create" action="create">Upload New Document</g:link></li></ul>
</div>
<div class="content scaffold-list" role="main">
<h1>Document List</h1>
<g:if test="${flash.message}"><div class="message" role="status">${flash.message}</div></g:if>
<table>
<thead>
<tr>
<g:sortableColumn property="filename" title="Filename" />
<g:sortableColumn property="uploadDate" title="Upload Date" />
</tr>
</thead>
<tbody>
<g:each in="${documentInstanceList}" status="i" var="documentInstance">
<tr class="${(i % 2) == 0 ? 'even' : 'odd'}">
<td><g:link action="download" id="${documentInstance.id}">${documentInstance.filename}</g:link></td>
<td><g:formatDate date="${documentInstance.uploadDate}" /></td>
</tr>
</g:each>
</tbody>
</table>
<div class="pagination">
<g:paginate total="${documentInstanceTotal}" />
</div>
</div>
</body>
</html>
在列表中的download列,下载链接指的是文档的id,显示文档的文件名。
Upload New Document 链接导航到文档上传页面,下面是controller和view代码
create.gsp
<%@ page import="com.tutorial.Document" %>
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="main">
<title>Upload New Document</title>
</head>
<body>
<div class="nav" role="navigation">
<ul><li><g:link class="list" action="list">Document List</g:link></li></ul>
</div>
<div class="content scaffold-create" role="main">
<h1>Upload New Document</h1>
<g:if test="${flash.message}"><div class="message" role="status">${flash.message}</div></g:if>
<g:uploadForm action="upload">
<fieldset class="form">
<input type="file" name="file" />
</fieldset>
<fieldset class="buttons">
<g:submitButton name="upload" class="save" value="Upload" />
</fieldset>
</g:uploadForm>
</div>
</body>
</html>
controller
def create() {
}
def upload() {
def file = request.getFile('file')
if(file.empty) {
flash.message = "File cannot be empty"
} else {
def documentInstance = new Document()
documentInstance.filename = file.originalFilename
documentInstance.filedata = file.getBytes()
documentInstance.save()
}
redirect (action:'list')
}
documentInstance.filedata = file.getBytes()获取到文档的字节数,保存到document对象中。
下载代码也非常精简
def download(long id) {
Document documentInstance = Document.get(id)
if ( documentInstance == null) {
flash.message = "Document not found."
redirect (action:'list')
} else {
response.setContentType("APPLICATION/OCTET-STREAM")
response.setHeader("Content-Disposition", "Attachment;Filename=\"${documentInstance.filename}\"")
def outputStream = response.getOutputStream()
outputStream << documentInstance.filedata
outputStream.flush()
outputStream.close()
}
}
outputStream « documentInstance.filedata这句代码用来检索字节内容并发送给response对象。
点这里可以下载完整代码打包
1.修改domain:将filedata修改成文档路径,String fullPath
2.配置一个文件保存到服务器的物理地址,修改config/Config.groovy
environments {
development {
uploadFolder = "c:/temp/upload/"
}
test {
uploadFolder = "c:/temp/upload/"
}
production {
uploadFolder = "c:/temp/upload/"
}
}
3.修改文档上传的controller
def upload() {
def file = request.getFile('file')
if(file.empty) {
flash.message = "File cannot be empty"
} else {
def documentInstance = new Document()
documentInstance.filename = file.originalFilename
documentInstance.fullPath = grailsApplication.config.uploadFolder + documentInstance.filename
file.transferTo(new File(documentInstance.fullPath))
documentInstance.save()
}
redirect (action:'list')
}
4.修改文档下载的controller
def download(long id) {
Document documentInstance = Document.get(id)
if ( documentInstance == null) {
flash.message = "Document not found."
redirect (action:'list')
} else {
response.setContentType("APPLICATION/OCTET-STREAM")
response.setHeader("Content-Disposition", "Attachment;Filename=\"${documentInstance.filename}\"")
def file = new File(documentInstance.fullPath)
def fileInputStream = new FileInputStream(file)
def outputStream = response.getOutputStream()
byte[] buffer = new byte[4096];
int len;
while ((len = fileInputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, len);
}
outputStream.flush()
outputStream.close()
fileInputStream.close()
}
}