我以前有过这个工作,但后来我改变了一些东西,我无法让它再次工作。我正在尝试使用我的服务层来访问数据库并从我的转换器类中获取正确的对象,具体取决于用户单击的内容。我用弹簧将服务属性注入我的转换器。在调试期间,我可以看到该属性正确设置。但是当我去调用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>
仅当相关依赖注入框架将转换器声明为托管 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
)。这样,您最终会获得一个没有任何注入依赖项的转换器实例。
另请参阅:
- 如何将弹簧豆注入 JSF 转换器
至于转换器本身的角色,这是强制性的,因为 HTML 代码表示为一个大字符串,而 HTTP 请求参数值只能表示为字符串。否则复杂的Java对象会通过Object#toString()
打印,就像com.example.Place@hashcode
一样,使其在服务器端无法使用。
我找到了更好的方法,可能更合适的方法来获得我想要的东西。我不完全确定转换器的工作原理以及如何将所选项目的值传递回托管 Bean。我刚刚在我的方法中声明了一个新的 Place 对象,设置了所需的值。然后我看到它被传递给了我管理的 bean
我让它在java EE中使用jsf 2.0像这样工作。通过使转换器成为支持Bean的成员。我使用 CDI 实例化这个成员,但它应该与 spring 一样工作。
首先是背豆:
@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>
Converter
在更新模型 Bean 之前发挥作用。当用户填写一些输入并将此值传输到服务器时,首先更新您的服务器端组件,并且发生了下一次转换。保存在 bean 中的转换值(使用方法 getAsObject
)和渲染 bean 的视图值之前再次转换为 String
,因为从用户端一切都是字符串(然后调用方法 getAsString
)。
总之 - Converter
方法是将用户输入更改为应用程序逻辑 Bean 字段的最佳方式,并以其他方式将逻辑 Bean 字段转换为用户友好的字符串。
由于您的问题和问题。您的意思是SearchQueryService
getAsObject
方法中不可用。尝试添加具有适当 name
属性的 addnotation @Resource
,然后它应该由容器注入。