简体   繁体   English

在Jersey 1.17中指定JAXB 2上下文

[英]Specifying JAXB 2 context in Jersey 1.17

I'm using Jersey 1.17 on the server side to process REST requests and JAXB 2 to unmarshall the XML request content. 我在服务器端使用Jersey 1.17来处理REST请求,使用JAXB 2来解组XML请求内容。

Context 上下文

This is the Jersey method I use. 这是我使用的Jersey方法。 The MyDTO class uses the @XmlRootElement annotation (otherwise, I'd need to define the parameter with the JAXBElement type). 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);
 }

Requirement 需求

By default, the Sun/Oracle JAXB implementation doesn't throw exceptions when the XML content has errors. 默认情况下,Sun / Oracle JAXB实现在XML内容出错时不会抛出异常。 For example providing a string value, say ABC, for an Integer attribute simply leaves the value as null instead of throwing an exception. 例如,为Integer属性提供字符串值(例如ABC)只是将值保留为null而不是抛出异常。

In JAXB 2 a ValidationEvenHandler can be defined. 在JAXB 2中,可以定义ValidationEvenHandler。 Using the following handler handler, makes the XML unmarshalling throw an exception the way I need it to. 使用以下处理程序处理程序,使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;
        }

    }

Question

How can I get Jersey to use a particular JAXBContext instance in order to use an unmarshaller with my custom validation event handler? 我怎样才能让Jersey使用特定的JAXBContext实例来使用unmarshaller和我的自定义验证事件处理程序?

Alternatively, given that my application only uses JAXB in Jersey methods, defining a particular JAXBContext globally for the the JVM instance would be a good option. 或者,鉴于我的应用程序仅在Jersey方法中使用JAXB,因此为JVM实例全局定义特定的JAXBContext将是一个不错的选择。 How could that be done? 怎么可能这样呢?

Jersey Users Guide covers this in Using custom JAXBContext chapter. Jersey用户指南在使用自定义JAXBContext章节中介绍了这一点。 Basically you need to provide ContextResolver<T> like: 基本上你需要提供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;
    }
}

You can see a sample use in storage-service sample project (see JAXBContextResolver ). 您可以在存储服务示例项目中查看示例用法(请参阅JAXBContextResolver )。

Note: Instead of ContextResolver<JAXBContext> you can also provide ContextResolver<Marshaller> or/and ContextResolver<Unmarshaller> . 注意:您还可以提供ContextResolver<Marshaller>或/和ContextResolver<Unmarshaller>而不是ContextResolver<JAXBContext> ContextResolver<Unmarshaller>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM