我在服务器端使用 Jersey 1.17 来处理 REST 请求,并使用 JAXB 2 来解码 XML 请求内容。
上下文
这是我使用的 Jersey 方法。 MyDTO 类使用@XmlRootElement 注释(否则,我需要使用 JAXBElement 类型定义参数)。
@Path("/myService")
@POST
@Consumes(MediaType.APPLICATION_XML)
public void myService(MyDTO dto) throws Exception
{
// Shouldn't get this far if the XML content in the request was invalid
System.out.println(dto);
}
要求
默认情况下,当 XML 内容有错误时,Sun/Oracle JAXB 实现不会抛出异常。例如,为 Integer 属性提供一个字符串值(比如 ABC)只是将该值保留为 null 而不是抛出异常。
在 JAXB 2 中,可以定义 ValidationEvenHandler。使用以下处理程序处理程序,使 XML 解码以我需要的方式抛出异常。
public class UnmarshallerValidationEventHandler implements ValidationEventHandler {
@Override
public boolean handleEvent(ValidationEvent event) {
// This indicates JAXB that it should continue processing only if the
// severity level is less than error. NOTE: validation event constants
// go in ascending order in level of severity(i.e., 0 WARNING, 1: ERROR, 2 :FATAL_ERROR)
return event.getSeverity() < ValidationEvent.ERROR;
}
}
问题
如何让 Jersey 使用特定的 JAXBContext 实例,以便将解码器与我的自定义验证事件处理程序一起使用?
或者,鉴于我的应用程序仅在 Jersey 方法中使用 JAXB,为 JVM 实例全局定义一个特定的 JAXBContext 将是一个不错的选择。这怎么可能?
最佳答案
Jersey 用户指南在 Using custom JAXBContext 中对此进行了介绍章节。基本上你需要提供 ContextResolver<T>喜欢:
@Provider
public class PlanetJAXBContextProvider implements ContextResolver<JAXBContext> {
private JAXBContext context = null;
public JAXBContext getContext(Class<?> type) {
if(type != Planet.class)
return null; // we don't support nothing else than Planet
if(context == null) {
try {
context = JAXBContext.newInstance(Planet.class);
} catch (JAXBException e) {
// log warning/error; null will be returned which indicates that this
// provider won't/can't be used.
}
}
return context;
}
}
您可以在 storage-service 中看到示例使用示例项目(参见 JAXBContextResolver)。
注意:而不是ContextResolver<JAXBContext>
你也可以提供ContextResolver<Marshaller>
或/和 ContextResolver<Unmarshaller>
.
关于java - 在 Jersey 1.17 中指定 JAXB 2 上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18436782/