jsf转换器失去了注入属性

时间:2013-01-27 00:37:46

标签: spring jsf converter code-injection

我之前有过这个工作,但后来我改变了一些东西,我再也无法让它工作了。我正在尝试使用我的服务层来访问数据库并从我的转换器类中获取正确的对象,具体取决于用户点击的内容。我用spring将服务属性注入到我的转换器中。在调试过程中,我可以看到该属性正确设置。但是当我去调用getService时,它是null。

@FacesConverter("PlaceConverter")

@SessionScoped public class PlaceConverter实现了Converter {

private SearchQueryService searchQueryService;

/**
 * @return the searchQueryService
 */
public SearchQueryService getSearchQueryService() {
    return searchQueryService;
}

/**
 * @param searchQueryService the searchQueryService to set
 */
public void setSearchQueryService(SearchQueryService searchQueryService) {
    this.searchQueryService = searchQueryService;
}

@Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String submittedValue) {
        try {
            Criteria criteria = new Criteria();
            criteria.setId(Integer.parseInt(submittedValue));
            return getSearchQueryService().findPlaces(criteria).get(0);
        } catch (NumberFormatException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    return null;
}

@Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object value) {
    ((Place) value).setCategory(" (" + ((Place) value).getCategory() + ")");
    return String.valueOf(((Place) value).getPlaceId());
}

}

<bean id="placeConverterBean" class="com.ghghg.converter.PlaceConverter">
    <property name="searchQueryService" ref="searchQueryServiceBean" />
</bean>

4 个答案:

答案 0 :(得分:1)

只有当转换器被相关的依赖注入框架声明为托管bean时,转换器中的依赖注入才有效。例如。 JSF自己的@ManagedBean,或CDI的@Named,或Spring的@Component。您应该完全删除@FacesConverter并在EL范围中引用转换器实例,而不是通过转换器ID引用它。

因此,所以

<h:inputXxx converter="#{placeConverter}" />

<f:converter binding="#{placeConverter}" />

而不是

<h:inputXxx converter="PlaceConverter" />

<f:converter converterId="PlaceConverter" />

您的具体问题表明您是通过转换器ID引用它的(因此,通过@FacesConverter)。这样,您最终得到的转换器实例没有任何注入依赖项。

另见:

关于转换器本身的作用,这是必需的,因为HTML代码表示为一个大字符串,HTTP请求参数值只能表示为字符串。否则复杂的Java对象将通过Object#toString()打印,如com.example.Place@hashcode那样,使其在服务器端无法使用。

答案 1 :(得分:0)

我找到了一种更好的方法,也许更合适的方法来获得我想要的东西。我不完全确定转换器的工作原理以及所选项的值如何传递回托管bean。我刚刚在我的方法中声明了一个新的Place对象,设置了所需的值。然后我看到它被传递给我的托管bean

答案 2 :(得分:0)

在更新模型bean之前,

Converter开始发挥作用。当用户填写一些输入并且该值被转移到服务器时,首先更新服务器端组件并进行下一次转换。保存在bean中的转换值(使用方法getAsObject)并在从bean呈现视图值之前再次转换为String,因为从用户端一切都是字符串(然后方法getAsString是调用)。

总而言之 - Converter方法是将用户输入更改为应用程序逻辑,bean字段以及将逻辑,bean字段转换为用户友好字符串的其他方式的最佳位置。

由于您的问题和疑问。您的意思是SearchQueryService方法中getAsObject不可用。尝试添加具有正确@Resource属性的注释name,然后应该由您的包含注入。

我希望它会有所帮助。

答案 3 :(得分:0)

我使用jsf 2.0在java EE中使用它。通过使转换器成为支持bean的成员。我使用CDI实例化该成员,但它应该与spring一样。

首先是支持bean:

@ViewScoped
@ManagedBean
public class SomeView implements Serializable {

    private static final long serialVersionUID = 1L;

    @Inject
    private SomeConverter converter;

    public Converter getConverter() {
        return converter;
    }
}

然后这是jsf xhtml:

<p:selectOneMenu id="someId" value="#{someView.value}" converter="#{someView.converter}">
    <f:selectItems value="#{someView.values}" var="object" itemLabel="#{object.name}" />
</p:selectOneMenu>