2013-06-10 28 views
9

Tôi muốn sử dụng EL trong đơn đăng ký của mình. Nhưng tôi không thể tìm thấy bất kỳ cách nào. Tôi thường kết thúc cần một số giao diện mà tôi không có một thực hiện.Java: Cách đánh giá một biểu thức EL - độc lập (bên ngoài bất kỳ khuôn khổ web nào) mà không cần triển khai giao diện?

Tôi có bản đồ các đối tượng và tôi muốn biểu thức chuỗi như Hello, ${person.name} được đánh giá thành chuỗi.

Làm cách nào tôi có thể đạt được điều đó, sử dụng bất kỳ Commons EL, javax.el, OGNL, hoặc như vậy? Phải là một thư viện độc lập.

Và tôi biếtJava: using EL outside J2EE và đã xem JSTL/JSP EL (Expression Language) in a non JSP (standalone) context. Đó không phải là những gì tôi đang tìm kiếm.

Những gì tôi đang tìm kiếm là một ví dụ về những gì phụ thuộc thêm vào, và sau đó làm thế nào để khởi tạo một phân tích cú pháp mà sẽ có:

private static String evaluateEL(String expr, Map<String, String> properties); 

và cho phép tôi làm:

String greet = evaluateEL("Hello ${person.name}", 
    new HashMap(){{ 
     put("person", new Person("Ondra")); 
    }} 
); 

Và Tôi cần nó để sử dụng một số giá trị hợp lý, ví dụ "" trên null thay vì ném NPE hoặc hơn.

+1

Trong khi không chính xác EL, [FreeMarker] (http://freemarker.sourceforge.net/) có cú pháp và tính năng tương tự. – fge

+0

Ngoài ra Velocity có cú pháp tương tự như EL. –

+0

OGNL có thể là như vậy, nhưng trang web của họ không hoạt động với ATM. –

Trả lời

12

Có khá một loạt các động cơ EL, trong đó thực hiện hầu hết các Java Expression Language API.

  • Commons EL (http://jakarta.apache.org/commons/el/) Thực hiện các API JSP EL đó là tồn tại mãi mãi. Thư viện này có thể được tìm thấy trong nhiều thùng chứa JSP (ví dụ Tomcat) hoặc được sử dụng làm nền tảng cho các máy chủ J2EE của nhiều nhà cung cấp.

  • OGNL (http://www.ognl.org/) Một trong những ELs biểu cảm nhất hiện nay và được sử dụng rộng rãi với WebWork (Struts 2) và Tapestry.

  • MVEL (https://github.com/mvel/mvel) Một người mới đến EL là một phần của dự án MVFlex/Valhalla. Các tính năng trông phù hợp hơn với lời đề nghị của OGNL với lời gọi phương thức và một số hỗ trợ biểu thức chính quy thú vị.

  • Language (Unified) Expression (https://jcp.org/aboutJava/communityprocess/final/jsr341/index.htmlhttp://jcp.org/en/jsr/detail?id=245) Chuẩn ngôn ngữ biểu hiện đầu tiên được giới thiệu trong Java EE 5 (EL 2.1) và tăng cường trong Java EE 6 (EL 2.2) và Java EE 7 (EL 3.0). Thực hiện tham chiếu có sẵn từ dự án Glassfish - Unified Expression Language.

  • JEXL (http://jakarta.apache.org/commons/jexl/) Thực hiện dựa trên trình phân tích cú pháp của Velocity. Bởi vì điều này, nó hoạt động giống như một giải pháp templating hạn chế với những thứ như lời gọi phương thức.

Source

Để bây giờ tôi đã kết thúc với mã này sử dụng BeanUtils - xấu xí nhưng công trình.

import java.lang.reflect.InvocationTargetException; 
import java.util.Map; 
import java.util.NoSuchElementException; 
import java.util.StringTokenizer; 
import org.apache.commons.beanutils.PropertyUtils; 
import org.apache.commons.lang.StringUtils; 
import org.slf4j.LoggerFactory; 

public static class SimpleEvaluator implements IExprLangEvaluator { 
    private static final org.slf4j.Logger log = LoggerFactory.getLogger(SimpleEvaluator.class); 

    @Override 
    public String evaluateEL(String template, Map<String, String> properties) { 

     StringTokenizer st = new StringTokenizer(template); 
     String text = st.nextToken("${"); 
     StringBuilder sb = new StringBuilder(); 

     // Parse the template: "Hello ${person.name} ${person.surname}, ${person.age}!" 
     do{ 
      try { 
       sb.append(text); 
       if(! st.hasMoreTokens()) 
        break; 

       // "${foo.bar[a]" 
       String expr = st.nextToken("}"); 
       // "foo.bar[a].baz" 
       expr = expr.substring(2); 
       // "foo" 
       String var = StringUtils.substringBefore(expr, "."); 

       Object subject = properties.get(var); 

       // "bar[a].baz" 
       String propPath = StringUtils.substringAfter(expr, "."); 

       sb.append(resolveProperty(subject, propPath)); 

       text = st.nextToken("${"); 
       text = text.substring(1); 
      } catch(NoSuchElementException ex){ 
       // Unclosed ${ 
       log.warn("Unclosed ${ expression, missing } : " + template); 
      } 
     } while(true); 

     return sb.toString(); 
    } 

    // BeanUtils 
    private String resolveProperty(Object subject, String propPath) { 
     if(subject == null) return ""; 

     if(propPath == null || propPath.isEmpty()) return subject.toString(); 

     try { 
      return "" + PropertyUtils.getProperty(subject, propPath); 
     } catch( IllegalAccessException | InvocationTargetException | NoSuchMethodException ex) { 
      log.warn("Failed resolving '" + propPath + "' on " + subject + ":\n " + ex.getMessage(), ex); 
      return ""; 
     } 
    } 

}// class SimpleEvaluator 
3

Tôi đã tìm thấy một số tại http://juel.sourceforge.net/guide/start.html. Vẫn không chính xác 1 lót, nhưng gần.

ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl(); 
de.odysseus.el.util.SimpleContext context = new de.odysseus.el.util.SimpleContext(); 
context.setVariable("foo", factory.createValueExpression("bar", String.class)); 
ValueExpression e = factory.createValueExpression(context, "Hello ${foo}!", String.class); 
System.out.println(e.getValue(context)); // --> Hello, bar! 

Maven DEPS:

<!-- Expression language --> 
    <dependency> 
     <groupId>javax.el</groupId> 
     <artifactId>javax.el-api</artifactId> 
     <version>2.2.4</version> 
     <type>jar</type> 
    </dependency> 
    <dependency> 
     <groupId>juel</groupId> 
     <artifactId>juel</artifactId> 
     <version>2.2.1</version> 
     <type>jar</type> 
    </dependency> 
+2

Sử dụng ' juel-impl ', nếu không bạn sẽ có hai EL-APIs xung đột. – chris