因爲有一天我被困在這個問題中。但首先我想描述一下,爲什麼我要按照所示方式行事:在運行時添加@XmlTransient註釋(結合自己的註釋)
我們正在使用EE7和Glassfish4在Java中構建一個RESTful API。認證和授權必須由我們自己構建(學生項目)。所以這個想法是爲@AccesRight和@Roles添加我們自己的註釋。在解釋每個集合上的元數據並獲得我們模型的方法(如果聲明)後,應在運行時設置@XmlTransient註釋,當用戶無權查看時。簡而言之:在模型屬性中授予不同的訪問權限。我試圖從_model-class-methods(請參閱方法簽名)修改方法註釋,但是當我運行「.toClass()」時,它失敗了,因爲WebAppClassLoader已經加載了一個類(重複條目)。所以我決定使用給定模型的另一個名稱(_model.getClass()。getName()+ transactionToken)創建副本。最大的問題是:我無法將這個副本轉換爲原始模型(我得到ClassCastException)。類和copyclass存儲在同一個類加載器中。
所以我認爲要調用像「loadModelByEntity(UserModel _model)」存儲在所有模型中。問題是:在運行.toClass()我的副本類後的方法簽名,現在看起來如下:loadModelByEntity(UserModel020a8e6bb07c65da3e9095368db34e843c0b0d1e _model)
了Javassist正在改變類中的所有數據類型。
有什麼辦法來防止這種情況發生,或者用我的複製模型填充數據嗎?有什麼方法可以投射我的複製模型?
非常感謝! 菲爾
//my annotation interface
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD})
public @interface AccessRight
{
String name() default "";
Role[] roles() default {};
boolean self() default true;
boolean friends() default true;
}
//my method where i analyse the annotation (and perhaps set a new one)
public Object filter(Object _model, String _transactionToken) throws Exception
{
String className = _model.getClass().getName() + transactionToken;
ClassPool pool = ClassPool.getDefault();
CtClass copyClass = pool.getOrNull(className);
if(copyClass != null)
{
Class filterModel = copyClass.getClass().getClassLoader().loadClass(className);
Object filterInstance = filterModel.newInstance();
filterInstance.getClass().getDeclaredMethod("loadByEntity", _model.getClass()).invoke(filterInstance, _model);
return filterInstance;
}
pool.insertClassPath(new ClassClassPath(_model.getClass()));
pool.makeClass(className);
copyClass = pool.getAndRename(_model.getClass().getName(), className);
ClassFile copyClassFile = copyClass.getClassFile();
ConstPool constPool = copyClassFile.getConstPool();
AnnotationsAttribute attribute = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
Annotation annotation = attribute.getAnnotation("javax.xml.bind.annotation.XmlTransient");
if(annotation == null)
{
attribute.addAnnotation(new Annotation("javax.xml.bind.annotation.XmlTransient", constPool));
}
for(CtMethod method : copyClass.getDeclaredMethods())
{
if(method.hasAnnotation(AccessRight.class))
{
AccessRight arAnnotation = (AccessRight)method.getAnnotation(AccessRight.class);
if(!checkAccess(arAnnotation.name(), arAnnotation.roles(), arAnnotation.friends(), arAnnotation.self()))
{
method.getMethodInfo().addAttribute(attribute);
}
}
}
return copyClass.toClass().newInstance();
}
//my consideration to fill the copy model (but it doesn`t work, like i described)
public void loadByEntity(UserModel _model)
{
this.m_id = _model.getId();
this.m_firstname = _model.getFirstname();
this.m_lastname = _model.getLastname();
this.m_username = _model.getUsername();
this.m_birthday = _model.getBirthday();
this.m_email = _model.getEmail();
this.m_password = _model.getPassword();
this.m_roleId = _model.getRoleId();
this.m_timestampCreated = _model.getTimestampCreated();
this.m_accessRightList = _model.getAccesRightList();
}
我發現vor鑄造(但非常sc))的一種可能的方式是設置原始模型的超類。但是,我的所有方法都是重複的。他的問題很大:我的方法loadByEntity()完全是另一個,因爲方法簽名看起來像loadByEntity(UserModel020a8e6bb07c65da3e9095368db34e843c0b0d1e _model) –