Date format error in .page.xml params: a Seam issue?
jkronegg Sep 3, 2009 10:32 PMIn this post, I present my experiments on java.util.Date passed as parameters in the .page.xml's <param> tag. Please let me know if it worth a JIRA issue. I'm using Seam 2.1.2.GA, RichFaces 3.3.0, JBoss 4.2.2 and its default JSF RI implementation.
What I would like to have is two rich:calendar with different date formats in search.xhtml :
... <rich:calendar id="dateNaisDebut" datePattern="ddMMyyyy" value="#{personneExtendedList.dateNaissanceDebut}" enableManualInput="true"/> <rich:calendar id="dateNaisFin" datePattern="dd.MM.yyyy" value="#{personneExtendedList.dateNaissanceFin}" enableManualInput="true"/> ...
These two dates are passed by GET parameters as specified in my search.page.xml, without constraining the date format using a custom converter :
... <param name="dateNaisDebut" value="#{personneExtendedList.dateNaissanceDebut}"/> <param name="dateNaisFin" value="#{personneExtendedList.dateNaissanceFin}"/> ...
The problem is that I ran into JSF messages telling that my date format is incorrect (message key is javax.faces.converter.DateTimeConverter.DATE).
I added some trace in org.jboss.seam.faces.DateConverter in order to obtain more details about the DateFormat used for conversion and added some HTTP request logging. I explain below what's going on in the log files (I set the first date to january first 1975 and the second date to december 31 2000):
20:48:57,036 INFO [HttpRequestDebugFilter] request: method=POST, URL=/registreEPG/PersonneExtendedList.seam 20:48:57,036 INFO [HttpRequestDebugFilter] contentType=application/x-www-form-urlencoded, characterEncoding=null) 20:48:57,036 INFO [HttpRequestDebugFilter] header: 20:48:57,036 INFO [HttpRequestDebugFilter] host = localhost:8080 20:48:57,036 INFO [HttpRequestDebugFilter] user-agent = Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.3pre) Gecko/20090816 SeaMonkey/2.0b2pre ... more header fields 20:48:57,036 INFO [HttpRequestDebugFilter] parameters: 20:48:57,036 INFO [HttpRequestDebugFilter] javax.faces.ViewState = [j_id6] 20:48:57,036 INFO [HttpRequestDebugFilter] personneExtendedSearch2 = [personneExtendedSearch2] 20:48:57,036 INFO [HttpRequestDebugFilter] personneExtendedSearch2:dateNaisField:dateNaisDebutInputCurrentDate = [09/2009] 20:48:57,036 INFO [HttpRequestDebugFilter] personneExtendedSearch2:dateNaisField:dateNaisFinInputCurrentDate = [09/2009] First rich:calendar field with a format ddMMyyyy, submitted as String in a POST parameter 20:48:57,036 INFO [HttpRequestDebugFilter] personneExtendedSearch2:dateNaisField:dateNaisDebutInputDate = [01011975] Second rich:calendar field with a format dd.MM.yyyy, submitted as a String in a POST parameter 20:48:57,036 INFO [HttpRequestDebugFilter] personneExtendedSearch2:dateNaisField:dateNaisFinInputDate = [31.12.2000] 20:48:57,036 INFO [HttpRequestDebugFilter] personneExtendedSearch2:dateNaisField:j_id170 = [] ... more POST parameters fields 20:48:57,630 TRACE [SeamPhaseListener] before phase: RESTORE_VIEW 1 20:48:57,630 DEBUG [SeamPhaseListener] beginning transaction prior to phase: RESTORE_VIEW 1 20:48:57,630 DEBUG [UTTransaction] beginning JTA transaction 20:48:57,630 TRACE [SeamPhaseListener] after phase: RESTORE_VIEW 1 20:48:57,630 DEBUG [Manager] No stored conversation 20:48:57,630 DEBUG [ManagedPersistenceContext] created seam managed persistence context from EntityManagerFactory 20:48:57,661 INFO [PersonneExtendedList] setDateNaissanceDebutStr : 20:48:57,661 TRACE [SeamPhaseListener] before phase: APPLY_REQUEST_VALUES 2 20:48:57,661 TRACE [SeamPhaseListener] after phase: APPLY_REQUEST_VALUES 2 20:48:57,661 TRACE [SeamPhaseListener] before phase: PROCESS_VALIDATIONS 3 First POST parameter date converted from String to Date using the format defined in the first rich:calendar (ddMMyyyy) 20:48:57,661 DEBUG [DateConverter] Converting string '01011975' to date for clientId 'personneExtendedSearch2:dateNaisField:dateNaisDebut' using Seam's built-in JSF date converter 20:48:57,661 DEBUG [DateConverter] org.jboss.seam.faces.DateConverter@10c2a7a, locale = fr, pattern = ddMMyyyy Second POST parameter date converted from String to Date using the format defined in the second rich:calendar (dd.MM.yyyy). Notice that the same converter is used as the pseudo address is the same 20:48:57,677 DEBUG [DateConverter] Converting string '31.12.2000' to date for clientId 'personneExtendedSearch2:dateNaisField:dateNaisFin' using Seam's built-in JSF date converter 20:48:57,677 DEBUG [DateConverter] org.jboss.seam.faces.DateConverter@10c2a7a, locale = fr, pattern = dd.MM.yyyy 20:48:57,677 TRACE [SeamPhaseListener] after phase: PROCESS_VALIDATIONS 3 20:48:57,677 TRACE [SeamPhaseListener] before phase: UPDATE_MODEL_VALUES 4 20:48:57,677 INFO [PersonneExtendedList] setDateNaissanceDebutStr : 20:48:57,677 INFO [PersonneExtendedList] setDateNaissanceDebut : Wed Jan 01 00:00:00 CET 1975 20:48:57,677 TRACE [SeamPhaseListener] after phase: UPDATE_MODEL_VALUES 4 20:48:57,677 TRACE [SeamPhaseListener] before phase: INVOKE_APPLICATION 5 Converting the first Date to String for the <param> in the .page.xml file. Notice that the converter is the same as previously and the date pattern is the last used (i.e. dd.MM.yyyy) 20:48:57,693 DEBUG [DateConverter] Converting date 'Wed Jan 01 00:00:00 CET 1975' to string for clientId '_viewRoot' using Seam's built-in JSF date converter 20:48:57,693 DEBUG [DateConverter] org.jboss.seam.faces.DateConverter@10c2a7a, locale = fr, pattern = dd.MM.yyyy Converting the second Date to String for the <param> in the .page.xml file. Notice that the converter is the same as previously and the date pattern is the last used (i.e. dd.MM.yyyy) 20:48:57,693 DEBUG [DateConverter] Converting date 'Sun Dec 31 00:00:00 CET 2000' to string for clientId '_viewRoot' using Seam's built-in JSF date converter 20:48:57,693 DEBUG [DateConverter] org.jboss.seam.faces.DateConverter@10c2a7a, locale = fr, pattern = dd.MM.yyyy Redirecting to the GET request using the Date as String parameters (were both converted using the dd.MM.yyyy pattern, see above) 20:48:57,693 DEBUG [FacesManager] redirecting to: /registreEPG/PersonneExtendedList.seam?prenom=&dateNaisFin=31.12.2000&dateNaisDebutStr=&dateNaisDebut=01.01.1975&prenom2=&nomJfille=&nom=&logic=and&cid=7 20:48:57,693 TRACE [SeamPhaseListener] after phase: INVOKE_APPLICATION 5 20:48:57,693 DEBUG [SeamPhaseListener] committing transaction after phase: INVOKE_APPLICATION 5 20:48:57,693 DEBUG [UTTransaction] committing JTA transaction 20:48:57,693 DEBUG [Manager] Storing conversation state: 7 20:48:57,708 INFO [HttpRequestDebugFilter] request: method=GET, URL=/registreEPG/PersonneExtendedList.seam 20:48:57,708 INFO [HttpRequestDebugFilter] contentType=null, characterEncoding=null) 20:48:57,708 INFO [HttpRequestDebugFilter] header: 20:48:57,708 INFO [HttpRequestDebugFilter] host = localhost:8080 20:48:57,708 INFO [HttpRequestDebugFilter] user-agent = Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.3pre) Gecko/20090816 SeaMonkey/2.0b2pre ... more GET header fields 20:48:57,708 INFO [HttpRequestDebugFilter] parameters: 20:48:57,708 INFO [HttpRequestDebugFilter] cid = [7] The query parameters confirm that both dates are passed in the GET request parameters as String with the dd.MM.yyyy format 20:48:57,708 INFO [HttpRequestDebugFilter] dateNaisDebut = [01.01.1975] 20:48:57,708 INFO [HttpRequestDebugFilter] dateNaisFin = [31.12.2000] ... more GET parameters fields 20:48:58,208 TRACE [SeamPhaseListener] before phase: RESTORE_VIEW 1 20:48:58,224 DEBUG [SeamPhaseListener] beginning transaction prior to phase: RESTORE_VIEW 1 20:48:58,224 DEBUG [UTTransaction] beginning JTA transaction 20:48:58,224 TRACE [SeamPhaseListener] after phase: RESTORE_VIEW 1 20:48:58,224 TRACE [ConversationPropagation] Found conversation id in request parameter: 7 20:48:58,224 DEBUG [Manager] Restoring conversation with id: 7 The first date is converted to be put in the value of the first rich:calendar. Now, the DateConverter instance has changed and the format has been defaulted to the default short format for locale 'fr' (french): dd/MM/yyyy 20:48:58,224 DEBUG [DateConverter] Converting string '01.01.1975' to date for clientId '_viewRoot' using Seam's built-in JSF date converter 20:48:58,224 DEBUG [DateConverter] org.jboss.seam.faces.DateConverter@191d67b, locale = fr, pattern = dd/MM/yyyy 20:48:58,224 DEBUG [ResourceLoader] resource bundle missing: PersonneExtendedList 20:48:58,224 DEBUG [ResourceLoader] resource bundle missing: PersonneExtendedList The second date is converted to be put in the value of the first rich:calendar. The converter used is the same as for the first date and the format has not changed (still dd/MM/yyyy) 20:48:58,224 DEBUG [DateConverter] Converting string '31.12.2000' to date for clientId '_viewRoot' using Seam's built-in JSF date converter 20:48:58,224 DEBUG [DateConverter] org.jboss.seam.faces.DateConverter@191d67b, locale = fr, pattern = dd/MM/yyyy 20:48:58,224 DEBUG [SeamPhaseListener] committing transaction after phase: RESTORE_VIEW 1 20:48:58,224 DEBUG [UTTransaction] committing JTA transaction 20:48:58,224 TRACE [SeamPhaseListener] before phase: RENDER_RESPONSE 6 20:48:58,224 DEBUG [SeamPhaseListener] beginning transaction prior to phase: RENDER_RESPONSE 6 20:48:58,224 DEBUG [UTTransaction] beginning JTA transaction 20:48:58,458 TRACE [SeamPhaseListener] after phase: RENDER_RESPONSE 6 20:48:58,458 DEBUG [SeamPhaseListener] committing transaction after phase: RENDER_RESPONSE 6 20:48:58,458 DEBUG [UTTransaction] committing JTA transaction 20:48:58,458 DEBUG [Manager] Discarding conversation state: 7 20:48:58,458 DEBUG [ManagedPersistenceContext] destroying seam managed persistence context for persistence unit: java:/entityManager
So to summarize, the java.util.Date passed by <param> tags in the .page.xml file are converted from Date to String for the GET request, using the date format defined in the last used rich:calendar. Then, the GET parameters are converted back from String to Date using the default date format which may not be the same as the one defined in the rich:calendar.
IMHO, the org.jboss.seam.navigation.Param class, which underlies the <param> tag, should use its own Date converter in order to be independent from the configuration changes in the org.jboss.seam.faces.DateConverter. I think it makes sense to provide a date converter which is specific to the technical stuff
of passing dates in GET request parameters.
Of course, I can create my own converter and add it to every <param> tag by means of the 'converterId' property, but this is typically something I expect that Seam is doing for me. Otherwise, it can take hours to track the problem, which makes me think about a JIRA issue.
For me, the solution would be to:
- define a org.jboss.seam.faces.DateParamConverter date converter with a selectable date format defaulted to
yyyyMMddHHmmssSSS
- change the org.jboss.seam.navigation.Param class to use a the DateParamConverter converter if the param value is java.util.Date, else, use the converters registered in JSF
What do you think about that and do you think it worth a JIRA issue?
Thanks