I'm having a problem formatting the contents of a bound Date field in a spring webflow form. The validation end of things is working, and correctly enforces the date format specified in my annotation. But whatever I try, I can't control the format of the initial display of the bound Date field (which is pre-populated with the current date). I'm using Spring 3.1.2.RELEASE, Webflow 2.3.2.RELEASE, and joda-time 2.2.
The date field in the form is initially populated with eg "Thu Apr 04 02:01:06 BST 2013", whereas I want it to contain "04:04:2013". (Don't mind the funny format with the colons - I'm only avoiding common formats for testing!)
If I overtype it with, eg 13:01:2013 and submit, the binding works fine and the webflow continues. Overtyping eg 13/01/2013 causes validation to fail with a ValueCoercionException, and the field on the webpage is re-populated with the "Thu Apr..." string. So validation, at least, seems to be OK.
I understood that the #DateTimeFormat annotations worked as both printer and parser, but I just can't get the printer side of things working.
Here are the relevant bits of my code...
event_add.xml (webflow)
<var name="event" class="project.persistence.DTO.EventDTO"/>
...
<view-state id="event_enterdates" model="flowScope.event">
<transition on="submit" to="saveEvent" />
</view-state>
EventDTO.java
public class EventDTO implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
#DateTimeFormat(pattern="dd:MM:yyyy")
private Date eventDate;
...
}
event_enterdates.jsp
<sf:form method="POST" commandName="event">
<input type="hidden" name="_flowExecutionKey" value="${flowExecutionKey}"/>
...
<div class="grid_3 formitemname"><label for="event_date">Event date:</label></div>
<div class="grid_3">
<sf:input path="eventDate" maxlength="255" id="event_date" class="form9colinput"/>
...
</sf:form>
project-servlet.xml
<mvc:annotation-driven />
<context:component-scan base-package="project"></context:component-scan>
<flow:flow-executor id="flowExecutor" flow-registry="flowRegistry" />
<flow:flow-registry id="flowRegistry" base-path="/WEB-INF/flows" flow-builder-services="flowBuilderServices">
<flow:flow-location-pattern value="*.xml" />
</flow:flow-registry>
<flow:flow-builder-services id="flowBuilderServices" conversion-service="defaultConversionService" view-factory-creator="viewFactoryCreator" />
<bean id="viewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
<property name="viewResolvers" ref="tilesViewResolver" />
</bean>
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
<property name="flowRegistry" ref="flowRegistry" />
</bean>
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor" />
</bean>
<bean id="defaultConversionService" class="org.springframework.binding.convert.service.DefaultConversionService">
<constructor-arg ref="applicationConversionService"/>
</bean>
<bean id="applicationConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />
Anyone have any idea how to get my bound date to display in the format specified in the #DateTimeFormat pattern?
Cheers,
Ian
Have you tried using a Property Editor. Spring already has one available for converting Dates.
In your #Controller that is handling the request you will instruct spring to convert to and from a particular format:
#InitBinder
protected void initBinder(final WebDataBinder binder) {
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("dd:MM:yyyy") , false));
}
Related
I'm testing for the first time Thymeleaf 3.x with a simples web app, and I'm having some issues doing form validation. I'm not able to change the graphical style of my form fields with the Thymeleaf attribute th:errorclass, and I don't know why.
Here is my controller:
#RequestMapping(value = {"/" , "" , "/home" , "/index" , "/login"} , method = RequestMethod.GET)
public String getLogin(final Model m)
{
if(m.containsAttribute("login") == false)
{
System.out.println("Creating login form...");
m.addAttribute("login", new For_Login());
}
return Util_Paginas.PAG_LOGIN.toString();
}
#RequestMapping(value = "/login" , method = RequestMethod.POST)
public String authenticate(
#Valid #ModelAttribute("login") final For_Login form ,
final BindingResult br ,
final Model m)
{
System.out.printf("Authentication received!%n");
System.out.printf("LOGIN: %s%n" , form.getLogin());
System.out.printf("PASS: %s%n" , form.getSenha());
if(br.hasErrors())
{
System.out.printf("Found %d fields!%n" , br.getErrorCount());
}
return Util_Paginas.PAG_LOGIN.toString();
}
My HTML file with Thymeleaf 3.x nature:
<!DOCTYPE html>
<html>
<head>
<title>Login page</title>
<link rel="stylesheet" type="text/css" media="all" th:href="#{/css/estilos.css}" />
</head>
<body>
<p>Welcome. Please login.</p>
<form action="#" th:action="#{/login}" th:object="${login}" method="post">
<fieldset>
<p>
Login:
<input
type="text"
th:field="*{login}"
th:class="campo"
th:errorclass="campo-invalido">
</p>
<p>
Password:
<input
type="password"
th:field="*{senha}"
th:class="campo"
th:errorclass="campo-invalido">
</p>
<p>
<input type="submit" value="Submit"/>
</p>
</fieldset>
</form>
</body>
</html>
My CSS file:
#CHARSET "ISO-8859-1";
.campo
{
background-color: gray;
border: 2px solid red;
}
.campo-invalido
{
background-color : #ff0000;
border: 1px solid #800000;
width: 230px;
color: white;
}
p
{
color: blue;
font-size: 22pt;
}
What is happening is that the style is not being applied. Errors are found on the server side, but when the page is returned, it is as if the th: errorclass attribute was not present. I do not know what I'm doing wrong.
I know that my css file is being read because the P tags are getting stylized.
I'm using:
Eclipse Mars.2 Release (4.5.2)
thymeleaf 3.0.3 RELEASE
thymeleaf-spring4 3.0.3 RELEASE
spring-webmvc 4.1.1 RELEASE
spring-context 4.1.1 RELEASE
validation-api 1.1.0 FINAL
hibernate-validator 5.3.4 FINAL
If in case someone wants to see some more code of my project, I'll be happy to present it here.
Thank you for your time and patience.
EDIT
I almost forgot something important too, my Spring MVC Application Context file:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd ">
<!-- ################################################################################### -->
<!-- MAPEAMENTO DE RECURSOS -->
<!-- ################################################################################### -->
<!-- Mapeamento de recursos (arquivos css, fontes, imagens, dentre outros). -->
<mvc:resources mapping="/css/**" location="/WEB-INF/recursos/css/" />
<mvc:resources mapping="/imagens/**" location="/WEB-INF/recursos/imagens/" />
<mvc:resources mapping="/fontes/**" location="/WEB-INF/recursos/fontes/" />
<!-- ################################################################################### -->
<!-- ANOTAÇÕES E RECURSOS SPRING -->
<!-- ################################################################################### -->
<!-- Possibilita o uso de anotações Spring Mvc. -->
<mvc:annotation-driven />
<!-- Define local para procura de componentes Spring (beans configurados
por anotações em classes). -->
<context:component-scan base-package="com.regra7.st.controle" />
<!-- ################################################################################### -->
<!-- INTERNACIONALIZAÇÃO -->
<!-- ################################################################################### -->
<!-- ################################################################################### -->
<!-- CONFIGURAÇÕES DO THYMELEAF -->
<!-- ################################################################################### -->
<!-- Template Resolver para Template Engine. -->
<!-- <bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
<property name="prefix" value="/WEB-INF/templates/" /> <property name="suffix"
value=".html" /> <property name="templateMode" value="HTML5" /> </bean> -->
<!-- SpringResourceTemplateResolver automatically integrates with Spring's
own -->
<!-- resource resolution infrastructure, which is highly recommended. -->
<bean id="templateResolver"
class="org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/WEB-INF/templates/" />
<property name="suffix" value=".html" />
<!-- HTML is the default value, added here for the sake of clarity. -->
<property name="templateMode" value="HTML" />
<!-- Template cache is true by default. Set to false if you want -->
<!-- templates to be automatically updated when modified. -->
<property name="cacheable" value="true" />
</bean>
<!-- SpringTemplateEngine automatically applies SpringStandardDialect and -->
<!-- enables Spring's own MessageSource message resolution mechanisms. -->
<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
<!-- Enabling the SpringEL compiler with Spring 4.2.4 or newer can speed
up -->
<!-- execution in most scenarios, but might be incompatible with specific -->
<!-- cases when expressions in one template are reused across different
data -->
<!-- ypes, so this flag is "false" by default for safer backwards -->
<!-- compatibility. -->
<property name="enableSpringELCompiler" value="true" />
</bean>
<!-- ################################################################################### -->
<!-- CONFIGURAÇÕES DO SPRING MVC -->
<!-- ################################################################################### -->
<!-- View resolver do Thymeleaf. -->
<bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
<property name="templateEngine" ref="templateEngine" />
</bean>
<!-- Definição de HandlerMapping. -->
<!-- Cuida de classes controladoras. -->
<!-- <bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
</bean> -->
<!-- ################################################################################### -->
<!-- INTERCEPTADORES -->
<!-- ################################################################################### -->
<!-- INTERCEPTADORES -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/usuario/*" />
<bean class="com.regra7.st.interceptadores.Login" />
</mvc:interceptor>
</mvc:interceptors>
</beans>
EDIT 2
After messing around a bit with the validation code, I changed the approach used and suddenly, things started to work.
Previously, I was using bean validation with my own annotations for data validation. I decided to change to the validation done with Spring, using org.springframework.validation.Validator, And magically everything went well.
However, I would not like to use the data validation approach with Spring, but rather with bean validation annotations. I've figured out where I'm wrong, but I do not understand why.
I'll put my login validation code:
// My bean validation annotation.
#Documented
#Constraint(validatedBy = Val_Login.class)
#Target({ElementType.METHOD , ElementType.FIELD , ElementType.ANNOTATION_TYPE})
#Retention(RetentionPolicy.RUNTIME)
public #interface Login
{
String message() default "{com.regra7.st.login}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
int min() default 10;
int max() default 20;
}
// Validator implementation.
public class Val_Login implements ConstraintValidator<Login , String>
{
private int min;
// private int max;
#Override
public void initialize(Login login)
{
this.min = login.min();
// this.max = login.max();
}
#Override
public boolean isValid(String value, ConstraintValidatorContext context)
{
return Util_Validador.isLoginValido(value , this.min);
}
}
// The form input object.
public class For_Login
{
#Login(min = 8)
private String login;
// Many things ommited
}
The Util_Validador class is able to return a true or false value, this has already been tested. If I do this:
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import com.regra7.st.formularios.For_Login;
import com.regra7.st.util.Util_Texto;
public class ValidadorFormulario implements Validator
{
#Override
public boolean supports(Class<?> clazz)
{
return For_Login.class.isAssignableFrom(clazz);
}
#Override
public void validate(Object objeto, Errors erros)
{
For_Login log = (For_Login) objeto;
if(Util_Texto.isVazia(log.getLogin()) ||
log.getLogin().length() < 8)
{
erros.rejectValue("login", "Login errado!");
}
if(Util_Texto.isVazia(log.getSenha()) ||
log.getSenha().length() < 14)
{
erros.rejectValue("senha", "Senha errada!");
}
}
}
Everything works out. Can you guys help me a bit, please? I think this can help many people who get on the same place as me.
As always, thank you.
I did two things wrong:
I forgot to import some libraries needed by Hibernate Validator.
I was using prefixes for form fields (For_Login). The data binding
was not happening properly. Actually, it was, but Thymeleaf was not
recognizing it properly. It's no use having a field named _myField
(for instance), and setting setMyField and getMyField methods. Either
you write the field with the name myField, or the methods with the
names get_myField and set_myField.
I have been trying to get this code to work. I've just started with Spring MVC (and I'm relatively new to web dev - my background is GUI dev/science) but I think the error may be triggered because there is a problem linking the jquery code in my jsp to the Spring controller. I've literally been trying to get this to work for days without success and I've tried all the suggestions made by posters on this forum with a similar problem - to no avail. I'd therefore very much appreciate your input. The project is being developed using Netbeans, Tomcat 8, Maven, Spring MVC, and Jquery.
projectDashboard.jsp (in WEB-INF/views):
<div class="col-lg-8 col-md-8 col-sm-8">
<div id="projectForm">
<div class="form-group">
<input id="name" name="name" type="text" class="form-control" placeholder="Project name (50 characters or less)"/>
<textarea id="description" name="description" class="form-control" placeholder="Project Description (200 characters or less)"></textarea>
</div>
<div class="form-group">
<input class="btn btn-primary pull-right" id="createProjectButton" value="Create" type="button"/>
</div>
</div>
</div>
JQuery:
<script>
$(document).ready(function(){
$("#createProjectButton").on("click", function(){
var projectJson = {
"name":$("#name").val(),
"description":$("#description").val()
};
$.ajax({
type: "POST",
url: "/ProgressManagerOnline/projectDashboard",
data: JSON.stringify(projectJson),
contentType: "application/json; charset=utf-8",
dataType: "json"
});
});
});
</script>
ProjectDashboard.java (Spring MVC controller class in src/main/java):
#RequestMapping(value = "/projectDashboard", method = RequestMethod.POST)
public String saveProject(#RequestBody Project project) throws Exception {
return "OK";
}
Relevant code in appconfig-mvc.xml:
<mvc:annotation-driven/>
<mvc:view-controller path="/" view-name="login"/> //home web page - login.jsp
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
Maven pom.xml includes:
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.5</version>
</dependency>
Tomcat context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/ProgressManagerOnline"/>
Error in Firefox web console:
The requested resource is not available. (404 error)
My Project.java:
#Entity
#Table(name = "projects")
public class Project implements Serializable {
private Long id;
private String name;
private String description;
private java.util.Date dateCreated;
public Project(){};
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id){
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Column(name = "dateCreated", columnDefinition="DATETIME")
#Temporal(TemporalType.TIMESTAMP)
public Date getDateCreated() {
return dateCreated;
}
public void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}
}
I've been at this for days now and have tried every suggestion posted on this forum and others.
Many thanks in advance to anyone who can help out.
You are missing couple of configurations I guess in your application.
You require auto conversion of json to java object ,
#RequestBody Project project
Hence you need to add json converter so please look documentation : http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/converter/json/MappingJackson2HttpMessageConverter.html
Add following in your configuration context xml along with required dependencies added in your pom.xml,
<!-- Configure bean to convert JSON to POJO and vice versa -->
<beans:bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
<!-- Configure to plugin JSON as request and response in method handler -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonMessageConverter"/>
</list>
</property>
</bean>
(Posted on behalf of the OP).
The solution suggested by TechBreak worked - I was missing the Spring context dependency in my pom.xml and the extra config in my xml:
<!-- Configure bean to convert JSON to POJO and vice versa -->
<bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
<!-- Configure to plugin JSON as request and response in method handler -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonMessageConverter"/>
</list>
</property>
</bean>
After a restart of the server and
mvn clean install
Cheers.
The power of Spring Roo is that it handles the difficult stuff.
Question: if there a good best practice and implementation on how to show to each user, where ever he lives on this planet, the dates in local time.
Issue:
When a user enters a date and goes to the "list all visits" page, he/she will see a total different date, if he /she is in a different timezone than the OpenShift server. For example I'm in GMT+1 (West Europe) timezone.
My situation:
Web application is developed with Spring Roo 2.0 / gvNIX 2.0
Will be hosted on OpenShift (rhcloud.com)
Like the petclinic sample: https://petclinic-gvnix.rhcloud.com/
Users can live everywhere in the world, so every timezone.
Java 8 is at this time not an option, because OpenShift has not TomCat 8 deployment yet, and, if possible, I want to keep away from creating a OpenShift DIY application.
Requirement:
Each user should see the dates in his local time.
Reproduce:
Go the the Petclinic sample and log in: https://petclinic-gvnix.rhcloud.com/
Choose Visit -> Create new visit
Choose List all Visits
When you are in a different timezone than the Openshift server you get something like above
Having thought about this problem, I think I have a clean solution for implementing Timezone support without affecting current projects.
My starting point is that the solution should be backward compatible and should not break current projects. Also the change should be as little as possible.
I tested it and it works, also when my web application runs on Openshift, where it is hosted in TimeZone GMT-5:00 and me living in West Europe, GMT +1:00
Please give me your opinions.
I will describe the solution / proposal for the show.jspx views. But in the same way it can be implemented for the other views as well.
The essense of the change is that I added timeZone to the fmt:formatDate .. statement in WEB-INF/tags/form/fields/column.tagx/display.jspx:
Old:
<fmt:formatDate value="${object[field]}" pattern="${fn:escapeXml(dateTimePattern)}" />
New:
<fmt:timeZone value="${timeZone}">
<fmt:formatDate value="${object[field]}" pattern="${fn:escapeXml(dateTimePattern)}" timeZone="${timeZone}" />
</fmt:timeZone>
For this to work I also added the declaration and a default timeZone setting when not used.
<jsp:root xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:fn="http://java.sun.com/jsp/jstl/functions" xmlns:fmt="http://java.sun.com/jsp/jstl/fmt" xmlns:spring="http://www.springframework.org/tags" xmlns:form="http://www.springframework.org/tags/form" xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
<jsp:output omit-xml-declaration="yes" />
<jsp:directive.attribute name="id" type="java.lang.String" required="true" rtexprvalue="true" description="The identifier for this tag (do not change!)" />
<jsp:directive.attribute name="object" type="java.lang.Object" required="true" rtexprvalue="true" description="The form backing object" />
<jsp:directive.attribute name="field" type="java.lang.String" required="true" rtexprvalue="true" description="The field name" />
<jsp:directive.attribute name="label" type="java.lang.String" required="false" rtexprvalue="true" description="The label used for this field, will default to a message bundle if not supplied" />
<jsp:directive.attribute name="date" type="java.lang.Boolean" required="false" rtexprvalue="true" description="Indicate that this field is of type java.util.Date" />
<jsp:directive.attribute name="calendar" type="java.lang.Boolean" required="false" rtexprvalue="true" description="Indicate that this field is of type java.util.Calendar" />
<jsp:directive.attribute name="dateTimePattern" type="java.lang.String" required="false" rtexprvalue="true" description="The date / time pattern to use if the field is a date or calendar type" />
========== Added declaration
<jsp:directive.attribute name="timeZone" type="java.lang.String" required="false" rtexprvalue="true" description="The timezone to use if the field is a date or calendar type" />
========== End
<jsp:directive.attribute name="render" type="java.lang.Boolean" required="false" rtexprvalue="true" description="Indicate if the contents of this tag and all enclosed tags should be rendered (default 'true')" />
<jsp:directive.attribute name="z" type="java.lang.String" required="false" description="Used for checking if element has been modified (to recalculate simply provide empty string value)" />
<c:if test="${empty render or render}">
<c:if test="${not empty object and empty label}">
<spring:message code="label_${fn:toLowerCase(fn:substringAfter(id,'_'))}" var="label" htmlEscape="false" />
</c:if>
<c:if test="${empty dateTimePattern}">
<c:set value="MM/dd/yyyy" var="dateTimePattern" />
</c:if>
========== Added default setting. Taking the timezone of the server!
<c:if test="${empty timeZone}">
<jsp:scriptlet>
jspContext.setAttribute("timeZone", java.util.TimeZone.getDefault().getID());
</jsp:scriptlet>
</c:if>
========== End
<div id="_${fn:escapeXml(id)}_id">
<label for="_${fn:escapeXml(field)}_id">
<c:out value="${label}" />
:
</label>
<div class="box" id="_${fn:escapeXml(id)}_${fn:escapeXml(field)}_id">
<c:choose>
<c:when test="${date}">
<spring:escapeBody>
========== Changed: added timeZone support for Date
<fmt:timeZone value="${timeZone}">
<fmt:formatDate value="${object[field]}" pattern="${fn:escapeXml(dateTimePattern)}" timeZone="${timeZone}" />
</fmt:timeZone>
========== End
</spring:escapeBody>
</c:when>
<c:when test="${calendar}">
<spring:escapeBody>
========== Changed: added timeZone support for Calendar
<fmt:timeZone value="${timeZone}">
<fmt:formatDate value="${object[field].time}" pattern="${fn:escapeXml(dateTimePattern)}" timeZone="${timeZone}" />
</fmt:timeZone>
========== End
</spring:escapeBody>
</c:when>
<c:otherwise>
<spring:eval expression="object[field]" />
</c:otherwise>
</c:choose>
</div>
</div>
<br />
</c:if>
</jsp:root>
When adding / changing these few lines, all the old code will continue to work.
You will have to apply these changes also to the WEB-INF/tags/form/fields/column.tagx file.
I you use gvNIX JQuery the same changes should be applied there also.
This is all the change you have to do!!!!
To add timezone support in all your show.jspx files:
1) add the extra timezone option for any date.
old:
<field:display date="true" dateTimePattern="${fileUpload_uploaddate_date_format}" field="uploadDate" id="s_com_myproject_onlineviewer_domain_FileUpload_uploadDate" object="${fileupload}" z="user-managed"/>
new:
<field:display date="true" dateTimePattern="${fileUpload_uploaddate_date_format}" field="uploadDate" id="s_com_myproject_onlineviewer_domain_FileUpload_uploadDate" object="${fileupload}" timeZone="${fileUpload_uploaddate_date_timezone}" z="user-managed"/>
2) In your controller specify your timeZone like:
uiModel.addAttribute("fileUpload_uploaddate_date_timezone", "Europe/Amsterdam");
In the spirit of Spring Roo's dataformat addDateTimeFormatPatterns(uiModel); I added addTimeZone(uiModel); .
In this method you can specify the source of the timezone.
In my web application I ask the user to specify his/her timezone when they reigster. All other workaround fail somewhere.
void addTimeZone(Model uiModel) {
uiModel.addAttribute("fileUpload_uploaddate_date_timezone", UserUtils.geTimeZone());
}
BTW, an addTimeZone default method in the AspectJ controller could be as the sample below, leaving the programmer to be able to push in and alter it.
void FileUploadController.addTimeZone(Model uiModel) {
uiModel.addAttribute("fileUpload_uploaddate_date_timezone", TimeZone.getDefault().getID());
}
I have defined a Spring application context xml which will be edited by end users to add new beans.Something like:
<bean name="myBeanName1" class="com.xxx.Yyy">
<property name="type" value="type1" />
<property name="name" value="name1" />
<property name="arguments" value="arg1" />
</bean>
<bean name="myBeanName2" class="com.xxx.Yyy">
<property name="type" value="type2" />
<property name="name" value="name2" />
<property name="arguments" value="arg2" />
</bean>
.
.
.
Now I am asked to change this to a normal xml so that users wont be bothered by bean property and class names:
<def name="Name1">
<type>type1</type>
<argument>arg1</argument
</def>
<def name="Name2">
<type>type2</type>
<argument>arg2</argument
</def>
As my code is using the bean, how can I use the new xml with minimal code change so that it is converted to a bean definition as earlier and things work as before?.
I dont know if Spring has a solution for this out of the box. What I thought was applying stylesheet to the new xml to create my older bean. Any other better/elegant solution for this?
Edit: Now that user input is not inside the bean anymore, is it possible to use the new xml to inject to a #Component class?
Spring supports creating custom tags. You need to create xsd schema, NamespaceHandlerm, implement BeanDefinitionParsers and make spring aware of these by creating spring.handlers & spring.schemas special files.
Have a look at Extensible XML authoring
Example:
<beans xmlns declaration goes here>
<yournamespace:yourcustomtag id="some id">
<yournamespace:some_other_tag your-custom-attribute="some value" />
</yournamespace:yourcustomtag>
</beans>
I'm using Tapestry 4.
I have several TextFields whose values get passed into Strings in the page class, and they work great as long as there is some content in the fields. Most of them are optional, so I believe I can use the StringTranslator with empty= in that case, but for a couple of fields for which a value is required, I'm having a hard time getting validation to work.
I expected a simple required validator to work:
<component id="myRequiredField" type="TextField">
<binding name="value" value="ognl:stringValue" />
<binding name="validators" value="validators:required" />
</component>
Failing that, I expected minLength to work:
<component id="myRequiredField" type="TextField">
<binding name="value" value="ognl:stringValue" />
<binding name="validators" value="validators:required,minLength=1" />
</component>
Both attempts at validation allow the value as retrieved with getStringValue() to be null upon form submission. My Form and Submit components look like:
<component id="myUpdateForm" type="Form">
<binding name="delegate" value="beans.validationDelegate" />
</component>
<component id="submitUpdate" type="Submit">
<binding name="action" value="listener:doUpdate" />
</component>
It turns out that the validation was working, but I wasn't checking whether my validation delegate had errors before operating on the incoming data. The following seems to be the correct approach to take in any listener that depends on validation, given the setup as listed in the question:
#Bean
public abstract ValidationDelegate getValidationDelegate();
public void doUpdate() {
if (!getValidationDelegate().getHasErrors()) {
// business logic
}
}