JAX-B定制的XML输出

时间:2016-05-12 12:44:50

标签: java xml jaxb

我正在使用ECCP协议,以便将我的CRM与Elastix呼叫中心模块集成。该协议使用如下定义的XML结构:

<request id="1">
   <request_type> <!-- this will be mapped to the Java request class -->
       <attributes>
       </attributes>
   </request_type>
</request>

<response id="1">
    <response_type> <!-- this will be mapped to the Java response class -->
        <attributes>
        </attributes>
    </response_type>
</response>

我正在使用JAX-B将XML映射到Java类,但问题是我必须在每个请求中将JAX-B生成的XML放在<request></request> XML中,并从{{1}中提取内容因为ECCP协议定义每个请求和响应都需要嵌套到它们各自的元素中。

以下是我用来执行此操作的代码:

<response></response>

示例性:

ECCP的一个协议操作是将JAX-B映射到这样的类中(省略了getter和setter):

document = createDocument();
Element requestWrapper = document.createElement("request");
requestWrapper.setAttribute("id", String.valueOf(wrapped.getId()));
document.appendChild(requestWrapper);

JAXBContext jc = JAXBContext.newInstance(wrapped.getClass());
Marshaller marshaller = jc.createMarshaller();
marshaller.marshal(wrapped, requestWrapper);

JAX-B输出以下内容:

@XmlRootElement(name = "loginagent")
@XmlAccessorType(XmlAccessType.FIELD)
public class EccpLoginAgentRequest implements IEccpRequest {

    @XmlElement(name = "agent_number")
    private String agentNumber;

    @XmlElement(name = "password")
    private String password;
}

但ECCP的协议要求是:

<loginagent>
   <agent_number>username</agent_number>
   <password>password</password>
</loginagent>

问题是:有没有其他方法可以通过其他更好的方式实现? 谢谢。

2 个答案:

答案 0 :(得分:1)

您可以查看@XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "request") public class RequestWrapper { @XmlElement(name = "loginagent", required = true) protected EccpLoginAgentRequest loginagent; public EccpLoginAgentRequest getLoginagent() { return loginagent; } public void setLoginagent(EccpLoginAgentRequest loginagent) { this.loginagent = loginagent; } } 注释,它可以帮助您为请求和响应包装相同的内容。对于内部部分,您可以创建单独的类并适当地映射所有字段。我希望这对你有所帮助。

编辑: 对不起,响应时间很长。您需要创建一个包装类,其内部结构定义为@XmlElement。以下是实现XML结构的方法:

@XmlAccessorType(XmlAccessType.FIELD)
public class EccpLoginAgentRequest {

@XmlElement(name = "agent_number")
private String agentNumber;

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

// getters and setters omitted
}

这是EccpLoginAgentRequest结构:

JAXBContext jaxbContext = JAXBContext.newInstance(Wrapper.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,    true);

EccpLoginAgentRequest request = new EccpLoginAgentRequest();
request.setAgentNumber("1");
request.setPassword("pass");

Wrapper wrapper = new Wrapper();
wrapper.setLoginagent(request);

jaxbMarshaller.marshal(wrapper, System.out);

因此,在结果中,您可以打印所需的XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<request>
    <loginagent>
        <agent_number>1</agent_number>
        <password>pass</password>
    </loginagent>
</request>

它会给你以下输出:

$icon-prefix: 'icon-test';

@mixin btn-state($state) {
  .x-btn-#{$state} & {
    @content;
  }
}

$icon-color-schemes: 'white', 'black';
$icon-color-scheme-default: 'black';

$icons: (
        'default' (
                'bookmark': 'icon-bookmark.png',
                'cancel': 'icon-cancel.png',
                'checklist': 'icon-checklist.png',
                'clipboard': 'icon-clipboard.png',
                'comments': 'icon-comments.png',
                'conference': 'icon-conference_background_selected.png',
                'edit': 'icon-pencil_tip.png',
                'add': 'icon-plus.png',
                'copy': 'icon-copy.png',
                'delete': 'icon-delete.png',
                'design': 'icon-design.png',
                'geography': 'icon-geography.png',
                'grid': 'icon-grid_filled.png',
                'group_message': 'icon-group_message.png',
                'help': 'icon-help.png',
                'minus': 'icon-minus.png',
                'password': 'icon-password.png',
                'pin': 'icon-pin.png',
                'plus': 'icon-plus.png',
                'settings': 'icon-settings.png',
                'shutdown': 'icon-shutdown_filled.png',
                'template': 'icon-template.png',
        ),
        'active' (
                'pin': 'icon-pin-filled.png',
        )
);

// color-schemes
@each $scheme in $icon-color-schemes {
  $postfix: '';
  @if $scheme != $icon-color-scheme-default { $postfix: -#{$scheme}; };

  @each $stateName, $stateValue in $icons {
    @each $class, $filename in $stateValue {
      .#{$icon-prefix}-#{$class}#{$postfix} {
        // default state
        @if $stateName == 'default' {
          background-image: url('icon-srg/#{$scheme}/#{$filename}');
        } @else {
          // active state
          @include btn-state(#{$stateName}) { background-image: url('icon-srg/#{$scheme}/#{$filename}'); }
        }
      }
    };
  }
}

答案 1 :(得分:0)

我在这篇文章中找到了解决这个问题的方法:XML element with attribute and content using JAXB

所以我已经将EccpRequestWrapper对象映射如下:

@XmlRootElement(name = "request")
public class EccpRequestWrapper {
    @XmlAttribute
    private Long id;

    @XmlAnyElement
    private IEccpRequest request;
}

然后我的请求JAX-B以ECCP协议要求的方式输出我的请求。 @XmlAttribute@XmlAnyElement注释起到了作用。

<request id="1">
   <login>
      <username>user</username>
      <password>****</password>
   </login>
</request>

可以在https://jaxb.java.net/guide/Mapping_interfaces.html

找到一个好的JAXB指南