Jersey REST / JAXB错误,映射接口 [英] Jersey REST/ JAXB error , mapping an Interface

查看:166
本文介绍了Jersey REST / JAXB错误,映射接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须在我的REST Web服务中使用接口。这是Interface Specs.java:

I have to use an interface in my REST web service. Here is the Interface Specs.java :

@XmlJavaTypeAdapter(MyAdapter.class)
public interface Specs {

    public BaseProperties getBaseProps();
    public void setBaseProps(BaseProperties baseProps);

}

MyAdapter.java:

MyAdapter.java :

public class MyAdapter extends XmlAdapter<Object,Object> 
{  
    public Object unmarshal(Object v) 
    { 
        return v; 
    }  
    public Object marshal(Object v) 
    { 
        return v; 
    }
}

RegSpecs.java

RegSpecs.java

@XmlType
public class RegSpecs implements Specs{
private BaseProperties baseProps;

    public BaseProperties getBaseProps()
    {
        return baseProps;
    }
    public void setBaseProps(BaseProperties baseProps)
    {
        this.baseProps = baseProps;
    }

}

MapSpecs.java

MapSpecs.java

@XmlType
public class MagSpecs implements Specs {

private BaseProperties baseProps;
private Features features;

    public BaseProperties getBaseProps()
    {
        return baseProps;
    }
    public void setBaseProps(BaseProperties baseProps)
    {
        this.baseProps = baseProps;
    }
    public Features getFeatures() {
        return features;
    }
    public void setFeatures(Features features) {
        this.features = features;
    }

}

访问此服务会引发以下错误:

Accessing this service throws the following error :


javax.xml.bind.MarshalException
- 链接异常:
[javax.xml.bind。 JAXBException:类entities.MagSpecs或它的任何超类都是这个上下文已知的。]

javax.xml.bind.MarshalException - with linked exception: [javax.xml.bind.JAXBException: class entities.MagSpecs nor any of its super class is known to this context.]

如何修改我的上下文?我正在使用与Jersey 1.5捆绑的JAXB

How to modify my context ? I am using JAXB bundled with Jersey 1.5

谢谢!

编辑:为了更新我的上下文,我将此代码添加到我的客户端(资源)类:

EDIT : In an attempt to update my context, I added this code to my client (resource) class :

public class BookService  implements ContextResolver<JAXBContext> 
{

        private JAXBContext jaxbContext;

        public BookService() {
            try {
                // Bootstrap your JAXBContext will all necessary classes
                jaxbContext = JAXBContext.newInstance(Specs.class,MagSpecs.class, RegSpecs.class);
            } catch(Exception e) {
                throw new RuntimeException(e);
            }
        }

        public JAXBContext getContext(Class<?> clazz) {
            if(BookService.class == clazz) {
                return jaxbContext;
            }
            return null;
        }

在这种情况下我收到错误:

In this case I get error :


entities.Spec是一个接口,JAXB无法处理接口。
此问题与以下位置有关:
at entities.Specs
entities.Specs没有no-arg默认构造函数。
此问题与以下位置有关:
at entities.Specs

entities.Specs is an interface, and JAXB can't handle interfaces. this problem is related to the following location: at entities.Specs entities.Specs does not have a no-arg default constructor. this problem is related to the following location: at entities.Specs


推荐答案

Specs 界面的客户端需要知道 MagSpecs 可以是它的一个实例,以便它知道为了工具目的而看它。最简单的方法是在 Specs 界面上放置 @XmlSeeAlso 注释:

The client of the Specs interface needs to know that MagSpecs can be an instance of it so that it knows to look at it for tooling purposes. The easiest way of doing this is to put an @XmlSeeAlso annotation on the Specs interface:

@XmlSeeAlso({ MagSpecs.class, RegSpecs.class })
@XmlJavaTypeAdapter(MyAdapter.class) // Never needed this annotation myself...
public interface Specs {
    public BaseProperties getBaseProps();
    public void setBaseProps(BaseProperties baseProps);
}

一般情况下,每当我使用JAXB注释时,我都要确保写大量的测试来检查是否可以从相关的类生成XML模式,检查从每个(理智的)入口点到类和接口的Web我可以生成一个合理的模式,没有例外。例如(我为此道歉有点长):

In general, whenever I'm working with JAXB annotations I make sure I write plenty of tests to check that an XML schema can be generated from the classes in question, checking that from each (sane) entry point into the web of classes and interfaces I can generate a sensible schema without exceptions. For example (and I apologize for this being a bit long):

private SchemaOutputResolver sink;
StringWriter schema;

@Before
public void init() {
    schema = new StringWriter();
    sink = new SchemaOutputResolver() {
        @Override
        public Result createOutput(String namespaceUri,
                String suggestedFileName) throws IOException {
            StreamResult sr = new StreamResult(schema);
            sr.setSystemId("/dev/null");
            return sr;
        }
    };
    Assert.assertTrue(schema.toString().isEmpty());
}

private void testJAXB(Class<?>... classes) throws Exception {
    JAXBContext.newInstance(classes).generateSchema(sink);
    Assert.assertTrue(schema.toString().length() > 0);
}

@Test
public void testJAXBForSpecs() throws Exception {
    testJAXB(Specs.class);
}






:你还需要 Specs 接口更改为一个类,并让当前的实现继承它。如果你愿意,它可以是一个完全抽象的类。只要你没有在课程中使用严肃的功能,它就可以工作。


: You also need to change the Specs interface into a class and have the current implementations inherit from it. It can be a fully abstract class if you want. As long as you're not putting serious functionality in the classes, it should work.

这篇关于Jersey REST / JAXB错误,映射接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆