【问题标题】:Issue in Date handling for JSON ObjectJSON 对象的日期处理问题
【发布时间】:2018-02-06 06:36:15
【问题描述】:

[在此处输入图像描述][1]我在 Drools 中遇到了一些问题,我想将日期作为日期类型传递,但目前我们在 JSONObject 中没有任何方法来处理日期。我的 JSONObject 看起来像这样。

{"id":600,"city":"Gotham","age":25,"startDate":"29-DEC-2017","endDate":"2014-08-31"}

我的流口水状况是这样的。

package com.rules
import org.drools.core.spi.KnowledgeHelper; 
import org.json.JSONObject;
rule "ComplexRule1"
salience 100
dialect "mvel"
date-effective "16-Jan-2018 00:00"
no-loop  
when
    $cdr : JSONObject( $cdr.optString("startDate") >= '28-Dec-2017') 
then
    $cdr.put("Action_1" , new JSONObject().put("actionName","Complex_Rule1_Action1").put("actionTypeName","SEND OFFER").put("channelName","SMS").put("messageTemplateName","SMSTemplate").put("@timestamp",(new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm:ss")).format(new java.util.Date())).put("ruleFileName","ComplexRule1.drl").put("ruleName","ComplexRule1"));
end

我目前正在使用 .optString 因为我们没有任何方法,如 optString/optInt/optBoolean 用于日期。那么如何在 Drools 中处理日期呢?

我们将不胜感激。

问候普内特

我的新 DRL 如下所示:

 package com.rules

import com.aravind.drools.SuperJSONObject;
import org.drools.core.spi.KnowledgeHelper; 
import org.json.JSONObject;


rule "Convert to SuperJSONObject"
when
    $cdr: JSONObject()      
then 
    insert(new SuperJSONObject($cdr));      
end


rule "ComplexRule1"
salience 100
dialect "mvel"
date-effective "16-Jan-2018 00:00"
no-loop  
when

    $cdr : SuperJSONObject( $cdr.getAsDate("startDate") == '28-Dec-2017')   
then
    $cdr.getObject().put("Action_1" , new JSONObject().put("actionName","Complex_Rule1_Action1").put("actionTypeName","SEND OFFER").put("channelName","SMS").put("messageTemplateName","SMSTemplate").put("@timestamp",(new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm:ss")).format(new java.util.Date())).put("ruleFileName","ComplexRule1.drl").put("ruleName","ComplexRule1"));
end

类看起来像这样:

   import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.json.*;

public class SuperJSONObject {
    public final JSONObject obj;
    SimpleDateFormat sdfmt2= new SimpleDateFormat("yyyy/MM/dd"); 

    public SuperJSONObject(JSONObject obj){
        this.obj = obj;
    }

    public Date getAsDate(String field) throws ParseException{
        return sdfmt2.parse(this.obj.optString(field));
    }

    public JSONObject getObject(){
        return this.obj;
    }

}

另一个类是这样的

    import java.io.File
import java.io.FileReader
import org.drools.KnowledgeBase
import org.drools.KnowledgeBaseFactory
import org.drools.builder.KnowledgeBuilder
import org.drools.builder.KnowledgeBuilderFactory
import org.drools.builder.ResourceType
import org.drools.io.ResourceFactory
import org.drools.runtime.StatefulKnowledgeSession
import org.json.JSONObject

object RunStandAloneDrools {


  def main(args: Array[String]): Unit = {
    var jsonObjectArray: Array[JSONObject] = new Array(1)
    jsonObjectArray(0) = new JSONObject("{\"id\":600,\"city\":\"Gotham\",\"age\":25,\"startDate\":\"28-Dec-2017\",\"endDate\":\"2014-08-01\"}")
    var file: String = "/home/puneet/Downloads/ComplexRule1.drl"
    var kbuilder: KnowledgeBuilder = KnowledgeBuilderFactory.newKnowledgeBuilder()
    kbuilder.add(ResourceFactory.newReaderResource(new FileReader(new File(file))), ResourceType.DRL)
   println("Errors? " + kbuilder.getErrors.size())
    var iter = kbuilder.getErrors.iterator()
    while(iter.hasNext()){
      println(iter.next().getMessage)
    }
    var kbase: KnowledgeBase = KnowledgeBaseFactory.newKnowledgeBase()
    kbase.addKnowledgePackages(kbuilder.getKnowledgePackages)
    var session: StatefulKnowledgeSession = kbase.newStatefulKnowledgeSession()
    callRulesEngine(jsonObjectArray,session)
    println("Done")  
  }

  def callRulesEngine(data: Array[JSONObject], knowledgeSession: StatefulKnowledgeSession): Unit = {
    data.map ( x => callRulesEngine(x,knowledgeSession) )
  }

  def callRulesEngine(data: JSONObject, knowledgeSession: StatefulKnowledgeSession): Unit = {
    try {
      println("Input data " + data.toString())
      knowledgeSession.insert(data)
      knowledgeSession.fireAllRules()
      println("Facts details " + knowledgeSession.getFactCount)
      println("Enriched data " + data.toString())
    } catch {
      case (e: Exception) => println("Exception", e);
    }
  }

`

输出未达到预期

【问题讨论】:

  • 您之前关于同一问题的帖子发生了什么变化?
  • 没有人回答。所以我删除了那个并重新发布。

标签: json scala maven drools


【解决方案1】:

有多种方法可以解决这个问题,但最重要的是让您了解这不是根本不是 Drools 问题。您的问题更多关于如何从JSONObject 获取Date

实现此目的的一种方法是使用function in Drools 进行转换。

但我不喜欢函数,所以我会给你另一种更详细的方法来处理这种情况(以及许多其他需要类型转换的情况)。

我们的想法是为您的JSONObject-SuperJSONObject-创建一个包装类,它将公开您需要的所有功能。对于此类的实现,我将使用组合,但如果需要,您可以使用继承(或代理)。

public class SuperJSONObject {
    public final JSONObject obj;

    public SuperJSONObject(JSONObject obj){
        this.obj = obj;
    }

    //expose all the methods from JSONObject you want/need

    public Date getAsDate(String field){
        return someDateParser.parse(this.obj.optString(field));
    }

    public JSONObject getObject(){
        return this.obj;
    }

}

所以现在我们有了一个可以在规则中使用的getAsDate() 方法。但我们首先需要将JSONObject 转换为SuperJSONObject,然后才能使用该方法。您可以通过多种方式和地点执行此操作。我将展示如何在 DRL 中做到这一点。

rule "Convert to SuperJSONObject"
when
    $jo: JSONObject() //you may want to filter which objects are converted by adding constraints to this pattern
then 
    insert(new SuperJSONObject($jo));
end

现在我们可以开始了。我们现在可以使用这个新类编写如下规则:

rule "ComplexRule1"
salience 100
dialect "mvel"
date-effective "16-Jan-2018 00:00"
no-loop  
when
    $cdr : SuperJSONObject( getAsDate("startDate") >= '28-Dec-2017') 
then
    $cdr.getObject().put("Action_1" , ...);
end

写完所有这些代码后,我可能会重新考虑在 DRL 中使用简单函数的选项... :P

希望对你有帮助,

【讨论】:

  • 我的回答中有一个链接,可以告诉您如何在 DRL 中定义函数。
  • 我已经编辑了帖子,请检查。我使用它时没有输出。
  • 那么,您在哪里将JSONObject 转换为SuperJSONObject?在我的回答中,我是按照规则去做的。
  • 我添加了一张图片,因为我正在使用所有规则
  • 请从我的评论中删除图片并将其添加到原始问题中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-04
  • 2018-10-10
  • 2011-03-21
  • 1970-01-01
相关资源
最近更新 更多