1

I can't inject the service using the @Autowired in the jsf converter:

Converter:

@Component("advertiserConverter")
@FacesConverter("advertiserConverter")
public class AdvertiserConverter implements Converter , Serializable {

 @Autowired
 private IAdvertiserService advertiserService;

 public Object getAsObject(FacesContext context, UIComponent component, String value) {
    if (value == null || value.length() == 0) {
        return null;
    }
    Long id = Long.parseLong(value);
    return advertiserService.findAdvertiser(id);
 }

 public String getAsString(FacesContext context, UIComponent component, Object value) {
    return value instanceof Advertiser ? ((Advertiser) value).getId().toString() : "";
 }
}

ApplicationContext.xml:

<context:annotation-config />
<context:component-scan base-package="com.test.example"/>
<tx:annotation-driven />

Service:

@Service
@Transactional
public class AdvertiserServiceImpl implements IAdvertiserService {

}
Youraf
  • 160
  • 2
  • 12
  • A `@FacesConverter` isn't a spring bean but a JSF bean. So using `@Autowired` on them isn't going to work. With your current configuration you have 2 instances one managed by Spring (due to the `@Component` and one by JSF due to `@FacesConverter`). You can try and remove `@FacesConverter` and if you have configured the Spring JSF integration properly it should be able to retrieve the converter, by name, from the spring context. – M. Deinum Jul 22 '14 at 09:25
  • Hey M.Deinum, thank's for your response. When I removed the @FacesConverter, the converter is not anymore detected. – Youraf Jul 22 '14 at 09:35
  • I would expect that if you use a correct expression the converter would be detected in the spring context. If not you have to do a dependency lookup and get hold of the `ApplicationContext` or `BeanFactoty` somehow. – M. Deinum Jul 22 '14 at 09:56
  • Sorry, can you explain anymore what can i do? – Youraf Jul 22 '14 at 10:05

4 Answers4

8

finally i found a solution:

converter:

@Service
public class AdvertiserConverter implements Converter{

xhtml:

converter="#{advertiserConverter}"

instead of

converter="advertiserConverter"
Youraf
  • 160
  • 2
  • 12
  • 1
    Additional information: JSF way would be using @ManagedBean annotation at your custom converter class. – LarsBauer Jul 23 '14 at 16:02
0

You do not need to create your own converter.

If you want a generic converter then Omnifaces SelectItemsConverter is the best in all.

Omni Faces Converter

If you don't want to use Omnifaces then use below generic converter

import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.WeakHashMap;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;

@FacesConverter(value = "entityConverter")
public class EntityConverter implements Converter {

    private static Map<Object, String> entities = new WeakHashMap<Object, String>();

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object entity) {
        synchronized (entities) {
            if (!entities.containsKey(entity)) {
                String uuid = UUID.randomUUID().toString();
                entities.put(entity, uuid);
                return uuid;
            } else {
                return entities.get(entity);
            }
        }
    }

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String uuid) {
        for (Entry<Object, String> entry : entities.entrySet()) {
            if (entry.getValue().equals(uuid)) {
                return entry.getKey();
            }
        }
        return null;
    }

}
Makky
  • 15,166
  • 17
  • 58
  • 81
0

JSF doesn't recoginize spring Beans. Hence you need to saprate out spring and JSF beans for better example refer here

JSF managed bean

@FacesConverter("advertiserConverter")
public class AdvertiserConverter implements Converter , Serializable {


 public Object getAsObject(FacesContext context, UIComponent component, String value) {
    if (value == null || value.length() == 0) {
        return null;
    }
    Long id = Long.parseLong(value);
    ApplicationContext ctx = WebApplicationContextUtils
            .getRequiredWebApplicationContext((ServletContext) FacesContext
                    .getCurrentInstance().getExternalContext()
                    .getContext());
    IAdvertiserService advertiserService= (AdvertiserServiceImpl) ctx.getBean("advertiserServiceImpl");
    return advertiserService.findAdvertiser(id);
 }

 public String getAsString(FacesContext context, UIComponent component, Object value) {
    return value instanceof Advertiser ? ((Advertiser) value).getId().toString() : "";
 }
}

Spring bean

@Service("advertiserServiceImpl")
@Transactional
public class AdvertiserServiceImpl implements IAdvertiserService {

}

faces-config.xml

<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_1.xsd"
    version="2.1">

    <application>
        <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
    </application>

</faces-config>

Web.xml

<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
  </listener>
  <listener>
    <listener-class>
        org.springframework.web.context.request.RequestContextListener
    </listener-class>
  </listener>
Karthik Prasad
  • 8,604
  • 7
  • 53
  • 93
  • Hey Karthik, Even if i do that, i still have null in the service – Youraf Jul 22 '14 at 10:58
  • Hope you have updated web.xml for spring listener, you have refering spring application context file(file where you defined package scan) in web.xml(context location). Its better to go through the tutorial cross examine all your configs are set properly – Karthik Prasad Jul 22 '14 at 11:04
  • in my web.xml i have: org.springframework.web.context.ContextLoaderListener – Youraf Jul 22 '14 at 11:08
  • Have you added second listener and contextConfigLocation {path}/applicationcontext.xml – Karthik Prasad Jul 22 '14 at 11:15
  • yes, contextConfigLocation /WEB-INF/spring/spring-root.xml – Youraf Jul 22 '14 at 11:28
  • OK.... Is your spring container getting initalized, when you enable your logs to debug mode is advertiserServiceImpl bean getting created? and hope you have change to @ManagedProperty(value="#{advertiserServiceImpl}") – Karthik Prasad Jul 22 '14 at 11:42
  • in the managaed bean the service is created and injected but the problem is just in the Converter. and even if i use @ManagedProperty(value="#{advertiserServiceImpl}") it's not working – Youraf Jul 22 '14 at 11:50
  • @Youraf: Tried today and found Converters are not created they way managedbeans are created, Hence you cannot inject using managedProperty. An alternative is use WebapplicationContextUtils to get spring beans. – Karthik Prasad Jul 23 '14 at 12:25
-1

FWIW, I had to convert my "@Autowired" services to be @ManagedProperty's... ...Something like this:

-
-
-

@ManagedProperty(value = "#{myService}")
private MyService myService;
public MyService getMyService()
{
    return myService;
}
public void setMyService(MyService myService)
{
    this.myService = myService;
}

-
-
-
sairn
  • 381
  • 3
  • 22
  • 52