我正在创建一个grails服务,它将通过Java库与第三方REST API进行交互.Java库需要通过URL,用户名和密码来获取REST API的凭据.
我想将这些凭据存储configuration/Config.groovy在一起,使它们可用于服务,并确保在服务需要它们之前可以使用凭据.
我很欣赏grailsApplication.config控制器可以使用,并且通过服务方法可以向服务提供相关的配置值,例如:
package example
class ExampleController {
    def exampleService
    def index = { }
    def process = {
        exampleService.setCredentials(grailsApplication.config.apiCredentials)
        exampleService.relevantMethod()
    }
}
package example
import com.example.ExampleApiClient;
class ExampleService {
    def credentials
    def setCredentials(credentials) {
        this.credentials = credentials
    }
    def relevantMethod() {
        def client = new ExampleApiClient(
            credentials.baseUrl,
            credentials.username,
            credentials.password
        )
        return client.action();
    }
}
我觉得这种方法有点缺陷,因为它取决于控制器调用setCredentials().将凭证自动提供给服务将更加健壮.
这两个选项中的任何一个都是可行的(我目前对grails不够熟悉):
grailsApplication.config.apiCredentials在创建服务时注入控制器中的服务?
在服务上提供某种形式的构造函数,允许在实例化时将凭据传递给服务吗?
将凭证注入服务是理想的.怎么可以这样做?
我刚刚意识到,对于Grails控制器,还有另一种渲染方法"响应".
如果我们想在控制器中渲染视图,则response和render方法之间有什么区别.
目前,当我需要共享processParams(params)不同控制器之间的方法时,我使用继承或服务.这两种解决方案都有一些不便之处:
所以我的问题是:有没有其他方法可以使用一些可用于多个控制器的常用方法?
文件说:
Grails团队不鼓励将核心应用程序逻辑嵌入到控制器中,因为它不会促进重用和关注的清晰分离.
我在src/groovy文件夹中有一个API控制器和一些Groovy类.这些类只实现了我的应用程序逻辑,因此API控制器中的操作以这种方式工作:
//index page
def index = {
    render new IndexApi().index(params) as JSON
}
我很好奇 - 有没有理由将我的应用程序逻辑从简单的groovy类转移到服务中?
在我的gsp视图中,我有这个代码:
<g:each in="${fileResourceInstanceList}" status="i" var="fileResourceInstance">
<tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
<td>${fileResourceInstance.decodeURL()}</td>
<td><a href="${createLinkTo( dir:"/upload_data/datasets/ds"+signalDataInstance.datasetID , file: fileResourceInstance.decodeURL(), absolute:true )}" target="_new">view</a></td>
<td><g:link action="deleteFile" id="${fileResourceInstance.replace('.','###')}" params="[rs:signalDataInstance.datasetID]" onclick="return confirm('Are you sure?');"> delete </g:link></td>
</tr>
</g:each>
我想下载我的csv文件,而不是在我的浏览器中读取我的csv文件!
如何强制下载?
这是我的控制器中的代码部分:
    def f = new File( "${linkDir}".toString() )
    if( f.exists() ){
        f.eachFile(){ file->
        if( !file.isDirectory() )
            fileResourceInstanceList.add( file.name )
        }
    }
在我的代码中添加此部分以强行下载?:
response.setHeader("Content-disposition", "attachment; filename=" + file.name + ".csv");
render(contentType: "text/csv", text: file.name.toString());
我有一个控制器,它连接到一个URL来检索一个csv文件.
我能够使用以下代码在响应中发送文件,这很好.
    def fileURL = "www.mysite.com/input.csv"
    def thisUrl = new URL(fileURL);
    def connection = thisUrl.openConnection();
    def output = connection.content.text;
    response.setHeader "Content-disposition", "attachment;
    filename=${'output.csv'}"
    response.contentType = 'text/csv'
    response.outputStream << output
    response.outputStream.flush()
但是我认为这个方法不适合大文件,因为整个文件被加载到控制器内存中.
我希望能够通过块读取文件块,并通过块将文件写入响应块.
有任何想法吗?
问题:有没有办法用request.JSON数据进行自动命令对象绑定?
在我的grails控制器中给出这个简单的Command对象:
class ProfileCommand{
int id
String companyName
static constraints = {
    companyName blank: false
    id nullable: false
}
@Override
public String toString() {
    return "ProfileCommand{id=$id, companyName='$companyName'}";
}
}
和我的控制器方法签名:
def update(ProfileCommand command) {...}
如何将request.JSON数据存入我的命令对象?
到目前为止,我能够做到的唯一方法是在update()方法中手动创建命令对象,传递request.JSON作为构造函数参数:
    def command = new ProfileCommand(request.JSON)
    log.debug "Command object contents: $command"
上面的debug命令产生:
Command object contents: ProfileCommand{id=1, companyName='Blub Muckers'}
这正是我想要的(对于上述解决方案,Oliver Tynes大声喊出来).不幸的是,command.validate()在创建命令后调用会产生以下异常:
Class org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException
Message Tag [validate] is missing required attribute [form]
我正在使用v2.0.3,uris产生了与v2.0.4相同的异常.
更新 
Grails邮件列表中的每个Ian Roberts,您需要将@Validateable注释添加到命令类才能开始validate()工作.谢谢,伊恩!
我正在尝试使用HQL(Hibernate查询语言)在两个表之间创建一个联盟.此SQL脚本在我的SQL服务器上正常工作:
SELECT COUNT(DISTINCT linkedin_id) as test, school_name
FROM
(SELECT * FROM alum_education 
 UNION
 SELECT * FROM alum_connection_educations) AS UNIONS where school_name='some string'
问题是,当我尝试在这样的grails中运行它:
     def countOfEdu = AlumEducation.executeQuery("select count (distinct linkedinId ) as countOfEdu, schoolName as SchoolName from (SELECT * FROM alumEducation UNION SELECT * FROM alumConnectionEducations) AS UNIONS where schoolName='some string'" )
我收到此错误:
  org.hibernate.hql.ast.QuerySyntaxException: unexpected token: ( near line 1, column 83 [select count(distinct linkedinId )  as countOfEdu, schoolName as SchoolName  from (SELECT * FROM alumEducation UNION SELECT * FROM …我是grails的新手.我必须与会议合作.我见过会话文档.但不知道将代码放在我的控制器中的哪个位置.我有一个学生创建名称createStudent的页面.现在我希望只有在用户进入会话时才能访问此页面.现在我该怎么办呢.我是否必须在登录时将用户设置为变量.有人可以帮我这个吗?
def index() {
    def user = session["user"]
    if (user){
        redirect(controller: 'admistratorAction', action: 'createUser')
    }else{
        redirect(controller: 'login', action: 'index')
    }
}
我开始使用Grails(3.x)Framework,但在尝试将域内容呈现给视图时,我遇到了这个错误:
Error 500: Internal Server Error
URI /hello/index
Class javax.servlet.ServletException
Message: Could not resolve view with name 'index' in servlet with name 'grailsDispatcherServlet'
HelloController.groovy:
package helloworld   
class HelloController {
    def index() {
        def Person persona1 = new Person(firstName: "someone", lastName: "stuck", age: 21)
        [persona:persona1]
    }
}
Person.groovy:
package helloworld
class Person {
    String firstName
    String lastName
    int age
}