4

プロバイダーによって公開された Web サービスを利用しようとしています。プロバイダーは、要求 xml に値を持たないタグを含めないように、最後に厳密にチェックします。

私はJax-WSを使用しています。特定のオブジェクトに値を設定しないと、空のタグとして送信され、タグが存在します。PFB私の問題を示す例。

クライアント XML :

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:host="http://host.testing.webservice.com/">
   <soapenv:Header/>
   <soapenv:Body>
      <host:testingMathod>
         <arg0>
            <PInfo>
               <IAge>45</IAge>
               <strName>Danny</strName>
            </PInfo>
            <strCorrId>NAGSEK</strCorrId>
            <strIpAddress></strIpAddress>
         </arg0>
      </host:testingMathod>
   </soapenv:Body>
</soapenv:Envelope>

この場合、IpAddress の値が指定されていないため、空のタグが送信されています。

そのため、リクエスト xml の空のタグを削除するにはどうすればよいか教えてください。同じ問題の唯一の解決策は Handlerchain ですか?

ありがとう、ナビーン。

4

3 に答える 3

10

Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.

By default MOXy like other JAXB implementations will not marshal an element for null values:

POSSIBLE PROBLEM

I believe the strIpAddress property is not null, but contains a value of empty String (""). This would cause the empty element to be written out.

Root

package forum11215485;

import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    String nullValue;
    String emptyStringValue;
    String stringValue;

}

Demo

package forum11215485;

import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);

        Root root = new Root();
        root.nullValue = null;
        root.emptyStringValue = "";
        root.stringValue = "Hello World";

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(root, System.out);
    }

}

Output

Note how there is no element marshalled out for the nullValue field, and the emptyStringValue field is marshalled as an empty element.

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <emptyStringValue></emptyStringValue>
   <stringValue>Hello World</stringValue>
</root>

SOLUTION #1 - Ensure the property is set to null and not ""

SOLUTION #2 - Write an XmlAdapter that converts "" to null

An XmlAdapter is a JAXB mechanism that allows an object to be marshalled as another object.

StringAdapter

The following XmlAdapter will marshal empty strings as null. This will cause them not to appear in the XML representation.

package forum11215485;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class StringAdapter extends XmlAdapter<String, String> {

    @Override
    public String unmarshal(String v) throws Exception {
        return v;
    }

    @Override
    public String marshal(String v) throws Exception {
        if(null == v || v.length() == 0) {
            return null;
        }
        return v;
    }

}

package-info

The XmlAdapter is hooked in using the @XmlJavaTypeAdapter annotation. Below is an example of hooking it in at the package level so that it applies to a fields/properties of type String within the package. For more information see: http://blog.bdoughan.com/2012/02/jaxb-and-package-level-xmladapters.html

@XmlJavaTypeAdapter(value=StringAdapter.class, type=String.class)
package forum11215485;

import javax.xml.bind.annotation.adapters.*;

Output

Now the output from running the demo code is the following:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <stringValue>Hello World</stringValue>
</root>
于 2012-06-28T16:41:59.780 に答える
1

これは、使用している XML シリアライザーの問題です (特別なことをしていない場合は、JAXB である必要があります)。

シリアライザの「null ポリシー」は設定可能であるべきですが、JAXB では不可能だと思います。MOXyを使用すると、null の場合はノードを書き込まないように使用できますXmlMarshalNullRepresentation.ABSENT_NODE。実装は次のようになります。

class MyClass {

    // ... here are your other attributes

    @XmlElement (name = "strIpAddress")
    @XmlNullPolicy(nullRepresentationForXml = XmlMarshalNullRepresentation.ABSENT_NODE)
    String strIpAddress = null;

}

emptyNodeRepresentsNullPS: のparamも定義する必要があるかもしれません@XmlNullPolicy

このテーマの詳細については、この質問を確認してください

于 2012-06-28T08:16:47.407 に答える
0

これは、注釈を使用できないクラスをシリアル化するときに機能しました( LogRecord):

            JAXBContext jc = JAXBContext.newInstance(LogRecord.class);
            JAXBElement<LogRecord> je = new JAXBElement<>(new QName("log"), LogRecord.class, record);
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.setAdapter(new XmlAdapter<String,String>() {
                @Override
                public String marshal(String v) throws Exception {
                    if(null == v || v.length() == 0) {
                        return null;
                    }
                    return v;
                }
                @Override
                public String unmarshal(String v) throws Exception {
                    return v;
                }
            });
            ByteArrayOutputStream xml = new ByteArrayOutputStream();
            marshaller.marshal(je, xml);
于 2015-12-13T00:28:30.367 に答える