Spring Webflow: Unable to display error messages with jsr 303 validations - spring

I'm working with spring mvc 4.3.8 and spring webflow 2.4.5 along with thymeleaf 3.x. I'm unable to get the error messages from jsr-303 annotations displayed with spring webflow after validation fails. While the view itself is re-rendered, error messages are not displayed. what else do I need to do ? Please help.
<!-- WebFlow Configuration -->
<bean id="viewFactoryCreator"
class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
<property name="viewResolvers" ref="viewResolver" />
</bean>
<webflow:flow-builder-services id="flowBuilderServices"
view-factory-creator="viewFactoryCreator" validator="validator"/>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
<webflow:flow-registry id="flowRegistry"
flow-builder-services="flowBuilderServices" base-path="/WEB-INF/spring/flows">
<webflow:flow-location id="add-locale" path="/locale-flow.xml" />
</webflow:flow-registry>
<!-- the flow executor drives the execution of the flow -->
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry"/>
<!-- Enables FlowHandler URL mapping.
This handler adapter is the bridge between DispatcherServlet and the flow executor -->
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor" />
</bean>
<!-- Maps request paths to flows in the flowRegistry.
Tells DispatcherServlet to send flow requests to the FlowHandlerAdapter -->
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
<property name="flowRegistry" ref="flowRegistry" />
<property name="order" value="0" />
</bean>
locale-flow.xml
<input name="id"/>
<on-start>
<evaluate expression="localeController.newLocaleForm(id)" result="flowScope.localeForm" />
</on-start>
<view-state id="localeForm" view="locale/locale-form-p1" model="flowScope.localeForm">
<transition on="next" to="configureMessageBundle"/>
</view-state>
<view-state id="configureMessageBundle" view="locale/locale-form-p2" model="flowScope.localeForm" />
<view-state id="returnToViewPage" view="externalRedirect:locale-page.html" />
The backing form bean, LocaleForm.java
#NotNull(message = "Locale cannot be blank")
private String code;
#NotBlank(message = "Name cannot be blank")
#Size(min = 3, max = 255, message = "Name must be between 3 and 255 characters")
#Pattern(regexp = "^[\\w-_]+$", message = "Name can contain only alphabets, numbers, hypen and underscore")
private String name;
The form view page, locale-form-p1.html
<form class="form-horizontal" th:action="${flowExecutionUrl}" th:object="${localeForm}" method="post" enctype="multipart/form-data">
<div class="form-group">
<label class="control-label col-xs-2">Locale</label>
<div class="col-xs-10">
<select class="selectpicker form-control" tabindex="0" th:field="*{code}">
<option value="en_US" th:each="locale : *{availableLocales}"
th:value="${locale.key}"
th:text="${locale.value}">English (US)</option>
</select>
</div>
</div>
<div class="form-group required">
<label class="control-label col-xs-2">
Name <a role="button" data-toggle="popover" data-trigger="hover" data-html="true" title="" data-content="Provide a unique name for the Locale." data-placement="top"><span class="fa fa-info-circle"></span></a>
</label>
<div class="col-xs-10" th:classappend="${#fields.hasErrors('name')}? has-error">
<input class="form-control" type="text" placeholder="Name" th:field="*{name}" >
<span class="help-block" th:unless="${#fields.hasErrors('name')}">Allowed characters are alphabets, numbers, hyphen and underscore.</span>
<span class="help-block" th:errors="*{name}"></span>
</div>
</div>
<div class="form-group">
<div class="col-xs-2 col-xs-offset-2">
<button class="btn btn-primary btn-sm btn-primary-spacing" type="submit" name="_eventId_next">Next</button>
<button class="btn btn-default btn-sm" type="button" up-href="locale-page.html" up-target="#page-content">Cancel</button>
</div>
</div>
</form>

Resolved it. It turns out that Spring Web Flow has a different way of providing the user with feedback messages. The Spring Web Flow reference documentation says: “Spring Web Flow’s MessageContext is an API for recording messages during the course of flow executions”.
<div class="form-group required">
<label class="control-label col-xs-2">
Name <a role="button" data-toggle="popover" data-trigger="hover" data-html="true" title="" data-content="Provide a unique name for the Locale." data-placement="top"><span class="fa fa-info-circle"></span></a>
</label>
<div class="col-xs-10" th:classappend="${#arrays.length(flowRequestContext.messageContext.getMessagesBySource('name'))>0}? has-error">
<input class="form-control" type="text" placeholder="Name" th:field="*{name}" >
<span class="help-block" th:if="${#arrays.isEmpty(flowRequestContext.messageContext.getMessagesBySource('name'))}">Allowed characters are alphabets, numbers, hyphen and underscore.</span>
<p class="help-block" th:each="err : ${flowRequestContext.messageContext.getMessagesBySource('name')}" th:text="${err.text}">Input is invalid</p>
</div>
</div>

Related

Password reset using spring through mail

I have implemented, mailing feature through which a confirmation token is send to the user and on clicking the url provided, a page opens that fills the email id of the user to which the email is sent.
Then they can reset, however when i am trying to submit the form with the new password. It is not passing the value to the function i have provided.
#PostMapping("/resetUserPassword")
public String accountPasswordReset(#Valid #ModelAttribute("updateUserPassword") ResetPassword user, BindingResult theBindingResult, Model theModel){
//this line outputs null value
System.out.println("accountPasswordReset: email="+user.getEmail());
if(user.getEmail()!=null) {
User tokenUser = userService.findByEmailIdIgnoreCase(user.getEmail());
tokenUser.setPassword(passwordEncoder.encode(user.getPassword()));
userService.save(tokenUser);
return "successPasswordReset";
}else {
return "error";
}
}
<form:form action="${pageContext.request.contextPath}/register/resetUserPassword" modelAttribute="updateUserPassword" class="form-horizontal" method="POST">
<!-- Email -->
<div class="form-group">
<label for="emailId">Email (*)</label>
<form:input path="email" id="emailId" placeholder="email (*)"
class="form-control" disabled="true" readonly="true" />
<form:errors path="email" cssClass="error" />
</div>
<!-- Password -->
<div class="form-group">
<label for="password">Password (*)</label>
<form:password path="password" id="password"
placeholder="password (*)" class="form-control" />
<form:errors path="password" cssClass="error" />
</div>
<!-- Reset Button -->
<div style="margin-top: 10px" class="form-group">
<div class="col-sm-6 controls">
<button type="submit" class="btn btn-primary">Reset</button>
</div>
</div>
</form:form>
I was missing smallest thing, in this line i just removed disabled="true" and it works
<form:input path="email" id="emailId" placeholder="email (*)" class="form-control" disabled="true" readonly="true" />
to
<form:input path="email" id="emailId" placeholder="email (*)" class="form-control" readonly="true" />

Conditional rendering in Spring in Action 4

I've been working on an example on conditional rendering from Spring in Action 4.
The code looks this way:
<sec:authorize access="hasRole('ROLE_SPITTER')">
<s:url value="/spittles" var="spittle_url" />
<sf:form modelAttribute="spittle" action="${spittle_url}">`
<sf:label path="text"><s:message code="label.spittle" text="Enter spittle:"/> </sf:label>
<sf:textarea path="text" rows="2" cols="40" />
<sf:errors path="text" />
<br/>
<div class="spitItSubmitIt">
<input type="submit" value="Spit it!" class="status-btn round-btn disabled" />
</div>
</sf:form>
</sec:authorize>
The question is what does the code attribute, namely label.spittle refers to? Does it refer to the modelAttribute from the form? Or does it mean that there should be message bundle with key label.spittle?
It means a key in a resource bundle (documentation):
<s:message code="label.spittle" text="Enter spittle:"/>

How To Configure /oauth/token ModelAndView in Spring

I successfully configured an oauth spring application. However, my headache is how to make it return to the login page with a successful token; The log shows the following entry:
`DEBUG o.s.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling`
Here is my login page:
` <c:url value="/oauth/token" var="loginProcessingUrl"/>
<form:form action="${loginProcessingUrl}" method="post">
<fieldset>
<legend>Please Login</legend>
<!-- use param.error assuming FormLoginConfigurer#failureUrl contains the query parameter error -->
<c:if test="${param.error != null}">
<div>
Failed to login.
<c:if test="${SPRING_SECURITY_LAST_EXCEPTION != null}">
Reason: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />
</c:if>
</div>
</c:if>
<!-- the configured LogoutConfigurer#logoutSuccessUrl is /login?logout and contains the query param logout -->
<c:if test="${param.logout != null}">
<div>
You have been logged out.
</div>
</c:if>
<c:if test="${param.success != null}">
<div>
You have been successfully been authenticated.
</div>
</c:if>
<p>
<label for="username">Username</label>
<input type="text" id="username" name="username"/>
</p>
<p>
<label for="password">Password</label>
<input type="password" id="password" name="password"/>
</p>
<!-- if using RememberMeConfigurer make sure remember-me matches RememberMeConfigurer#rememberMeParameter -->
<p>
<label for="remember-me">Remember Me?</label>
<input type="checkbox" id="remember-me" name="remember-me"/>
<input type="hidden" id="client_id" name="client_id" value="11111111"/>
<input type="hidden" id="client_secret" name="client_secret" value="2222222"/>
<input type="hidden" id="grant_type" name="grant_type" value="password"/>
<input type="hidden" id="response_type" name="response_type" value="token"/>
<input type="hidden" id="redirect_uri" name="redirect_uri" value="/login?success=1"/>
</p>
<div>
<button type="submit" class="btn">Log in</button>
</div>
</fieldset>
`
And here's my spring-security.xml file:
`<http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="authenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER"/>
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>`
Why can't I go back to the login page once a token is successfully issued. Any help is appreciated.
Thanks

how to call two submit buttons in spring form, one calls j_spring_security_check and another one calling controller method

How to call two submit buttons in spring form,
one button calls j_spring_security_check and another button one calling controller method.
following is login form
<form action="../../j_spring_security_check" method="post" >
<div class="right">
<ul>
<li>
<spring:message code="label.userName" text="UserName" />
<input id="j_username" name="j_username" type="text" />
<form:errors path="firstName" cssclass="error"> </form:errors>
</li>
<li>
<spring:message code="label.password" text="Password" />
<input id="j_password" name="j_password" type="password" />
<form:errors path="password" cssclass="error"></form:errors>
</li>
<li>
<input type="submit" value="Login" />
</li>
</ul>
</div>
</form>
<form action="/portal/main/resetForgetPassword" method="POST">
<input type="submit" value="ForgetPassword">
</form>
thanks advance
I guess your problem is that for every URL it is going to Security form of spring.
So you need to permit for some url so that it should not go to j_spring_security_check
You can do this in the security.xml (whatever may be the name of that file).
<intercept-url pattern="/portal/main/forgetPassword*" access="permitAll" />
<intercept-url pattern="/*" access="hasRole('ROLE_ADMIN_ASSUMED')">
And also in your html code
Forget Password

Angular form validation in IE

I'm trying to get Angular form validation working in ie8. Here is my code:
<form id="contact-form" name="cform" target="_blank" >
<div class="left">
<div>
<div class="group">
<label for="firstname">First Name <span class="asterisk">*</span></label><br />
<input type="text" name="firstname" id="firstname" data-ng-model="firstname" required />
<span class="error" data-ng-show="cform.input.$error.required">Required!</span>
</div>
<div class="group">
<label for="lastname">Last Name <span class="asterisk">*</span></label><br />
<input type="text" name="lastname" id="lastname" data-ng-model="lastname" required />
<span class="error" data-ng-show="cform.input.$error.required">Required!</span>
</div>
</div>
<div>
<div class="group">
<label for="email">Email Address <span class="asterisk">*</span></label><br />
<input type="email" id="email" name="email" data-ng-model="email" required />
<span class="error" data-ng-show="cform.email.$error.email">Required!</span>
</div>
</div>
<div>
<div class="group">
<label for="phone">Primary Phone Number <span class="asterisk">*</span></label><br />
<input type="text" name="phone" id="phone" data-ng-model="phone" required />
<span class="error" data-ng-show="cform.input.$error.required">Required!</span>
</div>
<div class="group">
<label for="-secondary-phone">Secondary Phone Number</label><br />
<input type="text" name="secondary-phone" id="secondary-phone" />
</div>
</div>
</div>
<div class="right">
<div class="group">
<label for="message">Your Message</label><br />
<textarea id="message"></textarea>
</div><br />
<input type="submit" value="SEND MESSAGE" class="button">
</div>
</form>
This works in Firefox and Chrome, but in IE8 no validation errors are triggered. Anyone know what the issue might be?
Thanks.
UPDATE: This seems to be a problem in all versions of IE. {{cform.input.$error}} and {{cform.input}} don't show output in any browser.
<div class="group">
<label for="firstname">First Name <span class="asterisk">*</span></label><br />
<input type="text" name="firstname" id="firstname" data-ng-model="firstname" ng-required="true" />
<span class="error" data-ng-show="cform.firstname.$error.required && cform.firstname.$dirty">Required!</span>
</div>
Ie 8 does not support html 5 ,Angular is using html 5 , Do the work around to get angular working on IE and then use the pattern because you cant use the html 5 element

Resources