0

我尝试在 Java 类上映射一个 opennms rest api;我使用正确配置的 Java 客户端,但 jaxb 解组失败并出现错误:

[org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver] (134) - 解决来自处理程序的异常...

这是 Java 客户端和 jaxb 代码:

@Override
public List<User> getUserList() {

    Client client = null;
    try {
        client = buildClient();
        final WebResource webResource = client.resource(opennmsUrl + "users");

        final ClientResponse response = webResource.get(ClientResponse.class);

        if (response.getStatus() != 200) {
            throw new IllegalStateException("Request to remote opennms server failed with error " + response.getStatus() + " : " + response.getStatusInfo().toString());
        } else {

            LOGGER.info("Response: result ({}), reason [{}]", response.getStatus(), response.getStatusInfo());
            LOGGER.info("Response: body [{}]", response.getEntity(String.class));

            final JAXBContext jaxbContext = JAXBContext.newInstance(opennmsUsersSchema);
            final Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            final JAXBElement<Users> element = (JAXBElement<Users>) jaxbUnmarshaller.unmarshal(response.getEntityInputStream());
            final Users usrList = (Users) element.getValue();

            return usrList.getUser();

            /*User admin = new User();

            admin.setUserId("admin");
            admin.setFullName("Administrator");
            admin.setUserComments("Default administrator, do not delete");                
            admin.setPassword("!!opennms2015");
            admin.setTuiPin("pin");
            admin.setReadOnly(Boolean.FALSE);

            List<User> users = new ArrayList<>();

            users.add(admin);

            return users;*/
        }
    } catch (IllegalStateException e) {
        throw e;
    } catch (Exception e) {
        throw new IllegalStateException("Exception on Request", e);
    } finally {
        if (client != null) {
            client.destroy();
        }
    }
}

编辑:响应正文 xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <users count="1" totalCount="1">
    <user>
      <user-id>admin</user-id>
      <full-name>Administrator</full-name>
      <user-comments>Default administrator</user-comments>
      <email></email>
      <password>123456</password>
      <passwordSalt>true</passwordSalt>
    </user>
  </users>

编辑:评论中提交的信息

opennmsUsersSchema包是否包含由 maven jaxb 插件从 xsd 模式自动生成的 java 类

xsd 架构在这里:xmlns.opennms.org/xsd/users

这是Usersjava类:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "", propOrder = { "user" })
@XmlRootElement(name = "users") 
public class Users { 
  @XmlElement(required = true) 
  protected List<User> user; 
  public List<User> getUser() { if (user == null) { user = new ArrayList<User>(); } return this.user; } 
}

这是Userjava类:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"userId",
"fullName",
"userComments",
"password",
"contact",
"dutySchedule",
"tuiPin"
})
@XmlRootElement(name = "user")
public class User {

@XmlElement(name = "user-id", required = true)
protected String userId;
@XmlElement(name = "full-name")
protected String fullName;
@XmlElement(name = "user-comments")
protected String userComments;
@XmlElement(required = true)
protected String password;
protected List<Contact> contact;
@XmlElement(name = "duty-schedule")
protected List<String> dutySchedule;
@XmlElement(name = "tui-pin")
protected String tuiPin;
@XmlAttribute(name = "read-only")
protected Boolean readOnly;

public String getUserId() {
    return userId;
}

public void setUserId(String value) {
    this.userId = value;
}

public String getFullName() {
    return fullName;
}

public void setFullName(String value) {
    this.fullName = value;
}

public String getUserComments() {
    return userComments;
}

public void setUserComments(String value) {
    this.userComments = value;
}

public String getPassword() {
    return password;
}

public void setPassword(String value) {
    this.password = value;
}

public List<Contact> getContact() {
    if (contact == null) {
        contact = new ArrayList<Contact>();
    }
    return this.contact;
}

public List<String> getDutySchedule() {
    if (dutySchedule == null) {
        dutySchedule = new ArrayList<String>();
    }
    return this.dutySchedule;
}

public String getTuiPin() {
    return tuiPin;
}

public void setTuiPin(String value) {
    this.tuiPin = value;
}

public boolean isReadOnly() {
    if (readOnly == null) {
        return false;
    } else {
        return readOnly;
    }
}

public void setReadOnly(Boolean value) {
    this.readOnly = value;
}

}

4

2 回答 2

0

谢谢你的支持 !这是最终代码:

    @Override
public List<User> getUserList() {

    Client client = null;
    try {
        client = buildClient();
        final WebResource webResource = client.resource(opennmsUrl + "users");

        final ClientResponse response = webResource.get(ClientResponse.class);

        if (response.getStatus() != 200) {
            throw new IllegalStateException("Request to remote opennms server failed with error " + response.getStatus() + " : " + response.getStatusInfo().toString());
        } else {

            //LOGGER.info("Response: result ({}), reason [{}]", response.getStatus(), response.getStatusInfo());
            //LOGGER.info("Response: body [{}]", response.getEntity(String.class));

            //Prepare JAXB objects
            JAXBContext jaxbContext = JAXBContext.newInstance(ObjectFactory.class);
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

            //Create an XMLReader to use with our filter
            XMLReader reader = XMLReaderFactory.createXMLReader();

            //Create the filter (to add namespace) and set the xmlReader as its parent.
            NamespaceFilter inFilter = new NamespaceFilter("http://xmlns.opennms.org/xsd/users", true);
            inFilter.setParent(reader);

            //Prepare the input, in this case a java.io.File (output)
            InputSource is = new InputSource(response.getEntityInputStream());

            //Create a SAXSource specifying the filter
            SAXSource source = new SAXSource(inFilter, is);

            //Do unmarshalling
            Object element = jaxbUnmarshaller.unmarshal(source);

            if (element instanceof Users) {
                //System.out.println(((Users) element).getUser().get(0).getFullName());
                return ((Users) element).getUser();
            }
        }
    } catch (IllegalStateException e) {
        throw e;
    } catch (NoSuchAlgorithmException | KeyManagementException | UniformInterfaceException | ClientHandlerException | JAXBException e) {
        throw new IllegalStateException("Exception on Request", e);
    } catch (SAXException ex) {
        java.util.logging.Logger.getLogger(OpennmsRemote.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
        if (client != null) {
            client.destroy();
        }
    }
    return null;
}

}

于 2015-11-16T15:57:14.820 回答
0

如果有问题的xml是:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <users count="1" totalCount="1" xmlns="xmlns.opennms.org/xsd/users">
    <user>
      <user-id>admin</user-id>
      <full-name>Administrator</full-name>
      <user-comments>Default administrator</user-comments>
      <email></email>
      <password>123456</password>
      <passwordSalt>true</passwordSalt>
    </user>
  </users>

注意:我添加了命名空间xmlns="xmlns.opennms.org/xsd/users"

此代码将解组它

JAXBContext jaxbContext = JAXBContext.newInstance(ObjectFactory.class);
javax.xml.bind.Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Object element = jaxbUnmarshaller.unmarshal(theXml);
if (element instanceof Users){
     System.out.println(((Users)element).getUser().get(0).getFullName());
}

ObjectFactory.class你的包中,你有由 maven jaxb 自动生成的 java 类

注意:在我的 package-info.java 中@javax.xml.bind.annotation.XmlSchema(namespace = "http://xmlns.opennms.org/xsd/users"),由 jaxb 自动生成

编辑:用户评论,xml 在没有名称空间的情况下到达

由于 xml 没有以正确的名称空间到达,您需要从您的类中删除它或将其添加到 xml。

删除它

  1. 包信息.java 删除 @javax.xml.bind.annotation.XmlSchema(namespace = "http://xmlns.opennms.org/xsd/users")

  2. Users.java, 删除所有命名空间规范

  3. User.java, 删除所有命名空间规范

它会在没有命名空间的情况下运行,

添加它

要在解组之前添加到 xml,请参阅此jaxb-how-to-ignore-namespace-during-unmarshalling-xml-document

于 2015-11-16T14:40:03.883 回答