# JSF 2 Global Converter



## Marsman (4. Jan 2011)

Hallo Ihr!

Ich migriere gerade meine Anwendung von JSF 1.2 zu 2.0. Dazu habe ich u.a. einen Typ-abhängigen Konverter registriert, der leere String in Null und umgekehrt konvertieren soll. Der Konverter wird auch aufgerufen und funktioniert korrekt. Der Null-Wert erreicht aber nicht die Bean und wird dem zufolge auch nicht persistiert. Mir fällt langsam keinen Grund mehr ein. Hier Ausschnitte meines Codes.

EmptyToNullConverter.java:

```
@FacesConverter(forClass = String.class)
public class EmptyToNullConverter implements Converter {

  public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
    if (value == null || value.trim().length() == 0) {
      if (component instanceof EditableValueHolder) {
        ((EditableValueHolder) component).setSubmittedValue(null);
      }
      return null;
    }
    return value;
  }

  public String getAsString(FacesContext facesContext, UIComponent component, Object value) {
    return (value == null) ? null : value.toString();
  }
}
```


editAlbum.xhtml:

```
<h:inputText id="label" value="#{albumDetailBean.album.label}" size="50"></h:inputText>
```


```
public class AlbumDetailBean {

  private AlbumService albumService;

  private Album album;

  public static AlbumDetailBean getInstance() {
    FacesContext fc = FacesContext.getCurrentInstance();
    return (AlbumDetailBean) fc.getApplication().evaluateExpressionGet(fc, "#{albumDetailBean}", AlbumDetailBean.class);
  }

  public String save() {
    if (album.getId() == null)
      albumService.insert(album);
    else
      albumService.update(album);
    return "success";
  }

  public Album getAlbum() {
    return album;
  }

  public void setAlbum(Album album) {
    // Hier ist album.label wieder "" und nicht null...!
    this.album = album;
  }

  public void setAlbumService(AlbumService albumService) {
    this.albumService = albumService;
  }
}
```

faces-config.xml (Migriere ich später noch in Annotations):

```
<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
    version="2.0">
  <managed-bean>
    <managed-bean-name>albumDetailBean</managed-bean-name>
    <managed-bean-class>de.freakworm.manager.controller.AlbumDetailBean</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    <managed-property>
      <property-name>albumService</property-name>
      <property-class>de.freakworm.manager.service.AlbumService</property-class>
      <value>
        #{albumService}</value>
    </managed-property>
  </managed-bean>
</faces-config>
```

Hat jemand eine Idee, warum der Null-Wert nicht in der Bean landet?


Titus


----------



## nocturne (5. Jan 2011)

Der Fehler liegt in "getAsString"! 
Der Rückgabewert darf nicht null sein, aber er darf "null" sein.

Aber damit hast du einen BUG gefunden: 
Eigentlich sollte eine eine IllegalStateException oder eine Nullpointerexception geworfen werden wenn getAsString einen null-wert zurückliefert.


----------



## Marsman (6. Jan 2011)

Ich habe getAsString() so geändert, dass bei null ein leerer String "" zurückgegeben wird. Beim Debuggen habe ich dann allerdings festgestellt, dass getAsString() bei null gar nicht erst aufgerufen wird.

Wie auch immer, das Problem mit getAsObject() besteht weiterhin.

Titus


----------



## Marsman (7. Jan 2011)

Ich habe inzwischen selbst weiter geforscht. Das Problem hängt nicht mit einem bestimmten Converter zusammen. Auch nicht, ob es sich um einen globalen vom Typ abhängigen Converter handelt. Gibt getAsObject() null zurück, wird dieses in new T() umgesetzt. Dieses Verhalten weicht in JSF 2 von dem Verhalten in JSF 1.x ab. Jedenfalls sieht es bis jetzt so aus. Oder bin ich hier total falsch unterwegs?

Titus


----------



## Marsman (10. Jan 2011)

Nach weiteren Forschungen habe ich die Lösung gefunden: Seit Tomcat 6.0.16 sollte man für JSF das VM Argument -Dorg.apache.el.parser.COERCE_TO_ZERO=false setzen.

Bin ich hier im Forum der einzige, der das Problem kennt? 

Titus


----------

