Transform & Execute Apache Struts 1.X Based Validations to Bean
Total Page:16
File Type:pdf, Size:1020Kb
International Journal of Computer Trends and Technology ( IJCTT ) - Volume 67 Issue 4 – April 2019 Transform & Execute Apache Struts 1.x based Validations to Bean Validation through JSF Vijay Kumar Pandey Director of Technology Solutions, Intueor Consulting, Inc. Irvine, CA (United States of America) Abstract. after the UPDATE_MODEL_VALUES phase to The paperis intended to provide an ensure that the action form bean (will call controller understanding of how to transform and execute bean in JSF) is populated with the request parameters. Apache Struts 1.x based validation to Bean Validation The downside to this is it will be populated with the and then execute the transformed validate method invalidated data. Developers need to ensure that their through Java Server Faces (JSF) runtime. JSF by forms do get validated before the data is sent for default executes the validation further processing through the PROCESS_VALIDATIONS after the INVOKE_APPLICATION phase. APPLY_REQUEST_VALUES phase and if there are no validation issues then the control passes to II. STRUTS VALIDATE TO JSF VALIDATE UPDATE_MODEL_VALUES phase else it goes to the RENDER_RESPONSE phase. While in the Struts 1.x Most of the struts-basedvalidators are based on application, first the Struts action form is populated the open source project Apache Commons Validator. with the request parameter values and then only it’s A standard Struts required validator maps to Bean ‘validate’ method is executed. So direct mapping of Validator’s NotNull constraint. For better struts validation execution process will fail in JSF understanding, a validated struts action form since model (action form) will not be populated with UserForm is created with a String property firstName, the request parameterswhen the validation is which will be configured with the required validation. executed. A. Struts based UserForm with firstName public class UserForm extends ValidatorForm { Keywords – Struts, JSF, ‘’validate’ method,Bean Validation (BV), OmniFaces, ThreadLocal, private String firstName; ActionForm, ControllerBean, TagHandler. public String getFirstName(){ return firstName; I. INTRODUCTION } Struts based validation of the action form is public void setFirstName(String firstName){ defined in the class ValidatorFormand executed this.firstName = firstName; through the validatemethodpublic ActionErrors } validate (Action Mapping mapping, Http Servlet public ActionErrors Request request). The implementation here executes validate(ActionMappingmapping,HttpServletRequest request) { all the configured struts-based validation on various properties of the form. Developers must execute this ActionErrors errors = super.validate(mapping, request) super method from their respective action forms if (errors.size() > 0) { validate method. Most of the time application will return errors; also have various non-configured validations that will } be present in the validate method. For every //some other specific validations validation failure in struts, an ActionErrorwill be } created and stored in request/response for it to be displayed during the rendering of the page. If the B. Struts Validation Configuration transformed JSF application from Struts transforms <form name="userform"> the struts-based validation config to Bean Validation, <field property="firstName" depends="required"> based constraint annotations and would like to <msg name="required" key="error.required.firstName"/> execute the transformed validate method in JSF only </field> after the UPDATE_MODEL_VALUES phase, then </form> the default lifecyle of JSF should be changed to provide this feature. JSF is a feature rich framework The userform above provides the struts validation and this unique problem can be solved through the configuration, based on the validate method.The code usage of a JSF based tag handler. A JSF based tag super.validate(mapping, request)will make use of the handler can execute the transformed validate method validation config and if any validation error, it gets added to the ActionErrors. ISSN: 2231 – 2803 http://www.ijcttjournal.org Page 24 International Journal of Computer Trends and Technology ( IJCTT ) - Volume 67 Issue 4 – April 2019 C. JSF based User Controller Bean with first Name A. Stopping Bean Validation during Instead of calling this class as a form, which PROCESS_VALIDATIONS was mainly a Struts way of naming them, let’s call A JSF based tag handler will be designed to this form class as UserControllerBean. This will manoeuvre the mechanism of moving the extend from a base class, that can provide all the PROCESS_VALIDATIONS phase after the common functionality and the implementation of the UPDATE_MODEL_VALUES phase. Bean Validation. public class ValidateTagHandler extends TagHandler public class UserControllerBean extends BaseControllerBean { @NotNull(message = "{error.required.firstName}") This being a tag handler for processing validation private String firstName; mainly on html form submission, it should only be set public String getFirstName(){ up during postBack processing for the return firstName; RESTORE_VIEW phase. } if (! (ComponentHandler.isNew(parent) public void setFirstName(String firstName){ &&facesContext.isPostback() this.firstName = firstName; &&facesContext.getCurrentPhaseId() == RESTORE_VIEW)) { } return; } public voidvalidate() { FacesContextfacesContext = FacesContext.getCurrentInstance(); super.validate(); Once the RESTORE_VIEW phase has completed, if (facesContext.getMessageList(). size() > 0) { all the JSF components will be set up.soDuring the return; tag handlerprocessing, add a phase listener that will } be executed after the RESTORE_VIEW phase is //some other specific validations completed. The main operations that will happen in } this dynamic phase listener are Remove the JSF based BeanValidator from the JSF In the above class, the field firstName is annotated component or else the validation will get invoked with the NotNull Bean Validation constraint during the PROCESS_VALIDATION annotation, which is likerequired validation from Struts. The validate method has been transformed by Validator[] validators = component.getValidators(); removing all the Struts based parameters and for (Validator validator : validators) { if (validator instanceofBeanValidator) { managing any request/response-based invocation return (BeanValidator) validator; through FacesContext. In the super class,validate } method will be implemented to provide Bean }//create a dummy validation group Validation based implementation. private interface NoValidationGroup {} //set a dummay validation group so that actual validation does D. Bean Validation JSF based implementation //not invokes Below is a code excerpt on how to take a String nonValGroup = NoValidationGroup.class.getName(); ControllerBean and validate the bean validation constraint annotations annotated on the field or the //keep the original validation group – that will be reset after //this phase property. beanValidator.setValidationGroups(nonValgroup); javax.validation.Validator validator = // fetch the validator for (String property : propertyList) { Set violationsRaw = validator.validateValue(this.getClass(), Add a new JSF validator Collect Submit Val property, propertyValue, beanValGroups); Validatdor to the JSF component that basically //add the violations as JSF error message collects the submitted and converted value through } its validate method but doesn’t perform the actual validation. This collection of submitted/converted III. JSF TAG HANDLER MECHANISM TO value will laterbe validated through Bean CHANGE LIFECYCLE Validation. Transforming Struts based validation to Bean Validation and executing it through JSF runtime, will component.addValidator(new <<SomeValidator to extract submitted value>>); require execution of validate method of the ControllerBean, after it has been populated with the Both above processes of removing the bean validation request parameters. To ensure this, validate method by adding a dummy validation group, along with needs to be executed after the UPDATE_MODEL adding a new validator to collect the submitted and phase. The section below will describe how to set up converted values, must be set to be executed through this mechanism in JSF. a phase listener.This should be invoked before the PROCESS_VALIDATIONS phase. ISSN: 2231 – 2803 http://www.ijcttjournal.org Page 25 International Journal of Computer Trends and Technology ( IJCTT ) - Volume 67 Issue 4 – April 2019 A new phase listener should also be setup to be invoked after the PROCESS_VALIDATIONS phase, to ensure to reset the original validation group related to bean validation and remove the new validator CollectSubmitValValidatdor from the component that was added to collect the submitted values. //restore the original bean validation group BeanValidatorbeanValidator = getBeanValidator(component); if (beanValidator != null) { String originalValiGrp = component.getAttributes() .remove(“original_bean_val_group”); beanValidator.setValidationGroups(“original_bean_val_group”) ; } //remove the ‘CollectSubmitValValidatdor’ EditableValueHoldervalueHolder = //reference component E. User Controller Bean The code in the bean below shows the validate Validator colValidator = null; method and annotated firstNamefield with the for (Validator validator : valueHolder.getValidators()) { NotNull constraint annotation and shows a manual if (validator instanceofCollectSubmitValValidatdor) colValidator = validator; custom error condition. break; } } if (colValidator != null)