生成的泽西休息响应xml的名称空间前缀 [英] namespace prefix for generated jersey rest response xml

查看:80
本文介绍了生成的泽西休息响应xml的名称空间前缀的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用jaxb模型生成休息响应(使用Jersey)。对于某些响应,生成的XML将名称空间前缀(ns2)添加到名称空间属性,尽管它们都存在于同一名称空间中。但是对于其他人来说,它完全没问题。

I'm generating rest responses (using Jersey) from jaxb models. And for some of the responses, the generated XML has namespace prefix (ns2) added to the namespace attribute although they all exists in the same namespace. But for others, it is perfectly fine.

通过我的分析,我认为当一个复杂元素(另一个jaxb模型)被使用时,就会发生这种情况。但所有这些模型都在package-info.java中的相同名称空间中声明。

With my analysis, I think it happens when there is a complex element (another jaxb model) is being used inside one. But all these models are declared in same namespace in package-info.java.

这是代码。

XYZModel.class

XYZModel.class

package int.xyxp.model;

@XmlType(name="xyztype")
@XmlRootElement(name="xyz")
@XmlSeeAlso({XModel.class, YModel.class, Z.class})
@XmlAccessorType(XmlAccessType.FIELD)
public class XYZModel extends VModel {

    @XmlElement(name="code")
    private String code;

    @XmlElementWrapper(name="refs",  namespace="http://reference.com/ref")
    @XmlElementRef
    private List<XModel> refs = new ArrayList<XModel>(0); 
//continues

package-info.java

package-info.java

@javax.xml.bind.annotation.XmlSchema( 
    namespace = "http://reference.com/ref",    
    elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) 
package int.xyxp.model;

生成的XML

<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<ns2:xyz version="1.0" xmlns:ns2="http://reference.com/ref">
    <ns2:code>15</ns2:code>
    <ns2:refs/>
</ns2:xyz>

预期的XML(没有前缀,假设默认命名空间)。

expected XML (without prefix, by assuming default namespace).

<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<xyz version="1.0" xmlns="http://reference.com/ref">
    <code>15</code>
    <refs/>
</xyz>

任何想法。谢谢。

我尝试插入首选名称空间前缀后,它不起作用甚至。所以package-info.java可能只用于命名空间而不是用于选择命名空间前缀。

After I tried to insert my preferred namespace prefix and it doesn't work even. so probably the package-info.java is used only for namespace and not for selecting the namespace prefix.

package-info.java

package-info.java

 @javax.xml.bind.annotation.XmlSchema( 
           namespace = "http://reference.com/ref",    
    xmlns = { 
      @javax.xml.bind.annotation.XmlNs(prefix = "ref", namespaceURI = "http://reference.com/ref"), 
    }, 
    elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) 
 package int.xyxp.model;


推荐答案

注意:我有重写MessageBodyWriter以提供我自己的命名空间(my)。即使我返回空,默认情况下它为空时也需要ns2。所以如果你想拥有自己的命名空间而不是默认的ns2,这个答案就有用了。

NOTE: I have overridden MessageBodyWriter to provide my own namespace ("my"). Even though I have returned empty "", it takes ns2 by default when its empty. So this answers works if you want to have your own namespace instead of default "ns2".

import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.Providers;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper;

@Produces(value=MediaType.APPLICATION_XML)
public class WSNamespaceWriter implements MessageBodyWriter<Object>{

    @Context
    protected Providers providers;

    public boolean isWriteable(Class<?> type, Type genericType,
        Annotation[] annotations, MediaType mediaType) {
        System.out.println("Calling MessageWriter writetable--> " + type.getName());
        return true;
    }

    public void writeTo(Object object, Class<?> type, Type genericType,
        Annotation[] annotations, MediaType mediaType,
        MultivaluedMap<String, Object> httpHeaders,
        OutputStream entityStream) throws IOException,
        WebApplicationException {
        try {
            System.out.println("Calling MessageWriter-->");
            ContextResolver<JAXBContext> resolver 
                = providers.getContextResolver(JAXBContext.class, mediaType);
            JAXBContext jaxbContext;
            if(null == resolver || null == (jaxbContext = resolver.getContext(type))) {
                jaxbContext = JAXBContext.newInstance(type);
            }
            Marshaller m = jaxbContext.createMarshaller();
            NamespacePrefixMapper mapper = new NamespacePrefixMapper() {
                public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
                    System.out.println ("Called NAMESPACE----------" + namespaceUri);
                    if ("http://www.example.com".equals(namespaceUri)
                            || ("").equals(namespaceUri)) {
                        System.out.println ("Called NAMESPACE  return --------");
                        return "my"; // my own namespace
                    }   
                    System.out.println ("Called NAMESPACE  return ns--------");
                    return "";
                }
            };
            m.setProperty("com.sun.xml.internal.bind.namespacePrefixMapper", mapper);           
            m.marshal(object, entityStream);
        } catch(JAXBException jaxbException) {
            throw new WebApplicationException(jaxbException);
        }
    }

    public long getSize(Object t, Class<?> type, Type genericType,
        Annotation[] annotations, MediaType mediaType) {
        return -1;
    }

}

这篇关于生成的泽西休息响应xml的名称空间前缀的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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