让我们假设以下场景:
我有以下类型的对象列表:
public class MyObject {
private String name
private SomeClass someField
private List<Fact> facts
}
字段name
和something Field
只是为了表明该类有一些常规成员。您可以假设知道如何将这些类转换为xml。
Fact
是一个接口,其中的实现我不知道,但由插件提供。插件可以被要求提供任意代码,但我想让它尽可能简单。
我想将这些对象保存并加载到xml中。请注意,在加载xml时,并不是所有的实现都存在(xml可能是用不同的插件集编写的)。我希望在再次保存时仍能读取xml,并且不会丢失任何信息。换句话说:我愿意添加一个字段,比如List
如何最好地使用JAXB实现这一点?
我能看到的一种方法是使用
Map
不知道best
,但一种接近您描述的方法是:
JAXB不使用接口;它所能做的最好是一个抽象类。意思是你需要使用列表
您的插件提供了扩展的基本类(SPI将是通常的方法)。您收集它们并(在验证后)使用它们来创建您的
JAXBContext
。(如果您想支持多个接口,可以通过不同的方法提供它们)。
在xml中,需要有这样一个类型标记:
下面是一个简单的例子:
interface Fact {
}
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
class R {
@XmlElement(name = "fact")
private List<Object> facts;
@SuppressWarnings("unchecked")
public List<Fact> getTest() {
if (facts == null) {
facts = new ArrayList<>();
}
return (List<Fact>) (Object) facts;
}
public void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
// check if all facts implement same interface
for(Object object:facts) {
if (!(object instanceof Fact)) {
throw new IllegalArgumentException("Unsupported type in facts list");
}
}
}
}
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "aFact")
class AFact implements Fact {
@XmlElement
private String a;
public AFact() {
}
public AFact(String a) {
this.a = a;
}
public String getA() {
return a;
}
@Override
public String toString() {
return "AFact [a=" + a + "]";
}
}
public class Jax {
public static void main(String[] args) throws JAXBException {
String xml = "<r><fact xsi:type=\"aFact\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><a>ba</a></fact></r>";
List<Class<?>> contextClasses = new ArrayList<>();
contextClasses.add(R.class);
contextClasses.addAll(getClassesFromPlugin());
JAXBContext context = JAXBContext.newInstance(contextClasses.toArray(new Class<?>[0]));
R entity = (R) context.createUnmarshaller().unmarshal(new StringReader(xml));
System.out.println(entity.getTest());
R r = new R();
r.getTest().add(new AFact("ab"));
context.createMarshaller().marshal(r, System.out);
}
private static List<Class<?>> getClassesFromPlugin() {
List<Class<?>> asList = Arrays.asList(AFact.class);
for(Class<?> cls:asList) {
if (!Fact.class.isAssignableFrom(cls)) {
throw new IllegalArgumentException("Unsupported class");
}
}
return asList;
}
}
插件类是用户编写的, 但是它需要继承自Yaf_Plugin_Abstract. 对于插件来说, 上一节提到的7个Hook, 它不需要全部关心, 它只需要在插件类中定义和上面事件同名的方法, 那么这个方法就会在该事件触发的时候被调用. 而插件方法, 可以接受俩个参数, Yaf_Request_Abstract实例和Yaf_Response_Abstract实例. 一个插件类例子如下: 例 7.1.
本文向大家介绍jQuery定义插件的方法,包括了jQuery定义插件的方法的使用技巧和注意事项,需要的朋友参考一下 有些WEB开发者,会引用一个JQuery类库,然后在网页上写一写$("#"),$("."),写了几年就对别人说非常熟悉JQuery。我曾经也是这样的人,直到有一次公司里的技术交流,我才改变了自己对自己的看法。 扩展jquery的时候。最核心的方法是以下两种: $.extend(obj
英文原文: http://emberjs.com/guides/routing/defining-your-routes/ 当启动你的应用时,路由器会负责展示模板,载入数据,以及设置应用状态等任务。 这些都是通过将当前的URL与你定义的路由进行匹配来实现的。 1 2 3 4 App.Router.map(function() { this.route("about", { path: "/a
我使用了一个自定义插件,该插件使用PluginManager类以编程方式注册,以加载map中的值,并根据map的内容更改RollingFileAppender的文件名。 然后,我更改了配置,使用路由追加器,以便能够使用ThreadContext内容进一步更改文件名(基本上,我希望应用程序的每个线程都有一个日志文件)。 然而,自从我开始使用Routing appender以来,我的自定义插件不再产生
下面的这些代码可以帮助您通过CSS文件和SCSS文件,创建和编译 CSS 和 JS 文件的source-maps。 安装依赖 为了运行编译和压缩任务,你必须安装 node 和 npm。 命令行 // (Optional) Install Gulp module globally npm install gulp -g // Install fullpage's build dependen
注册路由规则 route目录下的任何路由定义文件都是有效的,默认的路由定义文件是route.php,但你完全可以更改文件名,或者添加多个路由定义文件(你可以进行模块定义区分,但最终都会一起加载)。 ├─route 路由定义目录 │ ├─route.php 路由定义 │ ├─api.php 路由定义 │ └─...