【发布时间】:2013-05-15 19:57:48
【问题描述】:
我有一个由 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>
这就是我的 UserRoleList.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;
}
}
这就是我的 UserView.java 的样子:
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;
}
}
这就是我填充该嵌套元素的方式,它需要 2 个入站参数并通过实体管理器执行查询:
List<UserRoleList> userRoleList = em.createNamedQuery("findRoleListByLoginName")
.setParameter(1, id)
.setParameter(2, client)
.getResultList();
关于我可能遗漏什么的任何想法?我尝试使用 pkg-info 无济于事。请注意,此输出构造了一个没有从中生成模式的 XML。不确定这是否有帮助或阻碍,但我们将不胜感激。
更新 1:根据要求,这是我的 web.xml:
<?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>
更新 2:根据要求,这是我的 REST 外观:
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);
}
}
}
【问题讨论】:
-
只需将您的代码放入 JAXBContext,然后创建一个编组器,就会为每个角色 SID 输出
<roleSID><userRoleSID>#</userRoleSID></roleSID>。我想这是您的 Jersey 编组配置、包信息中的设置,或者您没有在代码库中使用这些文件? -
添加了 XmlValue 属性,它会吐出正确的输出。仍然看不到你得到的命名空间。
-
不,我是说他们的默认不应该添加这些命名空间,除非你在某处有设置/配置
-
如果您需要帮助,请发布您的 web.xml 以及您的球衣端点代码。我不确定您已经发布的代码是您系统中正在使用的代码,因为它需要 @xmlvalue 才能使其没有子元素。
标签: java xml web-services jakarta-ee serialization