【问题标题】:Null checking in spring expression languageSpring表达式语言中的空值检查
【发布时间】:2012-07-25 04:38:43
【问题描述】:

我在检查集合对象内的日期字段中的空指针时遇到了一种奇怪的行为

public class FilterTest {
       public static void main(String[] args) {
              Collection<EmployeeDto> employees = new ArrayList<EmployeeDto>();
           employees.add(new EmployeeDto("", 1111, new Date()));
           employees.add(new EmployeeDto("123", 2222, null));
           employees.add(new EmployeeDto("22", 3333, new Date()));
           employees.add(new EmployeeDto("22", 4444, null));
           employees.add(new EmployeeDto("11", 5555, null));
           employees.add(new EmployeeDto("22", 6666, null));
           employees.add(new EmployeeDto(null, 6666,null));

           StandardEvaluationContext stdContext = new StandardEvaluationContext();
           stdContext.setVariable("emps", employees);      

           ExpressionParser parser = new SpelExpressionParser();    


          **String key4= "#emps.?[dateOfBirth != null ? T(DateUtil).formatDate(dateOfBirth), 'dd/MM/yyyy').contains('25/07/2012') : false]" ;**          


              Collection<Object> proj1 = (Collection<Object>) parser.parseExpression(
                      key4).getValue(stdContext);
              System.out.println(proj1);    



}
class EmployeeDto {
       String name;
       public String getName() {
              return name;
       }

       public void setName(String name) {
              this.name = name;
       }

       public int getAge() {
              return age;
       }

       public void setAge(int age) {
              this.age = age;
       }

       int age;
       Date dateOfBirth;

       public EmployeeDto(String name, int age, Date dateOfBirth) {
              this.name = name;
              this.age = age;
              this.dateOfBirth = dateOfBirth;
       }

    public Date getDateOfBirth() {
        return dateOfBirth;
    }

    public void setDateOfBirth(Date dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
    }
}

表达式应该返回满足条件的对象集合。但是现在,我遇到了一个异常,即在 null 上找不到 dateOfBirth。所以我尝试了一个新的表达方式

 String key4= "#emps.?[dateOfBirth != null ? T(DateUtil).formatDate(#emps.![dateOfBirth], 'dd/MM/yyyy').contains('25/07/2012') : false]" ;

这很好用。但是当我在集合的第一个对象中添加 null 时,它返回结果为 0,当我检查时,我发现 null 传递给了 DateUtil 类的 formatDate 方法。即员工集合就像 `

employees.add(new EmployeeDto("", 1111, null)); // first value is null, and I am getting empty result, but there is one corrrect result
           **employees.add(new EmployeeDto("12", 2222, null));**
           employees.add(new EmployeeDto("22", 3333, new Date()));
           employees.add(new EmployeeDto("33", 4444, null));
           employees.add(new EmployeeDto("FIVE", 5555, null));
           employees.add(new EmployeeDto("SIX", 6666, null));
           employees.add(new EmployeeDto(null, 6666,null));

你能帮我解决这个问题吗,谁能告诉我应该使用正确的表达方式吗?

【问题讨论】:

    标签: spring spring-el


    【解决方案1】:

    在 DateUtil 类中,添加如下方法:

        public static boolean isSameDay(Date date1, Date date2) {
            if (date1 == null || date2 == null) {
                return false;
            }
            Calendar cal1 = Calendar.getInstance();
            cal1.setTime(date1);
            Calendar cal2 = Calendar.getInstance();
            cal2.setTime(date2);
            return isSameDay(cal1, cal2);
        }
    

    那就这样吧:

    StandardEvaluationContext stdContext = new StandardEvaluationContext();
    stdContext.setVariable("emps", employees);
    stdContext.setVariable("yourTestDate", new Date());
    ExpressionParser parser = new SpelExpressionParser();   
    
    String key4 = "#emps.?[T(DateUtil).isSameDate(dateOfBirth, yourTestDate)]" ;
    Collection<Object> proj1 = (Collection<Object>) parser.parseExpression(key4).getValue(stdContext);
    System.out.println(proj1);   
    

    【讨论】:

    • 您好,感谢您的回答。但在我的情况下,我需要格式化的日期集合,根据日期格式避免空值。它不仅仅是一个布尔值检查它是同一日期,我如何才能实现这一点。提前致谢
    • 我尝试了您的回答,但仍然收到异常 Field or property 'dateOfBirth' cannot be found on null
    • 我尝试了不同的选项,但是当我在第一个集合对象中给出 null 时,它不起作用并返回空结果。但是如果第一个对象不为空,它就可以工作
    • 那么,为什么需要使用 Spring 表达式语言呢?你能收藏番石榴吗? marxsoftware.blogspot.fr/2011/10/…
    【解决方案2】:

    您前几天问了一个类似的问题 - 在这种情况下,您需要对集合选择的 RESULTS 执行投影。这是一个更简单的例子......

        Expression exp = new SpelExpressionParser()
            .parseExpression("(#emps.?[name != null]).![name.toUpperCase()]");
    

    第一部分 (...) 选择那些符合条件的元素;然后它在该新集合上执行投影。

    【讨论】:

    • 我试过这个,但我仍然遇到异常。我给出的关键是,(#emps.?[dateOfBirth != null]).![T(DateUtil).filterDate(dateOfBirth, 'dd/MM/yyyy')],在这个 DateUtil 中。 filterdate 方法将日期格式化为指定的格式。但是我遇到了一个例外,即在 null 上找不到字段或属性“dateOfBirth”,您可以看到在employeedto 中,我将 dateofbirth 的第一个值设为 null 。你能帮我纠正一下吗,在此先感谢
    • 我建议您逐步完成它。首先评估选择,以确保您得到您所期望的。 #emps.?[dateOfBirth != null] - 这是否为您提供了具有非空 DOB 的对象集合。你可以一个接一个地用几个表达式来做到这一点。一旦你调试了它,你应该能够重新组合成一个表达式。
    • 您好,感谢您的回答,我调试了代码并了解,当我尝试调用该方法时抛出异常。 [T(DateUtil).filterDate(dateOfBirth, 'dd/MM/yyyy']。当我给出时,#emps.?[dateOfBirth != null].![dateOfBirth],我得到了值,问题出在函数调用,你有什么想法吗,谢谢支持
    猜你喜欢
    • 1970-01-01
    • 2012-05-06
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 2014-01-14
    • 1970-01-01
    • 2021-10-30
    • 2013-03-20
    相关资源
    最近更新 更多