如何在 php-java 桥的帮助下将 java.util.Date 传递给 Java 库

How to pass java.util.Date to Java library with help of php-java bridge

我正在使用 javabridge 连接 php 到 jasper 报告,我试图传递两个参数,但我收到警告和错误

Warning: Unchecked exception detected: [[o:Response$UndeclaredThrowableErrorMarker]:"FATAL: Undeclared java.lang.RuntimeException detected. java.lang.Exception: CreateInstance failed: new java.util.Date((o:String)[o:String]). Cause: java.lang.IllegalArgumentException VM: 1.7.0_79@http://java.oracle.com/" at: #-10 java.util.Date.parse(Unknown Source) #-9 java.util.Date.<init>(Unknown Source) #-8 sun.reflect.GeneratedConstructorAccessor57.newInstance(Unknown Source) #-7 sun.reflect.DelegatingConstructorAccessor[...]/java/Java.inc(361): java_Arg->getResult(false) #2 http://localhost:8080/JavaBridgeTemplate/java/Java.inc(364): java_Client->getWrappedResult(false) #3 http://localhost:8080/JavaBridgeTemplate/java/Java.inc(536): java_Client->getInternalResult() #4 http://localhost:8080/JavaBridgeTemplate/java/Java.inc(1930): java_Client->createObject('java.util.Date', Array) #5 C:\wamp\www\advanced\backend\javabridge\generate.php(49): Java->Java('java.util.Date', '12/Feb/16') #6 {main}] in http://localhost:8080/JavaBridgeTemplate/java/Java.inc on line 202

 Fatal error: Uncaught [[o:Exception]:"java.lang.Exception: Invoke failed: [[c:JasperFillManager]]->fillReport((o:JasperReport)[o:JasperReport], (i:Map)[o:HashMap], (i:Connection)[o:Connection]). Cause: net.sf.jasperreports.engine.JRException: Incompatible php.java.bridge.Response$UndeclaredThrowableErrorMarker value assigned to parameter FInicio in the Reubicados dataset. VM: 1.7.0_79@http://java.oracle.com/" at: #-16 net.sf.jasperreports.engine.fill.JRFillDataset.setParameter(JRFillDataset.java:903) #-15 net.sf.jasperreports.engine.fill.JRFillDataset.setFillParameterValues(JRFillDataset.java:642) #-14 net.sf.jasperreports.engine.fill.JRFillDataset.setParameterValues(JRFillDataset.java:585) #-13 net.sf.jasperreports.engine.fill.JRBaseFiller.setParameters(JRBaseFiller.java:1280) #-12 net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:901) #-11 net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:845) #-10 net.sf.jasperreports.engine.fill.JRFiller.fillReport(JRFiller.java:58) #-9 net.sf.jas in http://localhost:8080/JavaBridgeTemplate/java/Java.inc on line 195

问题出在它试图创建 java.util.Date 实例时。这是 php 文件:

   <?php


    require_once("http://localhost:8080/JavaBridgeTemplate/java/Java.inc");

    try {   
        $Param1 = date('d/M/y', strtotime($_POST['FInicio']));
        $Param2 = date('d/M/y', strtotime($_POST['FFin']));



        $jasperxml = new java("net.sf.jasperreports.engine.xml.JRXmlLoader");
        $jasperDesign = $jasperxml->load(realpath("Reubicados.jrxml"));
        $query = new java("net.sf.jasperreports.engine.design.JRDesignQuery");

        $jasperDesign->setQuery($query);
        $compileManager = new JavaClass("net.sf.jasperreports.engine.JasperCompileManager");
        $report = $compileManager->compileReport($jasperDesign); } catch (JavaException $ex) {
        echo $ex; }


    $fillManager = new JavaClass("net.sf.jasperreports.engine.JasperFillManager"); //aqui se pasan los parametros (Fecha Inicio y Fecha Fin) 
$params = new Java("java.util.HashMap"); 
$date=new Java('java.util.Date',$Param1);
$date1=new Java('java.util.Date',$Param2); 
$params->put("FInicio",$date); 
$params->put("FFin",$date1);



    $class = new JavaClass("java.lang.Class"); $class->forName("com.mysql.jdbc.Driver"); $driverManager = new JavaClass("java.sql.DriverManager");

    //db username and password 
$conn = $driverManager->getConnection("jdbc:mysql://localhost/viajestrafico?zeroDateTimeBehavior=convertToNull", "root", "root"); $jasperPrint = $fillManager->fillReport($report, $params, $conn);

    $exporter = new java("net.sf.jasperreports.engine.JRExporter");

并且 sql 在 ireports 中查询:

SELECT
     ayudante_situacion_laboral.`FechaInicio` AS ayudante_situacion_laboral_FechaInicio,
     ayudante_situacion_laboral.`FechaFin` AS ayudante_situacion_laboral_FechaFin,
     ayudante_situacion_laboral.`Cant_Horas` AS ayudante_situacion_laboral_Cant_Horas,
     ayudante_situacion_laboral.`Descripcion` AS ayudante_situacion_laboral_Descripcion,
     ayudante.`Registro` AS ayudante_Registro,
     ayudante.`Nombre` AS ayudante_Nombre,
     situacion_laboral.`Estado` AS situacion_laboral_Estado
FROM
     `ayudante` ayudante INNER JOIN `ayudante_situacion_laboral` ayudante_situacion_laboral ON ayudante.`Ayudante_ID` = ayudante_situacion_laboral.`AyudanteAyudante_ID`
     INNER JOIN `situacion_laboral` situacion_laboral ON ayudante_situacion_laboral.`Situacion_LaboralSitL_ID` = situacion_laboral.`SitL_ID`
WHERE
     situacion_laboral.Estado = 'Reubicado'  and $P{FInicio}<= ayudante_situacion_laboral.`FechaInicio` and $P{FFin}>=ayudante_situacion_laboral.`FechaFin`
UNION

     SELECT
     chofer_situacion_laboral.`FechaInicio` AS chofer_situacion_laboral_FechaInicio,
     chofer_situacion_laboral.`FechaFin` AS chofer_situacion_laboral_FechaFin,
     chofer_situacion_laboral.`Cant_Horas` AS chofer_situacion_laboral_Cant_Horas,
     chofer_situacion_laboral.`Descripcion` AS chofer_situacion_laboral_Descripcion,
     chofer.`Registro` AS chofer_Registro,
     chofer.`Nombre` AS chofer_Nombre,
     situacion_laboral.`Estado` AS situacion_laboral_Estado
FROM
     `chofer` chofer INNER JOIN `chofer_situacion_laboral` chofer_situacion_laboral ON chofer.`Chofer_ID` = chofer_situacion_laboral.`ChoferChofer_ID`
     INNER JOIN `situacion_laboral` situacion_laboral ON chofer_situacion_laboral.`Situacion_LaboralSitL_ID` = situacion_laboral.`SitL_ID`
WHERE
     (situacion_laboral.Estado = 'Reubicado' and $P{FInicio}<= chofer_situacion_laboral.`FechaInicio` and $P{FFin}>=chofer_situacion_laboral.`FechaFin`)

查看您的错误消息,无法使用“12/Feb/16”创建 java.util.Date:

java_Client->createObject('java.util.Date', Array) 
#5 C:\wamp\www\advanced\backend\javabridge\generate.php(49): 
Java->Java('java.util.Date', '12/Feb/16') #6 {main}] in 

如果你想实例化一个java日期对象,使用java.util.Date(long date)构造函数接受以毫秒表示的时间戳:

<?php
$startDate = $_POST['FInicio'];  // better to filter this :)
$Param1 = strtotime($startDate) * 1000; // to get milliseconds
if ($Param1 == 0) {
   throw new Exception("FInicio date parameter could not be parsed");
}

// ...
$javaDate = new Java('java.util.Date',$Param1); // This is a java date

您的 $date 参数现在应该是一个有效的 java.util.Date 对象。

你可以测试一下 :

$simpleDateFormat = new Java("java.text.SimpleDateFormat", 'yyyy-MM-dd');
echo $simpleDateFormat->format($javaDate); 
// should print your date in Y-m-d format

或者,您可以通过 java.text.SimpleDateFormatter 对象解析 Java 中的日期:

$date = '2016-12-21';
$simpleDateFormat = new Java("java.text.SimpleDateFormat", 'yyyy-MM-dd');
$javaDate = $simpleDateFormat->parse($date); // This is a Java date

两种方法都有效...


JasperReport 日期问题

与您的问题不完全相关,但是如果您想将 Date 用作查询参数,您应该使用 java.sql.Date(long date) 对象而不是 java.util.Date...这里有一些 总结变化的片段:

// php 

$sqlDate = new Java('java.sql.Date', strtotime($_POST['FInicio']) * 1000));
$params->put('FInicio', $sqlDate);

// in your report header (.jrxml):
<parameter name="FInicio" class="java.sql.Date">

// in your report query (.jrxml):
$P{FInicio} <= chofer_situacion_laboral.`FechaInicio`

你也可以看看soluble-japha javabridge client (refactored Java.inc client), the syntax differs a bit but there's a documentation about dates,可能会发现有用的。

很简单,只是我从一开始就在 php 代码中遇到的一个问题。

    $query = new java("net.sf.jasperreports.engine.design.JRDesignQuery");

    $jasperDesign->setQuery($query);

此代码阻止了 xrml 查询的执行,因为它正在创建一个空的查询对象。