The ValidatorService provides the link between the REST framework and the validator framework. You can invoke the ValidatorService directly by using the invokeValidator method or by using the methods available in the RestUtils class.

If the endpoint has been annotated with isValidatedByFramework=true, then the REST framework invokes the ValidationService using the invokeValidator method. For example:

/**
  * Main entry point for validating an input object when
  * wanting to allow the framework to control selection of
  * validator, target bean, type of update etc.
  * @param pInputObject object to validate
  */
 public void invokeValidator(Object pInputObject)

The service tries to obtain the validator to use for a particular object by obtaining the validatorId endpoint setting from the RestContext.

The ValidationService provides access to the validator framework for the validation of incoming JSON JAX-RS messages and, optionally, the updating of target beans or repository items.

Whenever a PUT, POST or Patch operation occurs, its input is run through a validator service. The rules for this validation are configured using the payload schema XML file. Validation can be performed automatically by the framework or can be done manually using the endpoint. Validators are associated with an endpoint by using the validatorId endpoint annotation, which references the unique ID associated with a schema in the validation XML file. If validation fails, a 400 BAD_REQUEST response is returned to the client along with details of the property or properties whose values are invalid.

For additional information on the payload schema, refer to the Working with the Payload Schema section.

Configuring Automatic Validation

The ValidatorManager manages the validation of property values and maintains a Hashtable for the creating and updating of mapping from a property name to a validator. It also provides code to update one dynamic bean from another, enabling a way of going from input endpoint JSON to updating objects.

Validation is automatically performed for any update request by the ValidatorManager component using the defined schema for the endpoint. In addition to rejecting invalid input, the validation process also determines any sets of changes that the endpoint may need to apply, and can pre-populate target beans directly with the input values. The validation process first tries to GET the latest version of the resource. While validating against the schema, the validation process can also update the resource with the values taken from the input. For collection resources, elements are matched against the input by comparing ID fields.

If you want validation to occur automatically, your endpoints must specify a validatorId endpoint annotation. If you do not want the framework to validate an endpoint, change the isValidatedByFramework endpoint annotation from its default to false. The automatic update of the target beans by the validation process can be disabled using the @Endpoint annotation updateTarget attribute. RestUtils also has a method that you can use to manually invoke the validation process if automatic validation has been disabled for an endpoint. For additional information on validation, refer to the Working with the Payload Schema section.

Configuring Manual Validation

You can manually handle input validation by using the validateInputObject utility method that is available in RestUtils.

The payload schema framework can also provide additional support for an endpoint, depending on the endpoint type. For example, an endpoint can create a new resource or update an existing resource. If the message validates successfully, then a requestUpdateInfo property is populated on the current RestContext.

Use the endpoint annotation to assign a validator to a specific endpoint.

public @interface Endpoint
{
 ...
 String validatorId() default NULL_STRING;
 ...
}

This allows a validator to be associated to an endpoint:

@Endpoint(id="test.addorders.orderId", validatorId="type.id.addItem")
public RepresentationModel defaultGet(@PathParam("orderId") String pOrderId){
Working with Endpoints that Create Resources

For endpoints that create resources, the ResourceUpdateInfo, which is available using the RestUtils.getRestUtils().getResourceUpdateInfo() method, can provide validated input in the form of a map or an actual instance of the bean. Additionally, you can use the getUpdates() method to get the actual single item to be created.

If getUpdates is set to true, the framework tries to create an instance of the bean or repository item defined by the validator. The factory attribute can identify a Nucleus component or Java class that can create an instance of the target class. This may be required where the target instance requires initialization before it can be used. The Java class referenced by the factory attribute must implement the atg.service.validator.BeanInstanceFactory interface. For example:

<validator id="type.id-addItem">
  <bean class="atg.commerce.order.SomeItemType"
      factory="nucleus:/atg/commerce/order/restresources/SomeItemTypeCreator"/>
  ...
</validator>

If getUpdates is set to false, the ResourceUpdateInfo contains the validated input in the form of a java.utl.Map, which may be more convenient for the endpoint than working with the raw org.json.JSONObject. However the raw org.json.JSONObject is still available from the RestContext.inputJson property.

Working with Endpoints that Update Resources

For endpoints that update existing resources, the framework can validate and then apply incoming changes to the target bean.

Use the getMembersUpdateInfos() method of the ResourceUpdateInfo object to get information on the updated for a collection. Use the getTarget method of the ResourceUpdateInfo object to get information on the update of a single resource.

For detailed information on validation, refer to the Working with the Payload Schema section.

Reusing Validators

Both schema and bean-property properties allow the validators to be reused with the use-validator-id attribute. When this attribute is specified, the validator code retrieves the properties and bean-properties of the referred validator. The filtering code must inspect the schema and bean-property for the use-validator-id and, if populated, retrieve the properties and bean properties from that validator.

For example:

<validator id="orders.id-Other" use-validator-id="/orders/{id}-Summary">
  <bean class="atg.TestOrder"/>
</validator>

<validator id="orders.id-AndAnother" include-all-simple="true">
  <bean class="atg.TestOrder"/>
  <bean-property name="commerceItems" use-validator-id="orders.
      commerceitems.id-Summary"/>
</validator>
Validating Collections

Validators can be configured for beans and bean properties. To do this, set the treat-container-as-bean attribute of the schema and bean-property properties. The key/value pairs of the map are written to the output according to the schema and bean-property configuration, which will refer to the map keys.

Note: There may be errors upon startup of the ValidatorRegstry component since Map has neither description nor quantity properties.

The following is an example of using the treat-container-as-bean attribute:

<validator id="orders.id-Other" treat-container-as-bean="true">
  <bean class="java.util.Map"/>
  <property name="description" hidden="false"/>
  <property name="quantity" hidden="true"/>
</validator>

For additional information on the treat-container-as-bean attribute, refer to the Working with the Payload Schema section.

Use the pseudo-property value when you do not want a map to be treated as a dynamic bean. This configuration is applied to all values of the map when producing output:

<validator id="orders.commerceItems.id-Test" treat-container-as-bean="false">
  <bean class="java.util.Map"/>
  <bean-property name="value">
    <bean class="atg.TestCommerceItem"/>
    <property name="id" hidden="false"/>
    <property name="quantity" hidden="true"/>
  </bean-property>
</validator>

When working with collections, use the element pseudo-property. The configuration is applied to all elements of the collection when producing output:

<validator id="orders.commerceItems.id-Test">
  <bean class="java.util.Collection"/>
  <bean-property name="element">
    <bean class="atg.TestCommerceItem"/>
    <property name="id" hidden="false"/>
    <property name="quantity" hidden="true"/>
  </bean-property>
</validator>

If the value or element pseudo-property is not specific but the output code detects a map or collection, the framework attempts to apply the schema or bean-property configuration to all of the values or elements of the collection.

Configuring Timestamps

By default, timestamp properties returned in output are configured as Long. You can create a custom instance of a PropertyCustomizer that converts the Long format to a formatted date using the request locale. For example:

<property name="lastModifiedTime" writable="false" property-
    customizer="/atg/dynamo/service/filter/bean/CustomDatePropertyCustomizer"/>

Copyright © 1997, 2017 Oracle and/or its affiliates. All rights reserved. Legal Notices