我正在编写我的第一个Java EE 6 Web应用程序作为学习练习.我没有使用框架,只有JPA 2.0,EJB 3.1和JSF 2.0.
我有一个自定义转换器将存储在SelectOne组件中的JPA实体转换回实体.我正在使用InitialContext.lookup来获取对会话Bean的引用以查找相关的实体.
我想创建一个通用的实体转换器,所以我不必为每个实体创建一个转换器.我以为我会创建一个抽象实体并让所有实体扩展它.然后为抽象实体创建自定义转换器,并将其用作所有实体的转换器.
这听起来是否合理和/或切实可行?
是不是有一个抽象的实体,只是一个转换器来转换任何实体更有意义?在那种情况下,我不确定如何获得对相应会话Bean的引用.
我已经包含了我当前的转换器,因为我不确定我是否以最有效的方式获取对Session Bean的引用.
package com.mycom.rentalstore.converters;
import com.mycom.rentalstore.ejbs.ClassificationEJB;
import com.mycom.rentalstore.entities.Classification;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.FacesConverter;
import javax.naming.InitialContext;
import javax.naming.NamingException;
@FacesConverter(forClass = Classification.class)
public class ClassificationConverter implements Converter {
private InitialContext ic;
private ClassificationEJB classificationEJB;
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
try {
ic = new InitialContext();
classificationEJB = (ClassificationEJB) ic.lookup("java:global/com.mycom.rentalstore_RentalStore_war_1.0-SNAPSHOT/ClassificationEJB");
} catch (NamingException e) {
throw new ConverterException(new FacesMessage(String.format("Cannot obtain InitialContext - %s", e)), e);
}
try {
return classificationEJB.getClassificationById(Long.valueOf(value));
} catch (Exception e) {
throw new ConverterException(new FacesMessage(String.format("Cannot convert %s to Classification - %s", value, e)), e);
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return String.valueOf(((Classification) value).getId());
}
}
Run Code Online (Sandbox Code Playgroud)
我今天遇到了同样的问题,我通过创建一个通用的ConversionHelper并在转换器中使用它来解决它.为此,我有一个EntityService,它是一个通用的SLSB,我用它来为任何实体类型执行简单的CRUD操作.我的实体也实现了一个PersistentEntity接口,它有一个getId和setId方法,我用简单的主键保存它们.而已.
最后我的转换器看起来像这样:
@FacesConverter(value = "userConverter", forClass = User.class)
public class UserConverter implements Converter {
@Override
public Object getAsObject(FacesContext ctx, UIComponent component, java.lang.String value) {
return ConversionHelper.getAsObject(User.class, value);
}
@Override
public String getAsString(FacesContext ctx, UIComponent component, Object value) {
return ConversionHelper.getAsString(value);
}
}
我的转换助手看起来像这样:
public final class ConversionHelper {
private ConversionHelper() {
}
public static <T> T getAsObject(Class<T> returnType, String value) {
if (returnType== null) {
throw new NullPointerException("Trying to getAsObject with a null return type.");
}
if (value == null) {
throw new NullPointerException("Trying to getAsObject with a null value.");
}
Long id = null;
try {
id = Long.parseLong(value);
} catch (NumberFormatException e) {
throw new ConverterException("Trying to getAsObject with a wrong id format.");
}
try {
Context initialContext = new InitialContext();
EntityService entityService = (EntityService) initialContext.lookup("java:global/myapp/EntityService");
T result = (T) entityService.find(returnType, id);
return result;
} catch (NamingException e) {
throw new ConverterException("EntityService not found.");
}
}
public static String getAsString(Object value) {
if (value instanceof PersistentEntity) {
PersistentEntity result = (PersistentEntity) value;
return String.valueOf(result.getId());
}
return null;
}
}
现在为简单的JPA实体创建转换器是转换器的重复并且更改3个参数.
这对我很有用,但我不知道它是否是风格和性能方面的最佳方法.任何提示将不胜感激.
小智 7
我正在使用JSF 2.0视图:
@FacesConverter("entityConverter")
public class EntityConverter implements Converter {
private static final String key = "com.example.jsf.EntityConverter";
private static final String empty = "";
private Map<String, Object> getViewMap(FacesContext context) {
Map<String, Object> viewMap = context.getViewRoot().getViewMap();
@SuppressWarnings({ "unchecked", "rawtypes" })
Map<String, Object> idMap = (Map) viewMap.get(key);
if (idMap == null) {
idMap = new HashMap<String, Object>();
viewMap.put(key, idMap);
}
return idMap;
}
@Override
public Object getAsObject(FacesContext context, UIComponent c, String value) {
if (value.isEmpty()) {
return null;
}
return getViewMap(context).get(value);
}
@Override
public String getAsString(FacesContext context, UIComponent c, Object value) {
if (value == null) {
return empty;
}
String id = ((Persistent) value).getId().toString();
getViewMap(context).put(id, value);
return id;
}
}
Run Code Online (Sandbox Code Playgroud)