VW user tip1: A workaround for validation messages translation issues

This useful tip was sent to me by Jorge Campins. In this tip Jorge gives a solution to fix the problem related to intermixing of translated messages (Spanish, applies to other languages also) and English, which he jokingly calls as "Spanglish". Especially, this is a case with standard components and its Converters and Validators.

For other user tips, visit  Netbeans Visualweb user tips and code snippets

We wouldn’t know about other languages, but if you are developing with NetBeans 6 there are some translation issues you should solve before releasing your applications to Spanish speaking end-users. Here we specifically address those issues at JSF core components such as Converters and Validators. These issues include not translated, partially translated and wrongfully translated messages; also visual component ids appearing as part of the message, which is very helpful for the programmer but very confusing for the end-user. Fortunately, we were able to deal with all these in an easy way, based on the approach suggested by Dr. Winston Prakash. All we had to do was to build a translation routine and execute it at the prerender event. It was particularly easy for us because we already had all our pages calling some helper methods at prerender, so we didn’t had to modify every page to call the new translator routine. The following is an example of a translation routine based on the one we built:

public static void fixFacesMessages() {
FacesContext facesContext = FacesContext.getCurrentInstance();
UIViewRoot uivr = facesContext.getViewRoot();
Iterator messageClientIds = facesContext.getClientIdsWithMessages();
while (messageClientIds.hasNext()) {
String clientId = messageClientIds.next();
if (clientId != null) {
UIComponent uic = uivr == null ? null : uivr.findComponent(clientId);
Iterator messages = facesContext.getMessages(clientId);
while (messages.hasNext()) {
FacesMessage facesMessage = messages.next();
// Get the messages
String detail = facesMessage.getDetail();
String summary = facesMessage.getSummary();
// translate
String detalle = getMensaje(uic, detail);
String resumen = getMensaje(uic, summary);
// Set your own message

private static String getMensaje(UIComponent uic, String message) {
FacesContext facesContext = FacesContext.getCurrentInstance();
String mensaje = StringUtils.trimToEmpty(message);
if (uic != null) {
mensaje = trimPrefix(mensaje, uic.getClientId(facesContext));
mensaje = trimPrefix(mensaje, uic.getId());
mensaje = trimPrefix(mensaje, ": ");
mensaje = trimPrefix(mensaje, "Validation Error: ");
mensaje = trimPrefix(mensaje, "Error de Validación: ");
mensaje = trimSuffix(mensaje, "Example:");
mensaje = trimSuffix(mensaje, "Ejemplo:");
mensaje = mensaje.replace(
"is not a number",
"debe ser un número");
mensaje = mensaje.replace(
"must be a number consisting of one or more digits",
"debe ser un número");
mensaje = mensaje.replace(
"must be a number between",
"debe ser un número entre");
mensaje = mensaje.replace(
"Specified attribute is not between the expected values of",
"El valor debe estar comprendido entre");
mensaje = mensaje.replace(
" and ",
" y ");
\* We always use the maxLength property of the TextField component to avoid
\* length errors on string fields, so only TextArea components need a Length
\* validator. Therefore, only if the component is a TextArea we need to
\* change the subject of the sentence.
String sujeto = uic instanceof TextArea
? "La longitud del valor"
: "El valor";
mensaje = mensaje.replace(
"Valor es más grande de valor de máximo permitido:",
sujeto + " debe ser menor o igual que");
mensaje = mensaje.replace(
"Valor is menos de valor de mínimo permitido:",
sujeto + " debe ser mayor o igual que");
return mensaje;

public static String trimPrefix(String message, String prefix) {
String mensaje = StringUtils.trimToEmpty(message);
int i = mensaje.indexOf(prefix);
if (i >= 0) {
mensaje = mensaje.substring(i + prefix.length());
return mensaje;

public static String trimSuffix(String message, String suffix) {
String mensaje = StringUtils.trimToEmpty(message);
int i = mensaje.indexOf(suffix);
if (i > 0) {
mensaje = mensaje.substring(0, i);
return mensaje;


Hi Winston im having problems with parameterized Queries for MySQL Database in NetBeans6.1. I keep Getting Statement Parameter 1 not Set Error. Anyway here's what I did and I'm very sure im doing the right thing. Please how can u help me. Thanks in advance

public void reqEntDD_processValueChange(ValueChangeEvent event) {
Integer req = (Integer)reqEntDD.getSelected();
getSessionBean1().getTitlesRowSet().setObject(1, req);
catch(SQLException sqle){

And the following is the error Msg

java.sql.SQLException: Statement parameter 1 not set.
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:910)
at com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1036)
at com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:685)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1262)
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:92)
at com.sun.sql.rowset.internal.CachedRowSetXReader.readData(CachedRowSetXReader.java:227)
at com.sun.sql.rowset.CachedRowSetXImpl5.execute(CachedRowSetXImpl5.java:865)
at com.sun.sql.rowset.CachedRowSetXImpl5.execute(CachedRowSetXImpl5.java:1325)
at com.sun.data.provider.impl.CachedRowSetDataProvider.checkExecute(CachedRowSetDataProvider.java:1351)
at com.sun.data.provider.impl.CachedRowSetDataProvider.setCursorRow(CachedRowSetDataProvider.java:402)
at com.sun.data.provider.impl.CachedRowSetDataProvider.setCursorIndex(CachedRowSetDataProvider.java:373)
at com.sun.data.provider.impl.CachedRowSetDataProvider.getRowCount(CachedRowSetDataProvider.java:713)
at com.sun.webui.jsf.faces.DataProviderELResolver$SelectItemsData.getSelectItems(DataProviderELResolver.java:702)
at com.sun.webui.jsf.faces.DataProviderELResolver.getValue(DataProviderELResolver.java:166)
at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:53)
at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:58)
at org.apache.el.parser.AstValue.getValue(AstValue.java:97)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
at org.apache.jasper.el.JspValueExpression.getValue(JspValueExpression.java:101)
at com.sun.webui.jsf.component.Selector.getItems(Selector.java:577)
at com.sun.webui.jsf.component.ListSelector.getOptions(ListSelector.java:212)
at com.sun.webui.jsf.component.ListSelector.getListItems(ListSelector.java:140)
at com.sun.webui.jsf.renderkit.widget.ListRendererBase.getListProperties(ListRendererBase.java:269)
at com.sun.webui.jsf.renderkit.widget.ListRendererBase.getProperties(ListRendererBase.java:220)
at com.sun.webui.jsf.renderkit.widget.DropDownRenderer.getProperties(DropDownRenderer.java:74)
at com.sun.webui.jsf.renderkit.widget.RendererBase.encodeChildren(RendererBase.java:134)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:827)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:883)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:889)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:889)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:889)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:889)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:889)
at com.sun.faces.application.ViewHandlerImpl.doRenderView(ViewHandlerImpl.java:258)
at com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:176)
at com.sun.rave.web.ui.appbase.faces.ViewHandlerImpl.renderView(ViewHandlerImpl.java:320)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:108)
at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:266)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:159)
at com.sun.faces.extensions.avatar.lifecycle.PartialTraversalLifecycle.render(PartialTraversalLifecycle.java:106)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:245)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.sun.webui.jsf.util.UploadFilter.doFilter(UploadFilter.java:267)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:228)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:216)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:634)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:445)
at java.lang.Thread.run(Thread.java:619)

Posted by Henry Fimibama on April 24, 2008 at 11:07 PM PDT #

You are setting the parameter after displaying the page and selecting some item in the dropdown. But what about while displaying the page. At that time your drop down is bound to a data provider. So you should set some parameter value in the init() method also.

Posted by Winston Prakash on April 24, 2008 at 11:21 PM PDT #

Dear Winston.
Very interesant your tip. But I tried to implement it, and I found some problems. I created a class where I included your code, and I got several compile errors. I copy here the problematic lines

1) Although I tried with the following imports, the next line gives "INCOMPATIBLE TYPES"

import com.sun.xml.rpc.processor.util.StringUtils;
import com.sun.xml.internal.ws.util.StringUtils;
import com.sun.xml.ws.util.StringUtils;

String mensaje = StringUtils.trimToEmpty(message);

("cannot find symbol. Symbo: method trimToEmpty(java.lang.String). Location class.com.sun.xml.ws.util.String.Utils.
incompatible types. found: comsun.xml.ws.util.StringUtils.trimtoEmpty. Required: java.lang.String.

2) The following line gives

String sujeto = uic instanceof TextArea ? "La longitud del valor" : "El valor";


Thank you very much for you help. Juan Carlos.

Posted by juan_neufeld on November 17, 2008 at 02:39 PM PST #

Excelent solution for "validation messages translation issues". Thank you very much.
¡Muchas gracias!

Posted by juan_neufeld on November 18, 2008 at 04:13 PM PST #

Post a Comment:
  • HTML Syntax: NOT allowed

« April 2014