330 likes | 467 Views
What’s New with Bean Validation and Expression Language in Java EE 7. Reza Rahman Java EE/GlassFish Evangelist Reza.Rahman@Oracle.com @reza_rahman. Agenda. EL and BV powerful, key enabling APIs Underrated in the buzz Important changes in BV 1.1 and EL 3
E N D
What’s New with Bean Validation and Expression Language in Java EE 7 Reza Rahman Java EE/GlassFish Evangelist Reza.Rahman@Oracle.com @reza_rahman
Agenda EL and BV powerful, key enabling APIs Underrated in the buzz Important changes in BV 1.1 and EL 3 Especially from a broader Java EE 7 perspective
Bean Validation 1.1 Overview • Point release update to Java EE 6 • Small but important set of changes aligned with the platform • Integration with CDI, JAX-RS, JPA, JSF, etc
Bean Validation 1.1 Feature Summary • CDI alignment • Method validation • Integration with JAX-RS • Error messages using EL expressions
Bean Validation 1.1 CDI Alignment • Delegate Bean Validation component lifecycle to CDI • Particularly useful in ConstraintValidator implementations public class ZipCodeValidator implements ConstraintValidator<ZipCode, String> { @Inject @France private ZipCodeChecker checker; public void initialize(ZipCode zipCode) {} public boolean isValid(String value, ConstraintValidationContext context) { if (value==null) return true; return checker.isZipCodeValid(zipCode); } }
Bean Validation 1.1 Method Validation Overview • Validate parameters and return values upon invocation • Methods and constructors • Ideal for business methods
Bean Validation 1.1 Method Validation Example @RequestScope public class Client { @Inject AccountService service; public void createClient() { service.createUser(...); } } @ApplicationScoped public class AccountService { @NotNull public User createUser( @NotEmpty String username, String firstname, String lastname, @Valid Address home, @NotNull @Email String email, @Past Date birthDate) { // parameters are validated and an exception // is raised upon failure // business } }
Bean Validation 1.1 Integration with JAX-RS • Offer resource validation • Using Bean Validation constraints • Exactly like method validation @Path(“/user”) public class UserResource { @Post @Consumes("application/x-www-form-urlencoded") public void register( @NotEmpty @FormParam(“firstname”) String firstname, @NotEmpty @FormParam(“lastname”) String lastname, @NotNull @Email @FormParam(“email”) String email) { ... } // Works on fields and getters too }
Bean Validation 1.1 Error messages using Expression Language • Ability to use EL inside error messages • Access to constraint parameters and invalid value • Offer localized string formatting too javax.validation.constraints.DecimalMax.message=\ must be less than ${inclusive == true ? 'or equal to ' : ''}{value}
Expression Language 3 Overview • EL first introduced in JSTL 1 • Moved to JSP 2 • Unified with JSF 1.2 in JSP 2.1 • Now independent specification • Used in JSF, JSP, CDI, BV and more
Expression Language 3 New Feature Summary • Stand-alone API • New operators • Static field and method references • Custom type converters • Lambda expressions • Collection construction • Collection/lambda operations
Expression Language 3 Support for stand-alone environments • Provides standard ELResolvers and ELContext • Direct expression evaluation ELProcessor elp = new ELProcessor(); Object message = elp.eval(“’Welcome ‘ += user.name”);
Expression Language 3 Support for stand-alone environments • Defining functions and variables ELProcessor elp = new ELProcessor(); elp.defineFunction(“func”, “ns”, “test.MyClass”, “funcname”); elp.setVariable(“var”, “user.name”);
Expression Language 3 Support for stand-alone environments • Defining beans ELProcessor elp = new ELProcessor(); ELManager elm = elp.getELManager(); // Define a bean on the fly, into local bean repository elm.definBean(“name”, new Name(“Peter”)); // Add a map to bean look-up elm.addBeanNameResolver(new BeanNameResolver() { @Override public Object getBean(String name) { return myDB.get(name); } });
Expression Language 3 String concatenation operator += • Cannot use + because it is already used for arithmetic operation ELProcessor elp = new ELProcessor(); elp.eval(“’Welcome ‘ += user.name”);
Expression Language 3 Assignment operator = • Can assign to an existing bean • Or dynamically create a new bean for the value • Handled by ELResolver.setValue ELProcessor elp = new ELProcessor(); elp.eval(“xx = user.name); elp.eval(“’Welcome ‘ += xx”);
Expression Language 3 Semicolon operator ; • Useful for side effects in complicated expressions ELProcessor elp = new ELProcessor(); elp.eval(“xx = user.name; ‘Welcome ‘ += xx”);
Expression Language 3 Custom type converters • Allow plugging in custom type converters elp.getELManager().addELResolver(new TypeConverter() { @Override public Object convertToType(ELContext context, Object obj, Class<?> type) { if (obj instanceof String && type == MyBean.class) { context.setPropertyResolved(true); return new MyBean((String) obj); } return null; } }); Object val = elp.getValue("'John Doe'", MyBean.class);
Expression Language 3 Static field and method references • Includes enum constants • Class must be imported before its static members can be referenced ELProcessor elp = new ELProcessor(); ELManager elm = elp.getELManager(); Elm.importClass(“com.acme.MyClass”); elp.eval(“MyClass.staticName”);
Expression Language 3 Static field and method references • java.lang package is pre-imported ELProcessor elp = new ELProcessor(); elp.eval("Boolean.TRUE"); elp.eval("Integer.numberOfTrailingZeros(16)");
Expression Language 3 Lambda expressions • Same syntax as Java SE 8 • Behaves like an anonymous function • Body consist of an EL expression • Full access to EL environment in the body x -> x+1 (x,y) -> x+y () -> 64
Expression Language 3 Lambda expression: immediate evaluation • The lambda is evaluated and discarded (x -> x+1)(10) 11 ((x,y)->x+y)(3,4) 7 (()->64)() 64
Expression Language 3 Lambda expression: indirect evaluation • A lambda can be named and evaluated indirectly • Allows recursive invocation incr = x -> x+1; incr(10) 11 fact = n->n==0? 1: n*fact(n-1); fact(5) 120
Expression Language 3 Lambda expression: as javax.el.LambdaExpression • A lambda is encapsulated as javax.el.LambdaExpression • Can be evaluated programmatically LambdaExpression lamb = (LambdaExpression)elp.eval(“x->x+1”); lamb.invoke(10); elp.eval(“[1,2,3].stream().map(x->x+1).toList()”);
Expression Language 3 Collection constructions • Sets, lists, and maps can be constructed dynamically Set: {1,2,3} List: [“eenie”, “meenie”, “miney”, “mo”] Map: {‘one’:1, ‘two’:2} Composite: {‘joe’: [‘m’,25], ‘amy’: [‘f’,18]}
Expression Language 3 Collection operations: overview • Heavily influenced by JDK 8 libraries • Implemented with lambda and method calls • Allows fluent syntax/builder pattern • About 20 operations
Expression Language 3 Collection operations: stream and pipeline • Operates on stream of collection objects • Operations can be chained together to form a pipeline • Pipeline: source stream, intermediate operations, terminal operation To list history book titles: books.stream().filter(b->b.category == ‘history’) .map(b->b.title) .toList()
Expression Language 3 Collection operations: examples customers.stream().filter(c->c.country=='USA’) .flatMap(c->c.orders.stream()) .toList() [1,3,5,2].stream().sorted().toList() people.stream().sorted((p,q)->p.name.compareTo(q.name)) .toList() [1,2,3,4].stream().reduce(0, (a,i)->a+i)) [1,2,3,4].stream().sum()
Summary Both BV 1.1 and EL 3 bring important changes Both from a Java EE 7 and ecosystem perspective Try the APIs out, provide your feedback and get involved
Resources • EL project page • https://java.net/projects/el-spec/ • Bean Validation project page • http://beanvalidation.org • Glassfish 4 • https://glassfish.java.net/