Java 如何从嵌套的XML子元素中删除名称空间值?

Java 如何从嵌套的XML子元素中删除名称空间值?,java,xml,web-services,jakarta-ee,serialization,Java,Xml,Web Services,Jakarta Ee,Serialization,我有一个由Jackson、Jersey、EclipseLink和Tomcat支持的小型RESTful web服务。在大多数情况下,除了涉及到嵌套的子元素外,XML都按预期工作。它们是用名称空间属性编写的,而XML文档的其余部分不是。以下是响应XML的示例: <userView> <userIdSID>5</userIdSID> <userAuthLevel>5</userAuthLevel> <userRo

我有一个由Jackson、Jersey、EclipseLink和Tomcat支持的小型RESTful web服务。在大多数情况下,除了涉及到嵌套的子元素外,XML都按预期工作。它们是用名称空间属性编写的,而XML文档的其余部分不是。以下是响应XML的示例:

<userView>
    <userIdSID>5</userIdSID>
    <userAuthLevel>5</userAuthLevel>
    <userRoles>
        <roleSID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:decimal">1</roleSID>
        <roleSID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:decimal">3</roleSID>
        <roleSID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:decimal">2</roleSID>
        <roleSID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:decimal">8</roleSID>
        <roleSID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:decimal">5</roleSID>
        <roleSID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:decimal">4</roleSID>
        <roleSID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:decimal">9</roleSID>
        <roleSID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:decimal">1000001</roleSID>
    </userRoles>
</userView>
这就是my UserView.java的外观:

package com.company.project;

import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

@XmlAccessorType(XmlAccessType.FIELD)
public class UserRoleList implements Serializable {

    private int userRoleSID;

    public int getUserRoleSid() {
        return userRoleSID;
    }

    public void setUserRoleSid(int userRoleSid) {
        this.userRoleSID = userRoleSid;
    }
}
package com.company.project;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

@Entity
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class UserView implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "USER_ID_SID")
    private String userIdSID;
    @Basic(optional = true)
    private String userAuthLevel;
    @XmlElementWrapper(name = "userRoles")
    @XmlElement(name = "roleSID")
    private List<UserRoleList> userRoleList = new ArrayList<UserRoleList>();

    public UserView() {
    }

    public UserView(String userIdSID) {
        this.userIdSID = userIdSID;
    }

    public String getUserIdSID() {
        return userIdSID;
    }

    public void setUserIdSID(String userIdSID) {
        this.userIdSID = userIdSID;
    }

    public List<UserRoleList> getUserRoleList() {
        return userRoleList;
    }

    public void setUserRoleList(List<UserRoleList> userRoleList) {
        this.userRoleList = userRoleList;
    }

    public String getUserAuthLevel() {
        return userAuthLevel;
    }

    public void setUserAuthLevel(String userAuthLevel) {
        this.userAuthLevel = userAuthLevel;
    }
}

我认为问题在于你的UserRoleList类,它是一个只有一个字段的类,你真的想把它映射到一个简单的类型。您可能希望尝试使用
@XmlValue
注释注释
userRoleSID
成员。

在使用JAXB映射JPA实体时,我建议使用默认访问(或xmlacestype.PROPERTY)并注释get方法。JPA impl有一些技巧来处理延迟加载等问题,在使用字段访问时有时会导致问题。

我无法确定一个答案,但它们都给了我开始检查SQL结构的想法。事实证明,我的
UserRoleList
类采用了
int
的数据类型。在围栏的另一边,我的
ResultList
是一个
BigDecimal
数据类型列表

为了消除任何和所有歧义,我修改了SQL语句,将值返回为
VARCHAR
,该值将作为
String
数据类型对象。我更新了我的
UserRoleList
类来表示
String
对象,现在一切都正常了


我将重温我的代码,以反映数据类型的正确绑定,但现在,这让我克服了困难,从而可以完成解决方案的原型设计。非常感谢大家,特别是感谢dmos,为您提供了一个快速而高效的头脑风暴会议。

只需将您的代码放入JAXBContext,然后创建一个封送器,就可以为每个角色ID输出
。我想这是Jersey编组配置、包信息中的一个设置,或者您在代码库中没有使用这些文件?添加了XmlValue属性,它会输出正确的输出。仍然看不到您正在使用的名称空间。不,我是说他们的默认名称空间不应该添加这些名称空间,除非您有一个设置/配置,如果您需要帮助,请将您的web.xml与jersey端点代码一起发布。我不确定你发布的代码是否是你系统中使用的代码,因为它需要@xmlvalue才能没有子元素。让我们试试这个建议,Jersey/Jackson似乎不喜欢它:
原因:com.sun.xml.bind.v2.runtime.illegalannotations异常:1个illegalannotationexception计数如果类有@XmlElement属性,它就不能有@xmlvalue属性。
请注意,我删除了所有我看到的与
@xmlement
相关的引用,但仍然得到了那个错误。
 List<UserRoleList> userRoleList = em.createNamedQuery("findRoleListByLoginName")
                    .setParameter(1, id)
                    .setParameter(2, client)
                    .getResultList();
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <display-name>moxyWS</display-name>
    <servlet>
        <servlet-name>ServletAdaptor</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <init-param>
            <description>Multiple packages, separated by semicolon(;), can be specified in param-value</description>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>com.project.moxyws</param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletAdaptor</servlet-name>
        <url-pattern>/webresources/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
    <persistence-unit-ref>
        <persistence-unit-ref-name>persistence-factory</persistence-unit-ref-name>
        <persistence-unit-name>moxyWS_war_1.0-SNAPSHOTPU</persistence-unit-name>
    </persistence-unit-ref>
</web-app>
package com.project.moxyws.service;

import com.project.moxyws.UserView;
import com.project.moxyws.controller.UserViewJPAController;
import javax.naming.NamingException;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;

@Path("request")
public class UserViewRESTFacade {

    private EntityManagerFactory getEntityManagerFactory() throws NamingException {
        return (EntityManagerFactory) Persistence
                .createEntityManagerFactory("moxyWS_war_1.0-SNAPSHOTPU");
    }

    private UserViewJPAController getJpaController() {
        try {
            return new UserViewJPAController(getEntityManagerFactory());
        } catch (NamingException ex) {
            throw new RuntimeException(ex);
        }
    }

    public UserViewRESTFacade() {
    }

    @GET
    @Path("{client}/{id}")
    @Produces({"application/xml", "application/json"})
    public UserView findUserByClientAndID(@PathParam("client") String client, @PathParam("id") String id) {
        try {
            return getJpaController().findUserId(id, client);
        } catch (Exception e) {
            throw new WebApplicationException(204);
        }
    }
}