通常Scala被认为比Java要慢,特别是用于函数式编程时。本文会解释为什么这个被广泛接受的假设是错误的。 数据验证编程中一个常见的问题是数据验证。即我们要确保所有得到的数据处于正确的结构中。我们需要从安全的,编译器验证的数据中找到不安全的外部输入。在一 个典型的WEB应用中,你需要验证每个请求。很明显这会影响你的应用的性能。在本文中我将会比较处理这个问题的两种极不相同的解决方案。Java的 Bean验证API和来自play的统一验证API。后者是一种更为函数式的方法,它具有不变性和类型安全的特性。 Java: Bean 验证API, aka JSR 303Bean验证规范首发于2009年。此API使用注解为JavaBean设置约束。然后你需要在一个注解实例上调用验证方法来验证这个Bean的有效性。它的最著名的参考实现来自于Hibernate.
public class Car { @NotNull private String manufacturer; @NotNull @Size(min = 2, max = 14) private String licensePlate; @Min(2) private int seatCount; // ... } 这只是用于声明,真实的验证应该像这样(同样来自于他们的网址)。 ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator(); Car car = new Car("Ford", "0xCAFEBABE", 2); Set<ConstraintViolation<Car>> constraintViolations = validator.validate( car ); 所以你将一个实例传递给validator.validate并获得一个包含错误的Set。如果这个Set是空的,那这个对象就是正确的。 通常你需要用此API来验证Json和XML.以下是一个解析和验证Json对象的例子。 public class Car { @NotNull private String manufacturer; @NotNull @Size(min = 2, max = 14) private String licensePlate; @Min(2) private int seatCount; // getters and setters } String json = ... // contains a json string representing a car ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator(); ObjectMapper mapper = new ObjectMapper(); Car car = mapper.readValue(json, Car.class); // use Jackson to unmarshall the json Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car); Scala: Play 统一验证 API.这个统一验证API 致力于提供验证任何数据结构所需的核心原语。它的主要目的是替代Json验证API和play框架中的表单验证API。它易于拓展且支持Json验证和非传统的表单验证。 以下是一个Json验证场景的一点。注意这次我们在直接验证Json。 case class Car(manufacturer: String, licensePlate: String, seatCount: Int) val carValidation = From[JsValue]{ __ => ((__ \ "manufacturer").read[String] ~ (__ \ "seatCount").read(min(2)) ~ (__ \ "licensePlate").read(minLength(2) |+| maxLength(14)))(Car.apply _) } val json: String = ... // contains a json string representing a car val validationResult = From[JsObject, Car](json) 在实现此API时,我没有太注重性能。我的主要目标是正确性,组合性和类型安全。实例上一些设计选择,例如惰性验证,都会对性能产生影响。接下来我们看下它是如何执行的。 |