java - Jersey REST/JAXB 错误,映射接口(interface)

标签 java rest interface jaxb jersey

我必须在我的 REST 网络服务中使用一个接口(interface)。这是接口(interface) Specs.java :

@XmlJavaTypeAdapter(MyAdapter.class)
public interface Specs {

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

}

我的适配器.java :

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

RegSpecs.java

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

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

}

map 规范.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;
    }

}

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

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

谢谢!

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

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;
        }

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

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 接口(interface)的客户端需要知道 MagSpecs 可以是它的一个实例,以便它知道为了工具目的而查看它。最简单的方法是在 Specs 接口(interface)上添加一个 @XmlSeeAlso 注释:

@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类和接口(interface)我可以毫无异常(exception)地生成一个合理的模式。例如(对于这段时间有点长,我深表歉意):

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 接口(interface)更改为一个类,并让当前的实现从它继承。如果需要,它可以是一个完全抽象的类。只要您没有在类中添加重要的功能,它就应该可以工作。

关于java - Jersey REST/JAXB 错误,映射接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4931960/

相关文章:

java - 我们如何使用 Criteria Query 在 Spring JPA 中查询一对多关系

java - 如何在 Java 中解析和验证 WebSocket 框架?

java - 使用 RESTful 下载文件会出现 HTTP 406 不适用错误

java - 结果的 JSON 格式不正确

c# - 如何将参数传递给 WCF post 方法(restful 服务)

java - Hibernate EntityManager 不分配自动生成的主键值

java - 为什么这个简单的 Junit 5 测试不起作用

json - Go Lang 帮助 - 访问数组/接口(interface) slice

java - 自动实现接口(interface)时参数从哪里来?

Java 运行程序和接口(interface)