I haven't been able to figure out how to display a java.time.LocalDate value in a JSP.
In my JSP, I have this:
<fmt:formatDate value="${std.datum}" type="date" pattern="dd.MM.yyyy" var="stdDatum" />
The std.datum is of type java.time.LocalDate. When rendering the JSP I get this exception:
javax.el.ELException:
Cannot convert 2015-02-14 of type class
java.time.LocalDate to class java.util.Date
I'm assuming it's the conversion?
So is it possible to format an instance of LocalDate class with <fmr:formatDate> action?
I'm assuming it's the conversion?
Yes, it's a conversion related exception.
Solution
You could first use the <fmt:parseDate> action from the JSTL's "I18n capable formatting tag library" to do the conversion and then do the formatting with the <fmt:formatDate> action.
Here is an example:
<fmt:parseDate value="${std.datum}" type="date" pattern="yyyy-MM-dd" var="parsedDate" />
<fmt:formatDate value="${parsedDate}" type="date" pattern="dd.MM.yyyy" var="stdDatum" />
This solution is also presented right in the "JavaServer Pages™ Standard Tag Library (JSTL)" specification version 1.2 (see page 109).
This is an old question, but i find it is very best to do a custom tld in this case: without any double conversion to and from String.
Do your own tld file, then override the FormatDate class. Finally, declare your own custom prefix and use custom:formatDate instead of fmt:formatDate.
here is a simplified version
usage in JSP:
<%# taglib uri="/WEB-INF/custom" prefix="custom" %>
...
<custom:formatDate value="${std.datum}" pattern="dd/MM/yyyy" />
WEB-INF/custom.tld file
<?xml version="1.0" encoding="UTF-8"?>
<tag ib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd">
<tag>
<description>
FormatDate with java8 type
</description>
<name>formatDate</name>
<tag-class>com.custom.tag.FormatDateTag</tag-class>
<body-content>empty</body-content>
<attribute>
<description>
Date and/or time to be formatted.
</description>
<name>value</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<description>
Custom formatting style for dates and times.
</description>
<name>pattern</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
Then the java class tag file
public class FormatDateTag extends TagSupport {
protected Temporal value;
protected String pattern;
private String var;
private int scope;
public FormatDateTag()
{
super ();
init ();
}
private void init()
{
this.pattern = this.var = null;
this.value = null;
this.scope = PageContext.PAGE_SCOPE;
}
public void setVar(final String var)
{
this.var = var;
}
public void setScope(final String scope)
{
this.scope = Util.getScope (scope);
}
public void setValue(final Temporal value)
{
this.value = value;
}
public void setPattern(final String pattern)
{
this.pattern = pattern;
}
#Override
public int doEndTag() throws JspException
{
String formatted = null;
if (this.value == null)
{
if (this.var != null)
{
this.pageContext.removeAttribute (this.var, this.scope);
}
return EVAL_PAGE;
}
// Create formatter
if (this.pattern != null)
{
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern (this.pattern);
formatted = formatter.format (this.value);
}
else
{
// no formatting locale available, use Date.toString()
formatted = this.value.toString ();
}
if (this.var != null)
{
this.pageContext.setAttribute (this.var, formatted, this.scope);
}
else
{
try
{
this.pageContext.getOut ().print (formatted);
}
catch (final IOException ioe)
{
throw new JspTagException (ioe.toString (), ioe);
}
}
return EVAL_PAGE;
}
#Override
public void release()
{
init ();
}
}
I wanted to avoid changing all the places where <fmt:formatDate/> where used, so I created the following two classes in stead:
First, a converter to convert (some of) the java.time classes. It checks that java.util.Date is the target type, if not, it does nothing. It supports source time as java.util.Date (including java.sql.Timestamp and java.sql.Date), LocalDate, LocalDateTime, ZonedDateTime, Instant or Long (time in millis).
package com.example.elresolvers;
import javax.el.ELContext;
import javax.el.TypeConverter;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
#SuppressWarnings("UseOfObsoleteDateTimeApi")
public class DateFromJavaTimeResolver extends TypeConverter {
#Override
public Object convertToType(ELContext context, Object obj, Class<?> type) {
Date date = null;
if (Date.class.isAssignableFrom(type)) {
if (obj instanceof Date) {
date = (Date) obj;
} else {
ZonedDateTime zdt = null;
if (obj instanceof LocalDate) {
zdt = ((LocalDate) obj).atStartOfDay(ZoneId.systemDefault());
} else if (obj instanceof LocalDateTime) {
zdt = ((LocalDateTime) obj).atZone(ZoneId.systemDefault());
} else if (obj instanceof ZonedDateTime) {
zdt = (ZonedDateTime) obj;
} else if (obj instanceof Instant) {
date = Date.from((Instant) obj);
} else if (obj instanceof Long) {
date = new Date((Long) obj);
}
if (zdt != null) {
date = Date.from(zdt.toInstant());
}
}
context.setPropertyResolved(date != null);
}
return date;
}
}
Next, a ServletContextListener class to register the converter for use with JSP:
package com.example.web;
import com.example.elresolvers.DateFromJavaTimeResolver;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.jsp.JspApplicationContext;
import javax.servlet.jsp.JspFactory;
public class JspElResolverInitListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext servletContext = sce.getServletContext();
JspApplicationContext context = JspFactory.getDefaultFactory().getJspApplicationContext(servletContext);
context.addELResolver(new DateFromJavaTimeResolver());
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
Finally, an entry in web.xml (if you are not using annotations or other means):
<listener>
<listener-class>com.example.web.JspElResolverInitListener</listener-class>
</listener>
Java:
public class DateTimeUtil {
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd.MM.yyyy");
public static String toString(LocalDateTime ldt) {
return ldt.format(DATE_FORMATTER);
}
JSP:
<%# page import="ru.javaops.topjava.util.DateTimeUtil" %>
...
<%=DateTimeUtil.toString(std.getDatum())%>
Related
My problem relates to the following class:
public class MyClass {
private LocalDateTime startDate;
}
I am trying to setup the startDate property of this bean using Spring XML configuration:
<property name="startDate">
<value>2000-01-01</value>
</property>
I get an error:
Cannot convert value of type [java.lang.String] to required type [java.time.LocalDateTime] for property 'startDate'
Is it possible to use Spring to do this conversion? I found examples on the net how to do that for Date object, however, LocalDateTime doesn't have a constructor taking a string (and the solution seems to need such constructor). LocalDateTime is constructed by using the static method LocalDateTime.parse.
Using the annotations #DateTimeFormat, like:
public class MyClass {
#DateTimeFormat(iso=ISO.LOCAL_DATE_TIME)
private LocalDateTime startDate;
}
is not a solution, since MyClass has to be available outside Spring.
Thanks in advance
you can register your conversion. like the following code, the following will convert a string to LocalDateTime
class CustomLocalDateTimeEditor extends PropertyEditorSupport {
private final boolean allowEmpty;
private final int exactDateLength;
public CustomLocalDateTimeEditor( boolean allowEmpty) {
this.allowEmpty = allowEmpty;
this.exactDateLength = -1;
}
public CustomLocalDateTimeEditor(boolean allowEmpty, int exactDateLength) {
this.allowEmpty = allowEmpty;
this.exactDateLength = exactDateLength;
}
#Override
public void setAsText(String text) throws IllegalArgumentException {
if (this.allowEmpty && !StringUtils.hasText(text)) {
setValue(null);
}
else if (text != null && this.exactDateLength >= 0 && text.length() != this.exactDateLength) {
throw new IllegalArgumentException("Could not parse date: it is not exactly" + this.exactDateLength + "characters long");
}
else {
try {
setValue(LocalDateTime.parse(text));
}
catch (DateTimeParseException ex) {
throw new IllegalArgumentException("Could not parse date: " + ex.getMessage(), ex);
}
}
}
#Override
public String getAsText() {
LocalDateTime value = LocalDateTime.parse(String.valueOf(getValue()));
return (value != null ? value.toString() : "");
}
}
Here is what I ended up with based on Javy's comment:
import java.beans.PropertyEditorSupport;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class CustomLocalDateTimeEditor extends PropertyEditorSupport {
public CustomLocalDateTimeEditor() {
}
private LocalDateTime parseText(String text) {
LocalDateTime ldt;
try {
ldt = LocalDateTime.parse(text);
} catch(Exception ee) {
ldt = null;
}
if(ldt == null) {
try {
ldt = LocalDateTime.of(LocalDate.parse(text), LocalTime.of(0, 0));
} catch(Exception ee) {
ldt = null;
}
}
return ldt;
}
#Override
public void setAsText(String text) throws IllegalArgumentException {
setValue(parseText(text));
}
#Override
public String getAsText() {
LocalDateTime value = parseText(String.valueOf(getValue()));
return (value != null ? value.toString() : "");
}
}
And in the XML I have the following:
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.time.LocalDateTime" value="com.mycompany.CustomLocalDateTimeEditor" />
</map>
</property>
</bean>
<bean id="myClass" class="MyClass">
<property name="startDate">
<value>2000-01-01</value>
</property>
</bean>
You can use #DateTimeFormat annotation and provide a pattern. For example
#DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDateTime startDate;
When Spring find the Joda localdatetime, it will convert date in appropriate format.
#DateTimeFormat in spring
Declare a dateFormat bean, in “MyClass” bean, reference “dateFormat” bean as a factory bean. The factory method will call SimpleDateFormat.parse() to convert String into Date object automatically.
reference:
http://www.mkyong.com/spring/spring-how-to-pass-a-date-into-bean-property-customdateeditor/
I haven't been able to figure out how to display a java.time.LocalDate value in a JSP.
In my JSP, I have this:
<fmt:formatDate value="${std.datum}" type="date" pattern="dd.MM.yyyy" var="stdDatum" />
The std.datum is of type java.time.LocalDate. When rendering the JSP I get this exception:
javax.el.ELException:
Cannot convert 2015-02-14 of type class
java.time.LocalDate to class java.util.Date
I'm assuming it's the conversion?
So is it possible to format an instance of LocalDate class with <fmr:formatDate> action?
I'm assuming it's the conversion?
Yes, it's a conversion related exception.
Solution
You could first use the <fmt:parseDate> action from the JSTL's "I18n capable formatting tag library" to do the conversion and then do the formatting with the <fmt:formatDate> action.
Here is an example:
<fmt:parseDate value="${std.datum}" type="date" pattern="yyyy-MM-dd" var="parsedDate" />
<fmt:formatDate value="${parsedDate}" type="date" pattern="dd.MM.yyyy" var="stdDatum" />
This solution is also presented right in the "JavaServer Pages™ Standard Tag Library (JSTL)" specification version 1.2 (see page 109).
This is an old question, but i find it is very best to do a custom tld in this case: without any double conversion to and from String.
Do your own tld file, then override the FormatDate class. Finally, declare your own custom prefix and use custom:formatDate instead of fmt:formatDate.
here is a simplified version
usage in JSP:
<%# taglib uri="/WEB-INF/custom" prefix="custom" %>
...
<custom:formatDate value="${std.datum}" pattern="dd/MM/yyyy" />
WEB-INF/custom.tld file
<?xml version="1.0" encoding="UTF-8"?>
<tag ib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd">
<tag>
<description>
FormatDate with java8 type
</description>
<name>formatDate</name>
<tag-class>com.custom.tag.FormatDateTag</tag-class>
<body-content>empty</body-content>
<attribute>
<description>
Date and/or time to be formatted.
</description>
<name>value</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<description>
Custom formatting style for dates and times.
</description>
<name>pattern</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
Then the java class tag file
public class FormatDateTag extends TagSupport {
protected Temporal value;
protected String pattern;
private String var;
private int scope;
public FormatDateTag()
{
super ();
init ();
}
private void init()
{
this.pattern = this.var = null;
this.value = null;
this.scope = PageContext.PAGE_SCOPE;
}
public void setVar(final String var)
{
this.var = var;
}
public void setScope(final String scope)
{
this.scope = Util.getScope (scope);
}
public void setValue(final Temporal value)
{
this.value = value;
}
public void setPattern(final String pattern)
{
this.pattern = pattern;
}
#Override
public int doEndTag() throws JspException
{
String formatted = null;
if (this.value == null)
{
if (this.var != null)
{
this.pageContext.removeAttribute (this.var, this.scope);
}
return EVAL_PAGE;
}
// Create formatter
if (this.pattern != null)
{
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern (this.pattern);
formatted = formatter.format (this.value);
}
else
{
// no formatting locale available, use Date.toString()
formatted = this.value.toString ();
}
if (this.var != null)
{
this.pageContext.setAttribute (this.var, formatted, this.scope);
}
else
{
try
{
this.pageContext.getOut ().print (formatted);
}
catch (final IOException ioe)
{
throw new JspTagException (ioe.toString (), ioe);
}
}
return EVAL_PAGE;
}
#Override
public void release()
{
init ();
}
}
I wanted to avoid changing all the places where <fmt:formatDate/> where used, so I created the following two classes in stead:
First, a converter to convert (some of) the java.time classes. It checks that java.util.Date is the target type, if not, it does nothing. It supports source time as java.util.Date (including java.sql.Timestamp and java.sql.Date), LocalDate, LocalDateTime, ZonedDateTime, Instant or Long (time in millis).
package com.example.elresolvers;
import javax.el.ELContext;
import javax.el.TypeConverter;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
#SuppressWarnings("UseOfObsoleteDateTimeApi")
public class DateFromJavaTimeResolver extends TypeConverter {
#Override
public Object convertToType(ELContext context, Object obj, Class<?> type) {
Date date = null;
if (Date.class.isAssignableFrom(type)) {
if (obj instanceof Date) {
date = (Date) obj;
} else {
ZonedDateTime zdt = null;
if (obj instanceof LocalDate) {
zdt = ((LocalDate) obj).atStartOfDay(ZoneId.systemDefault());
} else if (obj instanceof LocalDateTime) {
zdt = ((LocalDateTime) obj).atZone(ZoneId.systemDefault());
} else if (obj instanceof ZonedDateTime) {
zdt = (ZonedDateTime) obj;
} else if (obj instanceof Instant) {
date = Date.from((Instant) obj);
} else if (obj instanceof Long) {
date = new Date((Long) obj);
}
if (zdt != null) {
date = Date.from(zdt.toInstant());
}
}
context.setPropertyResolved(date != null);
}
return date;
}
}
Next, a ServletContextListener class to register the converter for use with JSP:
package com.example.web;
import com.example.elresolvers.DateFromJavaTimeResolver;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.jsp.JspApplicationContext;
import javax.servlet.jsp.JspFactory;
public class JspElResolverInitListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext servletContext = sce.getServletContext();
JspApplicationContext context = JspFactory.getDefaultFactory().getJspApplicationContext(servletContext);
context.addELResolver(new DateFromJavaTimeResolver());
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
Finally, an entry in web.xml (if you are not using annotations or other means):
<listener>
<listener-class>com.example.web.JspElResolverInitListener</listener-class>
</listener>
Java:
public class DateTimeUtil {
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd.MM.yyyy");
public static String toString(LocalDateTime ldt) {
return ldt.format(DATE_FORMATTER);
}
JSP:
<%# page import="ru.javaops.topjava.util.DateTimeUtil" %>
...
<%=DateTimeUtil.toString(std.getDatum())%>
Im using rome 1.0 to generate RSS for my java application.
In my java:
SyndFeed feed = new SyndFeedImpl();
feed.setFeedType( "rss_2.0" );
feed.setTitle( "My Site" );
feed.setLink( "http://example.com" );
feed.setDescription( "Test Site." );
List<SyndEntry> entries = new ArrayList<SyndEntry>();
SyndEntry entry = null;
SyndContent description = null;
entry = new SyndEntryImpl();
entry.setTitle( "Entry1" );
entry.setLink( "http://example.com/entry1" );
entry.setPublishedDate( new Date() );
description = new SyndContentImpl();
description.setType("text/html");
description.setValue( "This is the content of entry 1." );
entry.setDescription( description );
entries.add( entry );
feed.setEntries(entries);
Writer writer = new FileWriter("/home/jr/Desktop/stream.xml");
SyndFeedOutput output = new SyndFeedOutput();
output.output(feed,writer);
writer.close();
The generated RSS:
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
<channel>
<title>My Site</title>
<link>http://example.com</link>
<description>Test Site.</description>
<item>
<title>Entry1</title>
<link>http://example.com/entry1</link>
<description>This is the content of entry 1.</description>
<pubDate>Fri, 09 Nov 2012 01:28:57 GMT</pubDate>
<guid>http://example.com/entry1</guid>
<dc:date>2012-11-09T01:28:57Z</dc:date>
</item>
</channel>
</rss>
When RSS is validated here, it has the following recommendations:
An item should not include both pubDate and dc:date
Missing atom:link with rel="self"
How to do the recommendation in rome library? Is the generated RSS ok?
Thanks.
In your custom SyndFeed class, make sure that you name your Date variable differently from what's on the SyndFeed class (Ie: instead of 'publishedDate', use something like 'pubDate'. This seems to have solved the issue for me.
public class CustomSyndFeed extends SyndFeedImpl {
protected Date pubDate;
#Override
public Date getPublishedDate() {
return pubDate;
}
#Override
public void setPublishedDate(final Date pubDate) {
this.pubDate = new Date(pubDate.getTime());
}
}
So this is happening because the SyndFeedImpl uses the same field for the date and publishedDate fields (from the DC Module) :
#Override
public Date getPublishedDate() {
return getDCModule().getDate();
}
#Override
public void setPublishedDate(final Date publishedDate) {
getDCModule().setDate(publishedDate);
}
Since the RSS093Generator (used by the RSS20Generator) creates a pubDate element from the specified item, but also inherits from the DCModuleGenerator, you get both this:
final Date pubDate = item.getPubDate();
if (pubDate != null) {
eItem.addContent(generateSimpleElement("pubDate", DateParser.formatRFC822(pubDate, Locale.US)));
}
and this:
final Date dcDate = dcModule.getDate();
if (dcDate != null) {
for (final Date date : dcModule.getDates()) {
element.addContent(generateSimpleElement("date", DateParser.formatW3CDateTime(date, Locale.US)));
}
}
This interaction can be prevented by implementing a custom SyndFeed of your own. In this case, all you need to do is create a class variable to store your pubDate so that the DCModule never gets a date set, and will therefore never generate your unwanted dc:date element.
I ran into the exact same problem and solved it by using this SyndFeed implementation:
public class CustomSyndFeed extends SyndFeedImpl {
protected Date publishedDate;
#Override
public Date getPublishedDate() {
return publishedDate;
}
#Override
public void setPublishedDate(final Date publishedDate) {
this.publishedDate = new Date(publishedDate.getTime());
}
}
Little late to the party, but no answer here works out of the box, so I figured I'd add mine.
As #Vitor points out in his comment, the correct way of doing this to extend SyndEntryImpl and use it as SyndEntry entry = new CustomEntryImpl();.
public class CustomEntryImpl extends SyndEntryImpl {
protected Date pubDate;
#Override
public Date getPublishedDate() {
return pubDate;
}
#Override
public void setPublishedDate(final Date pubDate) {
this.pubDate = new Date(pubDate.getTime());
}
}
I am using TomCat 5.5 with MyFaces 1.1 and am trying to implement a custom regex validation tag.
My RegExValidator class looks like this:
public class RegExValidator implements Validator, StateHolder {
private String regex;
private boolean transientValue = false;
public RegExValidator() {
super();
}
public RegExValidator(String regex) {
this();
this.regex = regex;
}
public void validate(FacesContext context, UIComponent component, Object toValidate) throws ValidatorException {
if ((context == null) || (component == null)) {
throw new NullPointerException();
}
if (!(component instanceof UIInput)) {
return;
}
if (null == regex || null == toValidate) {
return;
}
String val = (String) toValidate;
if (!val.matches(regex)) {
FacesMessage errMsg = MessageFactory.createFacesMessage(context, Constants.FORMAT_INVALID_MESSAGE_ID, FacesMessage.SEVERITY_ERROR, (new Object[]{regex}));
throw new ValidatorException(errMsg);
}
}
public Object saveState(FacesContext context) {
Object[] values = new Object[1];
values[0] = regex;
return (values);
}
public void restoreState(FacesContext context, Object state) {
Object[] values = (Object[]) state;
regex = (String) values[0];
}
public String getRegex() {
return regex;
}
public void setRegex(String regex) {
this.regex = regex;
}
public boolean isTransient() {
return transientValue;
}
public void setTransient(boolean transientValue) {
this.transientValue = transientValue;
}
}
My RegExValidatorTag class looks like this:
#SuppressWarnings("serial")
public class RegExValidatorTag extends ValidatorELTag {
private static String validatorID = null;
protected ValueExpression regex = null;
public RegExValidatorTag() {
super();
if (validatorID == null) {
validatorID = "RegExValidator";
}
}
public Validator createValidator() throws JspException {
FacesContext facesContext = FacesContext.getCurrentInstance();
RegExValidator result = null;
if (validatorID != null) {
result = (RegExValidator) facesContext.getApplication().createValidator(validatorID);
}
String patterns = null;
if (regex != null) {
if (!regex.isLiteralText()) {
patterns = (String) regex.getValue(facesContext.getELContext());
} else {
patterns = regex.getExpressionString();
}
}
result.setRegex(patterns);
return result;
}
public void setValidatorID(String validatorID) {
RegExValidatorTag.validatorID = validatorID;
}
/**
* #param regex
* the regex to set
*/
public void setRegex(ValueExpression regex) {
this.regex = regex;
}
}
My Taglibrary Descriptor looks like this:
<tag>
<name>regexValidator</name>
<tag-class>com.company.components.taglib.RegExValidatorTag</tag-class>
<attribute>
<name>regex</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
My face-common-config.xml has a Validator tag like this:
<validator>
<description>
Validate an input string value against a regular
expression specified by the "regex" attribute.
</description>
<validator-id>RegExValidator</validator-id>
<validator-class>com.company.components.validators.RegExValidator</validator-class>
<attribute>
<description>
The regular expression to test the value against
</description>
<attribute-name>regex</attribute-name>
<attribute-class>java.lang.String</attribute-class>
</attribute>
</validator>
And later on it is supposed to be used in a jsp file like this:
<tc:in value="${dataBean.currentBean.field}">
<a:regexValidator regex="${dataBean.currentBean.validationRegEx}" />
</tc:in>
When calling the page, the following error comes up:
javax.servlet.ServletException: javax.servlet.jsp.JspException: org.apache.jasper.JasperException: Unable to convert string "[\d{4}]" to class "javax.el.ValueExpression" for attribute "regex": Property Editor not registered with the PropertyEditorManager
Caused by:
org.apache.jasper.JasperException - Unable to convert string "[\d{4}]" to class "javax.el.ValueExpression" for attribute "regex": Property Editor not registered with the PropertyEditorManager
I hope I provided enough details for someone to help me out on this...
I seem to have a similar problem like yours, I'm trying to find the solution but seems that the problem is when using Tomcat or the application server(WebSphere Application Server 7.0) JSF libraries, my problem is that the new application server has new JSF libraries (1.2) instead of the 1.1 libraries that my old application server had. (Version 6.1)
To be more specific. my problem is described here. http://www-01.ibm.com/support/docview.wss?uid=swg21318801
i cannot use any bean value in my custom control.:
for instance:
this is my foo.taglib.xml file.
<facelet-taglib>
<namespace>http://www.penguenyuvasi.org/tags</namespace>
<tag>
<tag-name>test</tag-name>
<component>
<component-type>test.Data</component-type>
</component>
</tag>
</facelet-taglib>
faces-config.xml
<component>
<component-type>test.Data</component-type>
<component-class>test.Data</component-class>
</component>
test.Data class
package test;
import java.io.IOException;
import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;
public class Data extends UIComponentBase {
private Object msg;
#Override
public String getFamily() {
return "test.Data";
}
#Override
public void encodeBegin(FacesContext context) throws IOException {
super.encodeBegin(context);
context.getResponseWriter().write(msg.toString());
}
public void setMsg(Object msg) {
this.msg = msg;
}
}
Bean.java:
package test;
public class Bean {
private String temp = "vada";
public String getTemp() {
return temp;
}
}
test.xhtml (doesn't work)
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://www.penguenyuvasi.org/tags">
<py:test msg="#{bean.temp}" />
</html>
test.xhtml (works)
<py:test msg="#{bean.temp}" />
In your test.Data class, I suggest that you implement the getter for msg like that:
public String getMsg() {
if (msg != null) {
return msg;
}
ValueBinding vb = getValueBinding("msg");
if (vb != null) {
return (String) vb.getValue(getFacesContext());
}
return null;
}
And then, in your encodeBegin method:
...
context.getResponseWriter().write(getMsg());
...
This getter method is needed in order to evaluate the expression you may give to the msg attribute in your JSF page.
Edit, to use ValueExpression instead of the deprecated ValueBinding:
ValueExpression ve = getValueExpression("msg");
if (ve != null) {
return (String) ve.getValue(getFacesContext().getELContext());
}