生成的rest响应xml的命名空间前缀

生成的rest响应xml的命名空间前缀,rest,jaxb,jersey,xml-namespaces,Rest,Jaxb,Jersey,Xml Namespaces,我使用jaxb模型中的Jersey生成rest响应。对于某些响应,生成的XML将名称空间前缀ns2添加到名称空间属性中,尽管它们都存在于同一名称空间中。但对其他人来说,这是完美的 根据我的分析,我认为当一个复杂元素中使用另一个jaxb模型时,就会发生这种情况。但所有这些模型都在package-info.java中的相同名称空间中声明 这是代码 XYZModel.class package int.xyxp.model; @XmlType(name="xyztype") @XmlRootElem

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

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

这是代码

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
生成的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>
任何想法。谢谢

[编辑]

在我尝试插入首选名称空间前缀后,它甚至无法工作。因此,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;
 @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以提供自己的命名空间。即使我返回的是空的,当ns2为空时,它默认接受ns2。因此,如果您想要拥有自己的名称空间而不是默认的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;
    }

}

但是,带有ns2前缀的版本也非常好。任何符合规范的XML解析器都会像裸版本一样处理这个问题。为了阅读的清晰,我想删除编辑器中的冗余名称空间前缀.Global-search-replace,您可以在其中阅读它的webservice输出,这样消费者就可以阅读.XML,而人类就可以阅读了???
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;
    }

}