1

我以前有这个工作,但后来我改变了一些东西,我不能让它再次工作。我正在尝试使用我的服务层来访问数据库并从我的转换器类中获取正确的对象,具体取决于用户单击的内容。我用弹簧将服务属性注入我的转换器。在调试期间,我可以看到该属性已正确设置。但是当我去调用 getService 时,它​​是空的。

@FacesConverter("PlaceConverter")

@SessionScoped 公共类 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

4 回答 4

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()like so打印com.example.Place@hashcode,使其无法在服务器端使用。

于 2013-01-27T12:04:58.467 回答
0

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

于 2013-01-27T01:24:21.760 回答
0

Converter在更新模型 bean 之前开始播放。当用户填写一些输入并且此值首先传输到服务器时,会更新您的服务器端组件并发生下一次转换。保存在您的 bean 中的转换值(使用 method getAsObject)并且在渲染来自 bean 的视图值之前再次转换为,String因为从用户端一切都是一个字符串(然后getAsString调用方法)。

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

由于您的问题和问题。你的意思SearchQueryService是在方法内部不可用getAsObject。尝试添加@Resource具有适当name属性的附加注释,然后它应该由您的容器注入。

于 2013-01-27T09:35:50.573 回答
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>
于 2014-11-25T08:15:27.937 回答