如何将 jar 中的所有 类 添加到 Jersey JAXBContext 上下文
How to add all classes in a jar to Jersey JAXBContext context
我有一个装有模型 DTO 的罐子。
我希望 Jersey 1 HTTP 客户端可以使用这些 类(标记为 @XmlRootElement
)。我的初始化代码是:
ClientConfig cc = new DefaultClientConfig(MyContextResolver.class);
Client client = Client.create(cc);
在 MyContextResolver
(实现 ContextResolver<JAXBContext>
)中,我试过:
jaxbContext = JAXBContext.newInstance(Class1.class, Class2.class);
它可以工作,但它不是动态的(我必须手动添加 类,一个一个地添加)。
I also used Spring and it worked,但我想要一个 Spring 免费解决方案。
有更好的解决办法吗?自动扫描 jar 中的所有 类 并将它们添加到上下文中的一个?谢谢。
您是否希望有一个同时处理所有 classes 的上下文?如果名称冲突,您将面临异常风险。
为什么不简单地拥有一个像这样工作的 ContextResolver:
Map<Class,JAXBContect> cache = new ConcurrentHashMap<>();
getContext(Class<?> type) {
JAXBContect context = cache.get(type);
if (context == null) }
context = JAXBContext.newInstance(type);
cache.put(type,context);
}
return context;
}
JAXB 将解析必要的 classes 依赖项(唯一的问题是子 classes 但那些应该在父 class 中标记为 @XMLSeeAlso)。
唯一的潜在问题是您会在运行时而非启动期间发现任何 JAXB 问题。但与此同时,任何错误只会影响依赖于错误注释 classes 的客户端,其余的将正常工作。
我最终手动扫描了 jar...
public static List<Class> listClassesInPackage(String jarName, String packageName) throws IOException {
packageName = packageName.replaceAll("\.", "/");
JarInputStream jarFile = new JarInputStream(new FileInputStream(jarName));
JarEntry jarEntry = null;
List<Class> classes = new ArrayList();
do {
try {
jarEntry = jarFile.getNextJarEntry();
if (jarEntry != null && jarEntry.getName().startsWith(packageName) && jarEntry.getName().endsWith(".class")) {
Class<?> forName = Class.forName(jarEntry.getName().replaceAll("/", "\.").replaceAll(".class", ""));
XmlRootElement xmlAnnotation = forName.getAnnotation(XmlRootElement.class);
if (xmlAnnotation != null) {
classes.add(forName);
}
}
} catch (ClassNotFoundException | IOException ex) {
// ignore this class
}
} while (jarEntry != null);
return classes;
}
调用:
List<Class> packageClasses = listClassesInPackage(
Meta.class.getProtectionDomain().getCodeSource().getLocation().getPath(), "pt.iol.model2");
jaxbContext = JAXBContext.newInstance(packageClasses.toArray(new Class[0]));
我有一个装有模型 DTO 的罐子。
我希望 Jersey 1 HTTP 客户端可以使用这些 类(标记为 @XmlRootElement
)。我的初始化代码是:
ClientConfig cc = new DefaultClientConfig(MyContextResolver.class);
Client client = Client.create(cc);
在 MyContextResolver
(实现 ContextResolver<JAXBContext>
)中,我试过:
jaxbContext = JAXBContext.newInstance(Class1.class, Class2.class);
它可以工作,但它不是动态的(我必须手动添加 类,一个一个地添加)。
I also used Spring and it worked,但我想要一个 Spring 免费解决方案。
有更好的解决办法吗?自动扫描 jar 中的所有 类 并将它们添加到上下文中的一个?谢谢。
您是否希望有一个同时处理所有 classes 的上下文?如果名称冲突,您将面临异常风险。
为什么不简单地拥有一个像这样工作的 ContextResolver:
Map<Class,JAXBContect> cache = new ConcurrentHashMap<>();
getContext(Class<?> type) {
JAXBContect context = cache.get(type);
if (context == null) }
context = JAXBContext.newInstance(type);
cache.put(type,context);
}
return context;
}
JAXB 将解析必要的 classes 依赖项(唯一的问题是子 classes 但那些应该在父 class 中标记为 @XMLSeeAlso)。
唯一的潜在问题是您会在运行时而非启动期间发现任何 JAXB 问题。但与此同时,任何错误只会影响依赖于错误注释 classes 的客户端,其余的将正常工作。
我最终手动扫描了 jar...
public static List<Class> listClassesInPackage(String jarName, String packageName) throws IOException {
packageName = packageName.replaceAll("\.", "/");
JarInputStream jarFile = new JarInputStream(new FileInputStream(jarName));
JarEntry jarEntry = null;
List<Class> classes = new ArrayList();
do {
try {
jarEntry = jarFile.getNextJarEntry();
if (jarEntry != null && jarEntry.getName().startsWith(packageName) && jarEntry.getName().endsWith(".class")) {
Class<?> forName = Class.forName(jarEntry.getName().replaceAll("/", "\.").replaceAll(".class", ""));
XmlRootElement xmlAnnotation = forName.getAnnotation(XmlRootElement.class);
if (xmlAnnotation != null) {
classes.add(forName);
}
}
} catch (ClassNotFoundException | IOException ex) {
// ignore this class
}
} while (jarEntry != null);
return classes;
}
调用:
List<Class> packageClasses = listClassesInPackage(
Meta.class.getProtectionDomain().getCodeSource().getLocation().getPath(), "pt.iol.model2");
jaxbContext = JAXBContext.newInstance(packageClasses.toArray(new Class[0]));