从作业执行时,g.formatDate会引发错误吗?

时间:2015-09-28 20:51:10

标签: grails groovy

我使用Grails作业启动使用g.formatDate的服务。直接从Controller使用服务时我没有问题。当我从作业使用服务时,我收到以下错误:

ERROR listeners.ExceptionPrinterJobListener  - Exception occurred in job: Grails Job
Message: java.lang.NullPointerException
   Line | Method
->> 111 | execute in grails.plugins.quartz.GrailsJobFactory$GrailsJob
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   202 | run     in org.quartz.core.JobRunShell
^   573 | run . . in org.quartz.simpl.SimpleThreadPool$WorkerThread
Caused by NullPointerException: null
->> 245 | $tt__sendReportCompanyWeekly in Test.SendMailService$$EPPc274K
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    47 | doCall  in Test.ReportCompanyWeeklyJob$_execute_closure1
|    31 | execute in Test.ReportCompanyWeeklyJob$$EPPc2HTU
|   104 | execute in grails.plugins.quartz.GrailsJobFactory$GrailsJob
|   202 | run . . in org.quartz.core.JobRunShell
^   573 | run     in org.quartz.simpl.SimpleThreadPool$WorkerThread

这是我的工作:

class ReportCompanyWeeklyJob {  

  SendMailService sendMailService


  static triggers = {
    cron name: 'scheduledReportCompanyWeeklyJob', cronExpression: "0 15 22 ? * *" 
  }

  def execute() {
    sendMailService.sendReportCompanyWeekly(company.id, user.id)
  }

}

这是我的服务:

@Transactional
class SendMailService {

    def gspTagLibraryLookup  // being automatically injected by spring
    def g

  def sendReportCompanyWeekly(String companyId, String userId) {    
    g = gspTagLibraryLookup.lookupNamespaceDispatcher("g")

    Date today = new Date()
    Locale locale = // some locale

    // Line 245
    def test = g.formatDate(date: today, formatName: 'date.format.long.no.year', locale: locale)  

 }

}

编辑:我使用groovyPageRenderer.render(template: viewPathHTML, model: myModel)在服务中呈现GSP。

如何从作业中运行g.formatDate

1 个答案:

答案 0 :(得分:2)

grails.gsp.PageRenderer在可呈现的内容方面受到限制,因为它与从控制器呈现GSP页面的上下文不同。

使用 formatName 时,g.formatDate()会尝试从GrailsWebRequest获取区域设置 Locale 用于从MessageSource检索“date.format.long.no.year”。问题是grails.gsp.PageRenderer没有GrailsWebRequest。您可以看到g.formatDate()源代码here

变通

您可以通过格式化服务中的日期并通过模型将其传递给GSP来解决此问题。像这样:

import java.text.SimpleDateFormat

@Transactional
class SendMailService {

    ...
    def messageSource // Injected to look up 'date.format.long.no.year'

    def sendReportCompanyWeekly(String companyId, String userId) {    
        Date today = new Date()
        Locale locale = // some locale

        def formattedDate = new SimpleDateFormat(messageSource.getMessage('date.format.long.no.year', null, locale), locale)
            .format(today)

        /* 
          1. Add the formattedDate to the PageRenderer model, 
          2. Update the GSP code to use the value from the model instead of g.formatDate()
        */
    }

}

更好的主意 - 创建formatDate Closure

import java.text.SimpleDateFormat

@Transactional
class SendMailService {

    ...
    def messageSource // Injected to look up 'date.format.long.no.year'

    def sendReportCompanyWeekly(String companyId, String userId) {    
        Date today = new Date()
        Locale locale = // some locale

        def formatter= new SimpleDateFormat(messageSource.getMessage('date.format.long.no.year', null, locale), locale)

        def formatDate = { Date date -> formatter.format(date) }

        /* 
          1. Add the formatDate Closure to the PageRenderer model, 
          2. Update the GSP code to use the Closure from the model instead of g.formatDate()
        */
    }

}